diff options
author | Minteck <contact@minteck.org> | 2023-01-10 14:54:04 +0100 |
---|---|---|
committer | Minteck <contact@minteck.org> | 2023-01-10 14:54:04 +0100 |
commit | 99c1d9af689e5325f3cf535c4007b3aeb8325229 (patch) | |
tree | e663b3c2ebdbd67c818ac0c5147f0ce1d2463cda /alarm/node_modules/node-forge | |
parent | 9871b03912fc28ad38b4037ebf26a78aa937baba (diff) | |
download | pluralconnect-99c1d9af689e5325f3cf535c4007b3aeb8325229.tar.gz pluralconnect-99c1d9af689e5325f3cf535c4007b3aeb8325229.tar.bz2 pluralconnect-99c1d9af689e5325f3cf535c4007b3aeb8325229.zip |
Update - This is an automated commit
Diffstat (limited to 'alarm/node_modules/node-forge')
149 files changed, 0 insertions, 54446 deletions
diff --git a/alarm/node_modules/node-forge/.jscsrc b/alarm/node_modules/node-forge/.jscsrc deleted file mode 100644 index 06245e6..0000000 --- a/alarm/node_modules/node-forge/.jscsrc +++ /dev/null @@ -1,64 +0,0 @@ -{ - "excludeFiles": [ - "./js/forge.bundle.js", - "./js/forge.min.js", - "./js/jsbn.js", - "./nodejs/ui/require.js", - "./nodejs/ui/test.min.js" - ], - "disallowKeywords": ["with"], - "disallowKeywordsOnNewLine": ["else", "catch"], - // FIXME: enable this? - //"disallowImplicitTypeConversion": ["string"], - "disallowMixedSpacesAndTabs": true, - "disallowMultipleLineBreaks": true, - // FIXME: enable this or do we prefer to - // use w/angular directive templates? - //"disallowMultipleLineStrings": true, - "disallowNewlineBeforeBlockStatements": true, - "disallowSpaceAfterObjectKeys": true, - "disallowSpaceAfterPrefixUnaryOperators": ["++", "--", "+", "-", "~", "!"], - "disallowSpaceBeforeBinaryOperators": [","], - "disallowSpaceBeforePostfixUnaryOperators": ["++", "--"], - "disallowSpacesInAnonymousFunctionExpression": { - "beforeOpeningRoundBrace": true - }, - "disallowSpacesInFunctionDeclaration": { - "beforeOpeningRoundBrace": true - }, - "disallowSpacesInNamedFunctionExpression": { - "beforeOpeningRoundBrace": true - }, - "disallowSpacesInsideParentheses": true, - "disallowTrailingComma": true, - "disallowTrailingWhitespace": true, - "requireCommaBeforeLineBreak": true, - "requireCurlyBraces": ["if", "else", "for", "while", "do", "try", "catch"], - "requireLineFeedAtFileEnd": true, - "requireSpaceAfterBinaryOperators": ["?", ":", "+", "-", "/", "*", "%", "==", "===", "!=", "!==", ">", ">=", "<", "<=", "&&", "||"], - "requireSpaceBeforeBinaryOperators": ["?", ":", "+", "-", "/", "*", "%", "==", "===", "!=", "!==", ">", ">=", "<", "<=", "&&", "||"], - "requireSpaceAfterKeywords": [ - "else", - "do", - "return", - "try" - ], - "requireSpaceBeforeBlockStatements": true, - "requireSpacesInConditionalExpression": { - "afterTest": true, - "beforeConsequent": true, - "afterConsequent": true, - "beforeAlternate": true - }, - "requireSpacesInFunction": { - "beforeOpeningCurlyBrace": true - }, - "safeContextKeyword": "self", - "validateLineBreaks": "LF", - // FIXME: enable doc checks (update to use newer jscs jsdoc module) - //"validateJSDoc": { - // "checkParamNames": true, - // "requireParamTypes": true - //}, - "validateParameterSeparator": ", " -} diff --git a/alarm/node_modules/node-forge/.jshintignore b/alarm/node_modules/node-forge/.jshintignore deleted file mode 100644 index c50f474..0000000 --- a/alarm/node_modules/node-forge/.jshintignore +++ /dev/null @@ -1,6 +0,0 @@ -js/forge.bundle.js -minify.js -nodejs/build.js -nodejs/minify.js -nodejs/ui/require.js -nodejs/ui/test.min.js diff --git a/alarm/node_modules/node-forge/.jshintrc b/alarm/node_modules/node-forge/.jshintrc deleted file mode 100644 index 26d261c..0000000 --- a/alarm/node_modules/node-forge/.jshintrc +++ /dev/null @@ -1,3 +0,0 @@ -{ - "sub": true -} diff --git a/alarm/node_modules/node-forge/.npmignore b/alarm/node_modules/node-forge/.npmignore deleted file mode 100644 index 0cac541..0000000 --- a/alarm/node_modules/node-forge/.npmignore +++ /dev/null @@ -1,23 +0,0 @@ -*.py[co] -*.sw[nop] -*~ -.bower.json -.cdtproject -.classpath -.cproject -.project -.settings -Makefile -TAGS -aclocal.m4 -autom4te.cache -build -config.log -config.status -configure -dist -js/forge.bundle.js -js/forge.min.js -node_modules -nodejs/coverage -tests/forge diff --git a/alarm/node_modules/node-forge/.travis.yml b/alarm/node_modules/node-forge/.travis.yml deleted file mode 100644 index 7124426..0000000 --- a/alarm/node_modules/node-forge/.travis.yml +++ /dev/null @@ -1,12 +0,0 @@ -language: node_js -node_js: - - "0.10" - - "0.12" - - iojs -install: (cd nodejs && npm install) -script: - - (cd nodejs && npm test) -notifications: - email: - on_success: change - on_failure: change diff --git a/alarm/node_modules/node-forge/HACKING.md b/alarm/node_modules/node-forge/HACKING.md deleted file mode 100644 index 762dfe1..0000000 --- a/alarm/node_modules/node-forge/HACKING.md +++ /dev/null @@ -1,37 +0,0 @@ -Hacking on forge -================ - -Want to hack on forge? Great! Here are a few notes: - -Code ----- - -* In general, follow a common [Node.js Style Guide][]. -* Use version X.Y.Z-dev in dev mode. -* Use version X.Y.Z for releases. - -Versioning ----------- - -* Follow the [Semantic Versioning][] guidelines. - -Release Process ---------------- - -* commit changes -* `$EDITOR package.json`: update to release version and remove `-dev` suffix. -* `git commit package.json -m "Release {version}."` -* `git tag {version}` -* `$EDITOR package.json`: update to next version and add `-dev` suffix. -* `git commit package.json -m "Start {next-version}."` -* `git push` -* `git push --tags` - -To ensure a clean upload, use a clean updated checkout, and run the following: - -* `git checkout {version}` -* `npm publish` - -[Node.js Style Guide]: http://nodeguide.com/style.html -[jshint]: http://www.jshint.com/install/ -[Semantic Versioning]: http://semver.org/ diff --git a/alarm/node_modules/node-forge/LICENSE b/alarm/node_modules/node-forge/LICENSE deleted file mode 100644 index 1bba5ce..0000000 --- a/alarm/node_modules/node-forge/LICENSE +++ /dev/null @@ -1,331 +0,0 @@ -You may use the Forge project under the terms of either the BSD License or the -GNU General Public License (GPL) Version 2. - -The BSD License is recommended for most projects. It is simple and easy to -understand and it places almost no restrictions on what you can do with the -Forge project. - -If the GPL suits your project better you are also free to use Forge under -that license. - -You don't have to do anything special to choose one license or the other and -you don't have to notify anyone which license you are using. You are free to -use this project in commercial projects as long as the copyright header is -left intact. - -If you are a commercial entity and use this set of libraries in your -commercial software then reasonable payment to Digital Bazaar, if you can -afford it, is not required but is expected and would be appreciated. If this -library saves you time, then it's saving you money. The cost of developing -the Forge software was on the order of several hundred hours and tens of -thousands of dollars. We are attempting to strike a balance between helping -the development community while not being taken advantage of by lucrative -commercial entities for our efforts. - -------------------------------------------------------------------------------- -New BSD License (3-clause) -Copyright (c) 2010, Digital Bazaar, Inc. -All rights reserved. - -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 Digital Bazaar, Inc. nor the - names of its contributors may be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL DIGITAL BAZAAR BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -------------------------------------------------------------------------------- - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Lesser General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - diff --git a/alarm/node_modules/node-forge/Makefile.in b/alarm/node_modules/node-forge/Makefile.in deleted file mode 100644 index eb4495e..0000000 --- a/alarm/node_modules/node-forge/Makefile.in +++ /dev/null @@ -1,110 +0,0 @@ -# Makefile for Forge - -# Top-level build and dist dir -BUILD_DIR=@FORGE_DIR@/build -TOP_DIST_DIR=@FORGE_DIR@/dist -DIST_DIR=$(TOP_DIST_DIR)/forge - -_FLASH := $(DIST_DIR)/SocketPool.swf -ifeq (@BUILD_FLASH@,yes) -FLASH := $(_FLASH) -else -ifeq (@USE_PRE_BUILT_FLASH@,yes) -FLASH := $(_FLASH) -endif -endif -JS_SOURCES := $(wildcard js/*.js) -JS_DIST := $(JS_SOURCES:js/%.js=$(DIST_DIR)/%.js) -JS_DIST_MIN := $(JS_DIST:%.js=%.min.js) -TESTS_FORGE_LINK := @FORGE_DIR@/tests/forge - -ifeq (@BUILD_PYTHON_MODULES@,yes) -SSL_SESSIONS_DIR = \ - $(TOP_DIST_DIR)/forge_ssl/lib/python@PYTHON_VERSION@/site-packages -SSL_SESSIONS_FILES = \ - $(SSL_SESSIONS_DIR)/_forge_ssl.so \ - $(SSL_SESSIONS_DIR)/forge/ssl.py -endif - -# Whether or not to print commands as they are being executed, helpful for -# debugging the build system. -ifdef PRINT_COMMANDS -PCMD= -else -PCMD=@ -endif - -.PHONY: all build-all update-all verbose clean verbose-commands - -# debug flags for flash build -ifeq (@MXMLC_DEBUG_MODE@,yes) -FLASH_FLAGS = \ - -debug=true \ - -define=CONFIG::debugging,true \ - -define=CONFIG::release,false -else -FLASH_FLAGS = \ - -debug=false \ - -define=CONFIG::debugging,false \ - -define=CONFIG::release,true -endif - -all: $(BUILD_DIR) $(DIST_DIR) $(FLASH) $(JS_DIST) $(TESTS_FORGE_LINK) $(SSL_SESSIONS_FILES) - @echo "forge build complete." - -build-all: all - -update-all: - @git pull && ./build-setup && make all - -$(BUILD_DIR): - $(PCMD) mkdir -p $@ -$(DIST_DIR): - $(PCMD) mkdir -p $@ - -ifeq (@BUILD_FLASH@,yes) -$(DIST_DIR)/SocketPool.swf: flash/SocketPool.as flash/PooledSocket.as flash/SocketEvent.as - @echo "Building $@..." - $(PCMD) @MXMLC@ $(FLASH_FLAGS) \ - -load-config+=build-flash.xml \ - -output=$@ $< -else -ifeq (@USE_PRE_BUILT_FLASH@,yes) -$(DIST_DIR)/SocketPool.swf: @FORGE_DIR@/swf/SocketPool.swf - @echo "Copying pre-built $(@F)..." - $(PCMD) cp $< $@ -endif -endif - -$(DIST_DIR)/%.js: js/%.js - @echo "Linking $@..." - $(PCMD) ln -sf $(realpath $<) $@ - -$(TESTS_FORGE_LINK): $(DIST_DIR) - @echo "Linking $@..." - $(PCMD) ln -sf $(realpath $<) $@ - -ifeq (@BUILD_PYTHON_MODULES@,yes) -$(SSL_SESSIONS_DIR)/_forge_ssl.so: \ - @FORGE_DIR@/tests/forge_ssl/forge/_ssl.c \ - @FORGE_DIR@/tests/forge_ssl/forge/socketmodule.h \ - @FORGE_DIR@/tests/forge_ssl/setup.py -$(SSL_SESSIONS_DIR)/forge/ssl.py: \ - @FORGE_DIR@/tests/forge_ssl/forge/ssl.py \ - @FORGE_DIR@/tests/forge_ssl/setup.py - (cd @FORGE_DIR@/tests/forge_ssl && \ - @PYTHON@ setup.py \ - build --build-base $(BUILD_DIR) \ - install --prefix=$(TOP_DIST_DIR)/forge_ssl) - @# fix distutils timestamp issue - @# (sub-seconds of source file are truncated on target so rebuild is - @# always triggered) - @touch $@ -endif - -clean: - $(PCMD) rm -rf $(BUILD_DIR) $(TOP_DIST_DIR) - @echo "Removed all generated files." - -verbose-commands: - PRINT_COMMANDS=true $(MAKE) all diff --git a/alarm/node_modules/node-forge/README.md b/alarm/node_modules/node-forge/README.md deleted file mode 100644 index 0130ef4..0000000 --- a/alarm/node_modules/node-forge/README.md +++ /dev/null @@ -1,1796 +0,0 @@ -# Forge - -[![Build Status][travis-ci-png]][travis-ci-site] -[travis-ci-png]: https://travis-ci.org/digitalbazaar/forge.png?branch=master -[travis-ci-site]: https://travis-ci.org/digitalbazaar/forge - -A native implementation of [TLS][] (and various other cryptographic tools) in -[JavaScript][]. - -## Introduction - -The Forge software is a fully native implementation of the [TLS][] protocol in -JavaScript as well as a set of tools for developing Web Apps that utilize many -network resources. - -## Performance - -Forge is fast. Benchmarks against other popular JavaScript cryptography -libraries can be found here: - -http://dominictarr.github.io/crypto-bench/ - -http://cryptojs.altervista.org/test/simulate-threading-speed_test.html - -## Getting Started ------------------- - -### Node.js ### - -If you want to use forge with [node.js][], it is available through `npm`: - -https://npmjs.org/package/node-forge - -Installation: - - npm install node-forge - -You can then use forge as a regular module: - - var forge = require('node-forge'); - -### Requirements ### - -* General - * Optional: GNU autotools for the build infrastructure if using Flash. -* Building a Browser Bundle: - * nodejs - * npm -* Testing - * nodejs - * Optional: Python and OpenSSL development environment to build - * a special SSL module with session cache support for testing with flash. - * http://www.python.org/dev/ - * http://www.openssl.org/ - * Debian users should install python-dev and libssl-dev. -* Optional: Flash - * A pre-built SocketPool.swf is included. - * Adobe Flex 3 SDK to build the Flash socket code. - * http://opensource.adobe.com/wiki/display/flexsdk/ - -### Building a browser bundle ### - -To create a minimized JavaScript bundle, run the following: - -``` -npm install -npm run minify -``` - -This will create a single minimized file that can be included in -the browser: - -``` -js/forge.min.js -``` - -Include the file via: - -```html -<script src="js/forge.min.js"></script> -``` - -Note that the minify script depends on the requirejs package, -and that the requirejs binary 'r.js' assumes that the name of -the node binary is 'node' not 'nodejs', as it is on some -systems. You may need to change the hashbang line to use -'nodejs' or run the command manually. - -To create a single non-minimized file that can be included in -the browser: - -``` -npm install -npm run bundle -``` - -This will create: - -``` -js/forge.bundle.js -``` - -Include the file via: - -```html -<script src="js/forge.bundle.js"></script> -``` - -The above bundles will synchronously create a global 'forge' object. - -Keep in mind that these bundles will not include any WebWorker -scripts (eg: prime.worker.js) or their dependencies, so these will -need to be accessible from the browser if any WebWorkers are used. - -### Testing with NodeJS & RequireJS ### - -A test server for [node.js][] can be found at `./nodejs`. The following are included: - - * Example of how to use `forge` within NodeJS in the form of a [mocha](http://mochajs.org/) test. - * Example of how to serve `forge` to the browser using [RequireJS](http://requirejs.org/). - -To run: - - cd nodejs - npm install - npm test - npm start - - -### Old build system that includes flash support ### - -To build the whole project, including Flash, run the following: - - $ ./build-setup - $ make - -This will create the SWF, symlink all the JavaScript files, and build a Python -SSL module for testing. To see configure options, run `./configure --help`. - -### Old test system including flash support ### - -A test server is provided which can be run in TLS mode and non-TLS mode. Use -the --help option to get help for configuring ports. The server will print out -the local URL you can vist to run tests. - -Some of the simplier tests should be run with just the non-TLS server:: - - $ ./tests/server.py - -More advanced tests need TLS enabled:: - - $ ./tests/server.py --tls - -## Contributing ---------------- - -Any contributions (eg: PRs) that are accepted will be brought under the same -license used by the rest of the Forge project. This license allows Forge to -be used under the terms of either the BSD License or the GNU General Public -License (GPL) Version 2. - -See: [LICENSE](https://github.com/digitalbazaar/forge/blob/cbebca3780658703d925b61b2caffb1d263a6c1d/LICENSE) - -If a contribution contains 3rd party source code with its own license, it -may retain it, so long as that license is compatible with the Forge license. - -## Documentation ----------------- - -### Transports - -* [TLS](#tls) -* [HTTP](#http) -* [SSH](#ssh) -* [XHR](#xhr) -* [Sockets](#socket) - -### Ciphers - -* [CIPHER](#cipher) -* [AES](#aes) -* [DES](#des) -* [RC2](#rc2) - -### PKI - -* [RSA](#rsa) -* [RSA-KEM](#rsakem) -* [X.509](#x509) -* [PKCS#5](#pkcs5) -* [PKCS#7](#pkcs7) -* [PKCS#8](#pkcs8) -* [PKCS#10](#pkcs10) -* [PKCS#12](#pkcs12) -* [ASN.1](#asn) - -### Message Digests - -* [SHA1](#sha1) -* [SHA256](#sha256) -* [SHA384](#sha384) -* [SHA512](#sha512) -* [MD5](#md5) -* [HMAC](#hmac) - -### Utilities - -* [Prime](#prime) -* [PRNG](#prng) -* [Tasks](#task) -* [Utilities](#util) -* [Logging](#log) -* [Debugging](#debug) -* [Flash Socket Policy Module](#fsp) - ---------------------------------------- - -If at any time you wish to disable the use of native code, where available, -for particular forge features like its secure random number generator, you -may set the ```disableNativeCode``` flag on ```forge``` to ```true```. It -is not recommended that you set this flag as native code is typically more -performant and may have stronger security properties. It may be useful to -set this flag to test certain features that you plan to run in environments -that are different from your testing environment. - -To disable native code when including forge in the browser: - -```js -forge = {disableNativeCode: true}; -// now include forge script file(s) -// Note: with this approach, script files *must* -// be included after initializing the global forge var - -// alternatively, include script files first and then call -forge = forge({disableNativeCode: true}); - -// Note: forge will be permanently reconfigured now; -// to avoid this but use the same "forge" var name, -// you can wrap your code in a function to shadow the -// global var, eg: -(function(forge) { - // ... -})(forge({disableNativeCode: true})); -``` - -To disable native code when using node.js: - -```js -var forge = require('node-forge')({disableNativeCode: true}); -``` - ---------------------------------------- -## Transports - -<a name="tls" /> -### TLS - -Provides a native javascript client and server-side [TLS][] implementation. - -__Examples__ - -```js -// create TLS client -var client = forge.tls.createConnection({ - server: false, - caStore: /* Array of PEM-formatted certs or a CA store object */, - sessionCache: {}, - // supported cipher suites in order of preference - cipherSuites: [ - forge.tls.CipherSuites.TLS_RSA_WITH_AES_128_CBC_SHA, - forge.tls.CipherSuites.TLS_RSA_WITH_AES_256_CBC_SHA], - virtualHost: 'example.com', - verify: function(connection, verified, depth, certs) { - if(depth === 0) { - var cn = certs[0].subject.getField('CN').value; - if(cn !== 'example.com') { - verified = { - alert: forge.tls.Alert.Description.bad_certificate, - message: 'Certificate common name does not match hostname.' - }; - } - } - return verified; - }, - connected: function(connection) { - console.log('connected'); - // send message to server - connection.prepare(forge.util.encodeUtf8('Hi server!')); - /* NOTE: experimental, start heartbeat retransmission timer - myHeartbeatTimer = setInterval(function() { - connection.prepareHeartbeatRequest(forge.util.createBuffer('1234')); - }, 5*60*1000);*/ - }, - /* provide a client-side cert if you want - getCertificate: function(connection, hint) { - return myClientCertificate; - }, - /* the private key for the client-side cert if provided */ - getPrivateKey: function(connection, cert) { - return myClientPrivateKey; - }, - tlsDataReady: function(connection) { - // TLS data (encrypted) is ready to be sent to the server - sendToServerSomehow(connection.tlsData.getBytes()); - // if you were communicating with the server below, you'd do: - // server.process(connection.tlsData.getBytes()); - }, - dataReady: function(connection) { - // clear data from the server is ready - console.log('the server sent: ' + - forge.util.decodeUtf8(connection.data.getBytes())); - // close connection - connection.close(); - }, - /* NOTE: experimental - heartbeatReceived: function(connection, payload) { - // restart retransmission timer, look at payload - clearInterval(myHeartbeatTimer); - myHeartbeatTimer = setInterval(function() { - connection.prepareHeartbeatRequest(forge.util.createBuffer('1234')); - }, 5*60*1000); - payload.getBytes(); - },*/ - closed: function(connection) { - console.log('disconnected'); - }, - error: function(connection, error) { - console.log('uh oh', error); - } -}); - -// start the handshake process -client.handshake(); - -// when encrypted TLS data is received from the server, process it -client.process(encryptedBytesFromServer); - -// create TLS server -var server = forge.tls.createConnection({ - server: true, - caStore: /* Array of PEM-formatted certs or a CA store object */, - sessionCache: {}, - // supported cipher suites in order of preference - cipherSuites: [ - forge.tls.CipherSuites.TLS_RSA_WITH_AES_128_CBC_SHA, - forge.tls.CipherSuites.TLS_RSA_WITH_AES_256_CBC_SHA], - // require a client-side certificate if you want - verifyClient: true, - verify: function(connection, verified, depth, certs) { - if(depth === 0) { - var cn = certs[0].subject.getField('CN').value; - if(cn !== 'the-client') { - verified = { - alert: forge.tls.Alert.Description.bad_certificate, - message: 'Certificate common name does not match expected client.' - }; - } - } - return verified; - }, - connected: function(connection) { - console.log('connected'); - // send message to client - connection.prepare(forge.util.encodeUtf8('Hi client!')); - /* NOTE: experimental, start heartbeat retransmission timer - myHeartbeatTimer = setInterval(function() { - connection.prepareHeartbeatRequest(forge.util.createBuffer('1234')); - }, 5*60*1000);*/ - }, - getCertificate: function(connection, hint) { - return myServerCertificate; - }, - getPrivateKey: function(connection, cert) { - return myServerPrivateKey; - }, - tlsDataReady: function(connection) { - // TLS data (encrypted) is ready to be sent to the client - sendToClientSomehow(connection.tlsData.getBytes()); - // if you were communicating with the client above you'd do: - // client.process(connection.tlsData.getBytes()); - }, - dataReady: function(connection) { - // clear data from the client is ready - console.log('the client sent: ' + - forge.util.decodeUtf8(connection.data.getBytes())); - // close connection - connection.close(); - }, - /* NOTE: experimental - heartbeatReceived: function(connection, payload) { - // restart retransmission timer, look at payload - clearInterval(myHeartbeatTimer); - myHeartbeatTimer = setInterval(function() { - connection.prepareHeartbeatRequest(forge.util.createBuffer('1234')); - }, 5*60*1000); - payload.getBytes(); - },*/ - closed: function(connection) { - console.log('disconnected'); - }, - error: function(connection, error) { - console.log('uh oh', error); - } -}); - -// when encrypted TLS data is received from the client, process it -server.process(encryptedBytesFromClient); -``` - -Connect to a TLS server using node's net.Socket: - -```js -var socket = new net.Socket(); - -var client = forge.tls.createConnection({ - server: false, - verify: function(connection, verified, depth, certs) { - // skip verification for testing - console.log('[tls] server certificate verified'); - return true; - }, - connected: function(connection) { - console.log('[tls] connected'); - // prepare some data to send (note that the string is interpreted as - // 'binary' encoded, which works for HTTP which only uses ASCII, use - // forge.util.encodeUtf8(str) otherwise - client.prepare('GET / HTTP/1.0\r\n\r\n'); - }, - tlsDataReady: function(connection) { - // encrypted data is ready to be sent to the server - var data = connection.tlsData.getBytes(); - socket.write(data, 'binary'); // encoding should be 'binary' - }, - dataReady: function(connection) { - // clear data from the server is ready - var data = connection.data.getBytes(); - console.log('[tls] data received from the server: ' + data); - }, - closed: function() { - console.log('[tls] disconnected'); - }, - error: function(connection, error) { - console.log('[tls] error', error); - } -}); - -socket.on('connect', function() { - console.log('[socket] connected'); - client.handshake(); -}); -socket.on('data', function(data) { - client.process(data.toString('binary')); // encoding should be 'binary' -}); -socket.on('end', function() { - console.log('[socket] disconnected'); -}); - -// connect to google.com -socket.connect(443, 'google.com'); - -// or connect to gmail's imap server (but don't send the HTTP header above) -//socket.connect(993, 'imap.gmail.com'); -``` - -<a name="http" /> -### HTTP - -Provides a native [JavaScript][] mini-implementation of an http client that -uses pooled sockets. - -__Examples__ - -```js -// create an HTTP GET request -var request = forge.http.createRequest({method: 'GET', path: url.path}); - -// send the request somewhere -sendSomehow(request.toString()); - -// receive response -var buffer = forge.util.createBuffer(); -var response = forge.http.createResponse(); -var someAsyncDataHandler = function(bytes) { - if(!response.bodyReceived) { - buffer.putBytes(bytes); - if(!response.headerReceived) { - if(response.readHeader(buffer)) { - console.log('HTTP response header: ' + response.toString()); - } - } - if(response.headerReceived && !response.bodyReceived) { - if(response.readBody(buffer)) { - console.log('HTTP response body: ' + response.body); - } - } - } -}; -``` - -<a name="ssh" /> -### SSH - -Provides some SSH utility functions. - -__Examples__ - -```js -// encodes (and optionally encrypts) a private RSA key as a Putty PPK file -forge.ssh.privateKeyToPutty(privateKey, passphrase, comment); - -// encodes a public RSA key as an OpenSSH file -forge.ssh.publicKeyToOpenSSH(key, comment); - -// encodes a private RSA key as an OpenSSH file -forge.ssh.privateKeyToOpenSSH(privateKey, passphrase); - -// gets the SSH public key fingerprint in a byte buffer -forge.ssh.getPublicKeyFingerprint(key); - -// gets a hex-encoded, colon-delimited SSH public key fingerprint -forge.ssh.getPublicKeyFingerprint(key, {encoding: 'hex', delimiter: ':'}); -``` - -<a name="xhr" /> -### XHR - -Provides an XmlHttpRequest implementation using forge.http as a backend. - -__Examples__ - -```js -``` - -<a name="socket" /> -### Sockets - -Provides an interface to create and use raw sockets provided via Flash. - -__Examples__ - -```js -``` - ---------------------------------------- -## Ciphers - -<a name="cipher" /> -### CIPHER - -Provides a basic API for block encryption and decryption. There is built-in -support for the ciphers: [AES][], [3DES][], and [DES][], and for the modes -of operation: [ECB][], [CBC][], [CFB][], [OFB][], [CTR][], and [GCM][]. - -These algorithms are currently supported: - -* AES-ECB -* AES-CBC -* AES-CFB -* AES-OFB -* AES-CTR -* AES-GCM -* 3DES-ECB -* 3DES-CBC -* DES-ECB -* DES-CBC - -When using an [AES][] algorithm, the key size will determine whether -AES-128, AES-192, or AES-256 is used (all are supported). When a [DES][] -algorithm is used, the key size will determine whether [3DES][] or regular -[DES][] is used. Use a [3DES][] algorithm to enforce Triple-DES. - -__Examples__ - -```js -// generate a random key and IV -// Note: a key size of 16 bytes will use AES-128, 24 => AES-192, 32 => AES-256 -var key = forge.random.getBytesSync(16); -var iv = forge.random.getBytesSync(16); - -/* alternatively, generate a password-based 16-byte key -var salt = forge.random.getBytesSync(128); -var key = forge.pkcs5.pbkdf2('password', salt, numIterations, 16); -*/ - -// encrypt some bytes using CBC mode -// (other modes include: ECB, CFB, OFB, CTR, and GCM) -var cipher = forge.cipher.createCipher('AES-CBC', key); -cipher.start({iv: iv}); -cipher.update(forge.util.createBuffer(someBytes)); -cipher.finish(); -var encrypted = cipher.output; -// outputs encrypted hex -console.log(encrypted.toHex()); - -// decrypt some bytes using CBC mode -// (other modes include: CFB, OFB, CTR, and GCM) -var decipher = forge.cipher.createDecipher('AES-CBC', key); -decipher.start({iv: iv}); -decipher.update(encrypted); -decipher.finish(); -// outputs decrypted hex -console.log(decipher.output.toHex()); - -// encrypt some bytes using GCM mode -var cipher = forge.cipher.createCipher('AES-GCM', key); -cipher.start({ - iv: iv, // should be a 12-byte binary-encoded string or byte buffer - additionalData: 'binary-encoded string', // optional - tagLength: 128 // optional, defaults to 128 bits -}); -cipher.update(forge.util.createBuffer(someBytes)); -cipher.finish(); -var encrypted = cipher.output; -var tag = cipher.mode.tag; -// outputs encrypted hex -console.log(encrypted.toHex()); -// outputs authentication tag -console.log(tag.toHex()); - -// decrypt some bytes using GCM mode -var decipher = forge.cipher.createDecipher('AES-GCM', key); -decipher.start({ - iv: iv, - additionalData: 'binary-encoded string', // optional - tagLength: 128, // optional, defaults to 128 bits - tag: tag // authentication tag from encryption -}); -decipher.update(encrypted); -var pass = decipher.finish(); -// pass is false if there was a failure (eg: authentication tag didn't match) -if(pass) { - // outputs decrypted hex - console.log(decipher.output.toHex()); -} -``` - -Using forge in node.js to match openssl's "enc" command line tool (**Note**: OpenSSL "enc" uses a non-standard file format with a custom key derivation function and a fixed iteration count of 1, which some consider less secure than alternatives such as [OpenPGP](https://tools.ietf.org/html/rfc4880)/[GnuPG](https://www.gnupg.org/)): - -```js -var forge = require('node-forge'); -var fs = require('fs'); - -// openssl enc -des3 -in input.txt -out input.enc -function encrypt(password) { - var input = fs.readFileSync('input.txt', {encoding: 'binary'}); - - // 3DES key and IV sizes - var keySize = 24; - var ivSize = 8; - - // get derived bytes - // Notes: - // 1. If using an alternative hash (eg: "-md sha1") pass - // "forge.md.sha1.create()" as the final parameter. - // 2. If using "-nosalt", set salt to null. - var salt = forge.random.getBytesSync(8); - // var md = forge.md.sha1.create(); // "-md sha1" - var derivedBytes = forge.pbe.opensslDeriveBytes( - password, salt, keySize + ivSize/*, md*/); - var buffer = forge.util.createBuffer(derivedBytes); - var key = buffer.getBytes(keySize); - var iv = buffer.getBytes(ivSize); - - var cipher = forge.cipher.createCipher('3DES-CBC', key); - cipher.start({iv: iv}); - cipher.update(forge.util.createBuffer(input, 'binary')); - cipher.finish(); - - var output = forge.util.createBuffer(); - - // if using a salt, prepend this to the output: - if(salt !== null) { - output.putBytes('Salted__'); // (add to match openssl tool output) - output.putBytes(salt); - } - output.putBuffer(cipher.output); - - fs.writeFileSync('input.enc', output.getBytes(), {encoding: 'binary'}); -} - -// openssl enc -d -des3 -in input.enc -out input.dec.txt -function decrypt(password) { - var input = fs.readFileSync('input.enc', {encoding: 'binary'}); - - // parse salt from input - input = forge.util.createBuffer(input, 'binary'); - // skip "Salted__" (if known to be present) - input.getBytes('Salted__'.length); - // read 8-byte salt - var salt = input.getBytes(8); - - // Note: if using "-nosalt", skip above parsing and use - // var salt = null; - - // 3DES key and IV sizes - var keySize = 24; - var ivSize = 8; - - var derivedBytes = forge.pbe.opensslDeriveBytes( - password, salt, keySize + ivSize); - var buffer = forge.util.createBuffer(derivedBytes); - var key = buffer.getBytes(keySize); - var iv = buffer.getBytes(ivSize); - - var decipher = forge.cipher.createDecipher('3DES-CBC', key); - decipher.start({iv: iv}); - decipher.update(input); - var result = decipher.finish(); // check 'result' for true/false - - fs.writeFileSync( - 'input.dec.txt', decipher.output.getBytes(), {encoding: 'binary'}); -} -``` - -<a name="aes" /> -### AES - -Provides [AES][] encryption and decryption in [CBC][], [CFB][], [OFB][], -[CTR][], and [GCM][] modes. See [CIPHER](#cipher) for examples. - -<a name="des" /> -### DES - -Provides [3DES][] and [DES][] encryption and decryption in [ECB][] and -[CBC][] modes. See [CIPHER](#cipher) for examples. - -<a name="rc2" /> -### RC2 - -__Examples__ - -```js -// generate a random key and IV -var key = forge.random.getBytesSync(16); -var iv = forge.random.getBytesSync(8); - -// encrypt some bytes -var cipher = forge.rc2.createEncryptionCipher(key); -cipher.start(iv); -cipher.update(forge.util.createBuffer(someBytes)); -cipher.finish(); -var encrypted = cipher.output; -// outputs encrypted hex -console.log(encrypted.toHex()); - -// decrypt some bytes -var cipher = forge.rc2.createDecryptionCipher(key); -cipher.start(iv); -cipher.update(encrypted); -cipher.finish(); -// outputs decrypted hex -console.log(cipher.output.toHex()); -``` ---------------------------------------- -## PKI - -Provides [X.509][] certificate and RSA public and private key encoding, -decoding, encryption/decryption, and signing/verifying. - -<a name="rsa" /> -### RSA - -__Examples__ - -```js -var rsa = forge.pki.rsa; - -// generate an RSA key pair synchronously -var keypair = rsa.generateKeyPair({bits: 2048, e: 0x10001}); - -// generate an RSA key pair asynchronously (uses web workers if available) -// use workers: -1 to run a fast core estimator to optimize # of workers -rsa.generateKeyPair({bits: 2048, workers: 2}, function(err, keypair) { - // keypair.privateKey, keypair.publicKey -}); - -// generate an RSA key pair in steps that attempt to run for a specified period -// of time on the main JS thread -var state = rsa.createKeyPairGenerationState(2048, 0x10001); -var step = function() { - // run for 100 ms - if(!rsa.stepKeyPairGenerationState(state, 100)) { - setTimeout(step, 1); - } - else { - // done, turn off progress indicator, use state.keys - } -}; -// turn on progress indicator, schedule generation to run -setTimeout(step); - -// sign data with a private key and output DigestInfo DER-encoded bytes -// (defaults to RSASSA PKCS#1 v1.5) -var md = forge.md.sha1.create(); -md.update('sign this', 'utf8'); -var signature = privateKey.sign(md); - -// verify data with a public key -// (defaults to RSASSA PKCS#1 v1.5) -var verified = publicKey.verify(md.digest().bytes(), signature); - -// sign data using RSASSA-PSS where PSS uses a SHA-1 hash, a SHA-1 based -// masking function MGF1, and a 20 byte salt -var md = forge.md.sha1.create(); -md.update('sign this', 'utf8'); -var pss = forge.pss.create({ - md: forge.md.sha1.create(), - mgf: forge.mgf.mgf1.create(forge.md.sha1.create()), - saltLength: 20 - // optionally pass 'prng' with a custom PRNG implementation - // optionalls pass 'salt' with a forge.util.ByteBuffer w/custom salt -}); -var signature = privateKey.sign(md, pss); - -// verify RSASSA-PSS signature -var pss = forge.pss.create({ - md: forge.md.sha1.create(), - mgf: forge.mgf.mgf1.create(forge.md.sha1.create()), - saltLength: 20 - // optionally pass 'prng' with a custom PRNG implementation -}); -var md = forge.md.sha1.create(); -md.update('sign this', 'utf8'); -publicKey.verify(md.digest().getBytes(), signature, pss); - -// encrypt data with a public key (defaults to RSAES PKCS#1 v1.5) -var encrypted = publicKey.encrypt(bytes); - -// decrypt data with a private key (defaults to RSAES PKCS#1 v1.5) -var decrypted = privateKey.decrypt(encrypted); - -// encrypt data with a public key using RSAES PKCS#1 v1.5 -var encrypted = publicKey.encrypt(bytes, 'RSAES-PKCS1-V1_5'); - -// decrypt data with a private key using RSAES PKCS#1 v1.5 -var decrypted = privateKey.decrypt(encrypted, 'RSAES-PKCS1-V1_5'); - -// encrypt data with a public key using RSAES-OAEP -var encrypted = publicKey.encrypt(bytes, 'RSA-OAEP'); - -// decrypt data with a private key using RSAES-OAEP -var decrypted = privateKey.decrypt(encrypted, 'RSA-OAEP'); - -// encrypt data with a public key using RSAES-OAEP/SHA-256 -var encrypted = publicKey.encrypt(bytes, 'RSA-OAEP', { - md: forge.md.sha256.create() -}); - -// decrypt data with a private key using RSAES-OAEP/SHA-256 -var decrypted = privateKey.decrypt(encrypted, 'RSA-OAEP', { - md: forge.md.sha256.create() -}); - -// encrypt data with a public key using RSAES-OAEP/SHA-256/MGF1-SHA-1 -// compatible with Java's RSA/ECB/OAEPWithSHA-256AndMGF1Padding -var encrypted = publicKey.encrypt(bytes, 'RSA-OAEP', { - md: forge.md.sha256.create(), - mgf1: { - md: forge.md.sha1.create() - } -}); - -// decrypt data with a private key using RSAES-OAEP/SHA-256/MGF1-SHA-1 -// compatible with Java's RSA/ECB/OAEPWithSHA-256AndMGF1Padding -var decrypted = privateKey.decrypt(encrypted, 'RSA-OAEP', { - md: forge.md.sha256.create(), - mgf1: { - md: forge.md.sha1.create() - } -}); - -``` - -<a name="rsakem" /> -### RSA-KEM - -__Examples__ - -```js -// generate an RSA key pair asynchronously (uses web workers if available) -// use workers: -1 to run a fast core estimator to optimize # of workers -forge.rsa.generateKeyPair({bits: 2048, workers: -1}, function(err, keypair) { - // keypair.privateKey, keypair.publicKey -}); - -// generate and encapsulate a 16-byte secret key -var kdf1 = new forge.kem.kdf1(forge.md.sha1.create()); -var kem = forge.kem.rsa.create(kdf1); -var result = kem.encrypt(keypair.publicKey, 16); -// result has 'encapsulation' and 'key' - -// encrypt some bytes -var iv = forge.random.getBytesSync(12); -var someBytes = 'hello world!'; -var cipher = forge.cipher.createCipher('AES-GCM', result.key); -cipher.start({iv: iv}); -cipher.update(forge.util.createBuffer(someBytes)); -cipher.finish(); -var encrypted = cipher.output.getBytes(); -var tag = cipher.mode.tag.getBytes(); - -// send 'encrypted', 'iv', 'tag', and result.encapsulation to recipient - -// decrypt encapsulated 16-byte secret key -var kdf1 = new forge.kem.kdf1(forge.md.sha1.create()); -var kem = forge.kem.rsa.create(kdf1); -var key = kem.decrypt(keypair.privateKey, result.encapsulation, 16); - -// decrypt some bytes -var decipher = forge.cipher.createDecipher('AES-GCM', key); -decipher.start({iv: iv, tag: tag}); -decipher.update(forge.util.createBuffer(encrypted)); -var pass = decipher.finish(); -// pass is false if there was a failure (eg: authentication tag didn't match) -if(pass) { - // outputs 'hello world!' - console.log(decipher.output.getBytes()); -} - -``` - -<a name="x509" /> -### X.509 - -__Examples__ - -```js -var pki = forge.pki; - -// convert a PEM-formatted public key to a Forge public key -var publicKey = pki.publicKeyFromPem(pem); - -// convert a Forge public key to PEM-format -var pem = pki.publicKeyToPem(publicKey); - -// convert an ASN.1 SubjectPublicKeyInfo to a Forge public key -var publicKey = pki.publicKeyFromAsn1(subjectPublicKeyInfo); - -// convert a Forge public key to an ASN.1 SubjectPublicKeyInfo -var subjectPublicKeyInfo = pki.publicKeyToAsn1(publicKey); - -// gets a SHA-1 RSAPublicKey fingerprint a byte buffer -pki.getPublicKeyFingerprint(key); - -// gets a SHA-1 SubjectPublicKeyInfo fingerprint a byte buffer -pki.getPublicKeyFingerprint(key, {type: 'SubjectPublicKeyInfo'}); - -// gets a hex-encoded, colon-delimited SHA-1 RSAPublicKey public key fingerprint -pki.getPublicKeyFingerprint(key, {encoding: 'hex', delimiter: ':'}); - -// gets a hex-encoded, colon-delimited SHA-1 SubjectPublicKeyInfo public key fingerprint -pki.getPublicKeyFingerprint(key, { - type: 'SubjectPublicKeyInfo', - encoding: 'hex', - delimiter: ':' -}); - -// gets a hex-encoded, colon-delimited MD5 RSAPublicKey public key fingerprint -pki.getPublicKeyFingerprint(key, { - md: forge.md.md5.create(), - encoding: 'hex', - delimiter: ':' -}); - -// creates a CA store -var caStore = pki.createCaStore([/* PEM-encoded cert */, ...]); - -// add a certificate to the CA store -caStore.addCertificate(certObjectOrPemString); - -// gets the issuer (its certificate) for the given certificate -var issuerCert = caStore.getIssuer(subjectCert); - -// verifies a certificate chain against a CA store -pki.verifyCertificateChain(caStore, chain, customVerifyCallback); - -// signs a certificate using the given private key -cert.sign(privateKey); - -// signs a certificate using SHA-256 instead of SHA-1 -cert.sign(privateKey, forge.md.sha256.create()); - -// verifies an issued certificate using the certificates public key -var verified = issuer.verify(issued); - -// generate a keypair and create an X.509v3 certificate -var keys = pki.rsa.generateKeyPair(2048); -var cert = pki.createCertificate(); -cert.publicKey = keys.publicKey; -// alternatively set public key from a csr -//cert.publicKey = csr.publicKey; -cert.serialNumber = '01'; -cert.validity.notBefore = new Date(); -cert.validity.notAfter = new Date(); -cert.validity.notAfter.setFullYear(cert.validity.notBefore.getFullYear() + 1); -var attrs = [{ - name: 'commonName', - value: 'example.org' -}, { - name: 'countryName', - value: 'US' -}, { - shortName: 'ST', - value: 'Virginia' -}, { - name: 'localityName', - value: 'Blacksburg' -}, { - name: 'organizationName', - value: 'Test' -}, { - shortName: 'OU', - value: 'Test' -}]; -cert.setSubject(attrs); -// alternatively set subject from a csr -//cert.setSubject(csr.subject.attributes); -cert.setIssuer(attrs); -cert.setExtensions([{ - name: 'basicConstraints', - cA: true -}, { - name: 'keyUsage', - keyCertSign: true, - digitalSignature: true, - nonRepudiation: true, - keyEncipherment: true, - dataEncipherment: true -}, { - name: 'extKeyUsage', - serverAuth: true, - clientAuth: true, - codeSigning: true, - emailProtection: true, - timeStamping: true -}, { - name: 'nsCertType', - client: true, - server: true, - email: true, - objsign: true, - sslCA: true, - emailCA: true, - objCA: true -}, { - name: 'subjectAltName', - altNames: [{ - type: 6, // URI - value: 'http://example.org/webid#me' - }, { - type: 7, // IP - ip: '127.0.0.1' - }] -}, { - name: 'subjectKeyIdentifier' -}]); -/* alternatively set extensions from a csr -var extensions = csr.getAttribute({name: 'extensionRequest'}).extensions; -// optionally add more extensions -extensions.push.apply(extensions, [{ - name: 'basicConstraints', - cA: true -}, { - name: 'keyUsage', - keyCertSign: true, - digitalSignature: true, - nonRepudiation: true, - keyEncipherment: true, - dataEncipherment: true -}]); -cert.setExtensions(extensions); -*/ -// self-sign certificate -cert.sign(keys.privateKey); - -// convert a Forge certificate to PEM -var pem = pki.certificateToPem(cert); - -// convert a Forge certificate from PEM -var cert = pki.certificateFromPem(pem); - -// convert an ASN.1 X.509x3 object to a Forge certificate -var cert = pki.certificateFromAsn1(obj); - -// convert a Forge certificate to an ASN.1 X.509v3 object -var asn1Cert = pki.certificateToAsn1(cert); -``` - -<a name="pkcs5" /> -### PKCS#5 - -Provides the password-based key-derivation function from [PKCS#5][]. - -__Examples__ - -```js -// generate a password-based 16-byte key -// note an optional message digest can be passed as the final parameter -var salt = forge.random.getBytesSync(128); -var derivedKey = forge.pkcs5.pbkdf2('password', salt, numIterations, 16); - -// generate key asynchronously -// note an optional message digest can be passed before the callback -forge.pkcs5.pbkdf2('password', salt, numIterations, 16, function(err, derivedKey) { - // do something w/derivedKey -}); -``` - -<a name="pkcs7" /> -### PKCS#7 - -Provides cryptographically protected messages from [PKCS#7][]. - -__Examples__ - -```js -// convert a message from PEM -var p7 = forge.pkcs7.messageFromPem(pem); -// look at p7.recipients - -// find a recipient by the issuer of a certificate -var recipient = p7.findRecipient(cert); - -// decrypt -p7.decrypt(p7.recipients[0], privateKey); - -// create a p7 enveloped message -var p7 = forge.pkcs7.createEnvelopedData(); - -// add a recipient -var cert = forge.pki.certificateFromPem(certPem); -p7.addRecipient(cert); - -// set content -p7.content = forge.util.createBuffer('Hello'); - -// encrypt -p7.encrypt(); - -// convert message to PEM -var pem = forge.pkcs7.messageToPem(p7); - -// create a degenerate PKCS#7 certificate container -// (CRLs not currently supported, only certificates) -var p7 = forge.pkcs7.createSignedData(); -p7.addCertificate(certOrCertPem1); -p7.addCertificate(certOrCertPem2); -var pem = forge.pkcs7.messageToPem(p7); -``` - -<a name="pkcs8" /> -### PKCS#8 - -__Examples__ - -```js -var pki = forge.pki; - -// convert a PEM-formatted private key to a Forge private key -var privateKey = pki.privateKeyFromPem(pem); - -// convert a Forge private key to PEM-format -var pem = pki.privateKeyToPem(privateKey); - -// convert an ASN.1 PrivateKeyInfo or RSAPrivateKey to a Forge private key -var privateKey = pki.privateKeyFromAsn1(rsaPrivateKey); - -// convert a Forge private key to an ASN.1 RSAPrivateKey -var rsaPrivateKey = pki.privateKeyToAsn1(privateKey); - -// wrap an RSAPrivateKey ASN.1 object in a PKCS#8 ASN.1 PrivateKeyInfo -var privateKeyInfo = pki.wrapRsaPrivateKey(rsaPrivateKey); - -// convert a PKCS#8 ASN.1 PrivateKeyInfo to PEM -var pem = pki.privateKeyInfoToPem(privateKeyInfo); - -// encrypts a PrivateKeyInfo and outputs an EncryptedPrivateKeyInfo -var encryptedPrivateKeyInfo = pki.encryptPrivateKeyInfo( - privateKeyInfo, 'password', { - algorithm: 'aes256', // 'aes128', 'aes192', 'aes256', '3des' - }); - -// decrypts an ASN.1 EncryptedPrivateKeyInfo -var privateKeyInfo = pki.decryptPrivateKeyInfo( - encryptedPrivateKeyInfo, 'password'); - -// converts an EncryptedPrivateKeyInfo to PEM -var pem = pki.encryptedPrivateKeyToPem(encryptedPrivateKeyInfo); - -// converts a PEM-encoded EncryptedPrivateKeyInfo to ASN.1 format -var encryptedPrivateKeyInfo = pki.encryptedPrivateKeyFromPem(pem); - -// wraps and encrypts a Forge private key and outputs it in PEM format -var pem = pki.encryptRsaPrivateKey(privateKey, 'password'); - -// encrypts a Forge private key and outputs it in PEM format using OpenSSL's -// proprietary legacy format + encapsulated PEM headers (DEK-Info) -var pem = pki.encryptRsaPrivateKey(privateKey, 'password', {legacy: true}); - -// decrypts a PEM-formatted, encrypted private key -var privateKey = pki.decryptRsaPrivateKey(pem, 'password'); - -// sets an RSA public key from a private key -var publicKey = pki.setRsaPublicKey(privateKey.n, privateKey.e); -``` - -<a name="pkcs10" /> -### PKCS#10 - -Provides certification requests or certificate signing requests (CSR) from -[PKCS#10][]. - -__Examples__ - -```js -// generate a key pair -var keys = forge.pki.rsa.generateKeyPair(1024); - -// create a certification request (CSR) -var csr = forge.pki.createCertificationRequest(); -csr.publicKey = keys.publicKey; -csr.setSubject([{ - name: 'commonName', - value: 'example.org' -}, { - name: 'countryName', - value: 'US' -}, { - shortName: 'ST', - value: 'Virginia' -}, { - name: 'localityName', - value: 'Blacksburg' -}, { - name: 'organizationName', - value: 'Test' -}, { - shortName: 'OU', - value: 'Test' -}]); -// set (optional) attributes -csr.setAttributes([{ - name: 'challengePassword', - value: 'password' -}, { - name: 'unstructuredName', - value: 'My Company, Inc.' -}, { - name: 'extensionRequest', - extensions: [{ - name: 'subjectAltName', - altNames: [{ - // 2 is DNS type - type: 2, - value: 'test.domain.com' - }, { - type: 2, - value: 'other.domain.com', - }, { - type: 2, - value: 'www.domain.net' - }] - }] -}]); - -// sign certification request -csr.sign(keys.privateKey); - -// verify certification request -var verified = csr.verify(); - -// convert certification request to PEM-format -var pem = forge.pki.certificationRequestToPem(csr); - -// convert a Forge certification request from PEM-format -var csr = forge.pki.certificationRequestFromPem(pem); - -// get an attribute -csr.getAttribute({name: 'challengePassword'}); - -// get extensions array -csr.getAttribute({name: 'extensionRequest'}).extensions; - -``` - -<a name="pkcs12" /> -### PKCS#12 - -Provides the cryptographic archive file format from [PKCS#12][]. - -__Examples__ - -```js -// decode p12 from base64 -var p12Der = forge.util.decode64(p12b64); -// get p12 as ASN.1 object -var p12Asn1 = forge.asn1.fromDer(p12Der); -// decrypt p12 using the password 'password' -var p12 = forge.pkcs12.pkcs12FromAsn1(p12Asn1, 'password'); -// decrypt p12 using non-strict parsing mode (resolves some ASN.1 parse errors) -var p12 = forge.pkcs12.pkcs12FromAsn1(p12Asn1, false, 'password'); -// decrypt p12 using literally no password (eg: Mac OS X/apple push) -var p12 = forge.pkcs12.pkcs12FromAsn1(p12Asn1); -// decrypt p12 using an "empty" password (eg: OpenSSL with no password input) -var p12 = forge.pkcs12.pkcs12FromAsn1(p12Asn1, ''); -// p12.safeContents is an array of safe contents, each of -// which contains an array of safeBags - -// get bags by friendlyName -var bags = p12.getBags({friendlyName: 'test'}); -// bags are key'd by attribute type (here "friendlyName") -// and the key values are an array of matching objects -var cert = bags.friendlyName[0]; - -// get bags by localKeyId -var bags = p12.getBags({localKeyId: buffer}); -// bags are key'd by attribute type (here "localKeyId") -// and the key values are an array of matching objects -var cert = bags.localKeyId[0]; - -// get bags by localKeyId (input in hex) -var bags = p12.getBags({localKeyIdHex: '7b59377ff142d0be4565e9ac3d396c01401cd879'}); -// bags are key'd by attribute type (here "localKeyId", *not* "localKeyIdHex") -// and the key values are an array of matching objects -var cert = bags.localKeyId[0]; - -// get bags by type -var bags = p12.getBags({bagType: forge.pki.oids.certBag}); -// bags are key'd by bagType and each bagType key's value -// is an array of matches (in this case, certificate objects) -var cert = bags[forge.pki.oids.certBag][0]; - -// get bags by friendlyName and filter on bag type -var bags = p12.getBags({ - friendlyName: 'test', - bagType: forge.pki.oids.certBag -}); - -// get key bags -var bags = p12.getBags({bagType: forge.pki.oids.keyBag}); -// get key -var bag = bags[forge.pki.oids.keyBag][0]; -var key = bag.key; -// if the key is in a format unrecognized by forge then -// bag.key will be `null`, use bag.asn1 to get the ASN.1 -// representation of the key -if(bag.key === null) { - var keyAsn1 = bag.asn1; - // can now convert back to DER/PEM/etc for export -} - -// generate a p12 using AES (default) -var p12Asn1 = forge.pkcs12.toPkcs12Asn1( - privateKey, certificateChain, 'password'); - -// generate a p12 that can be imported by Chrome/Firefox -// (requires the use of Triple DES instead of AES) -var p12Asn1 = forge.pkcs12.toPkcs12Asn1( - privateKey, certificateChain, 'password', - {algorithm: '3des'}); - -// base64-encode p12 -var p12Der = forge.asn1.toDer(p12Asn1).getBytes(); -var p12b64 = forge.util.encode64(p12Der); - -// create download link for p12 -var a = document.createElement('a'); -a.download = 'example.p12'; -a.setAttribute('href', 'data:application/x-pkcs12;base64,' + p12b64); -a.appendChild(document.createTextNode('Download')); -``` - -<a name="asn" /> -### ASN.1 - -Provides [ASN.1][] DER encoding and decoding. - -__Examples__ - -```js -var asn1 = forge.asn1; - -// create a SubjectPublicKeyInfo -var subjectPublicKeyInfo = - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [ - // AlgorithmIdentifier - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [ - // algorithm - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, - asn1.oidToDer(pki.oids['rsaEncryption']).getBytes()), - // parameters (null) - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.NULL, false, '') - ]), - // subjectPublicKey - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.BITSTRING, false, [ - // RSAPublicKey - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [ - // modulus (n) - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false, - _bnToBytes(key.n)), - // publicExponent (e) - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false, - _bnToBytes(key.e)) - ]) - ]) - ]); - -// serialize an ASN.1 object to DER format -var derBuffer = asn1.toDer(subjectPublicKeyInfo); - -// deserialize to an ASN.1 object from a byte buffer filled with DER data -var object = asn1.fromDer(derBuffer); - -// convert an OID dot-separated string to a byte buffer -var derOidBuffer = asn1.oidToDer('1.2.840.113549.1.1.5'); - -// convert a byte buffer with a DER-encoded OID to a dot-separated string -console.log(asn1.derToDer(derOidBuffer)); -// output: 1.2.840.113549.1.1.5 - -// validates that an ASN.1 object matches a particular ASN.1 structure and -// captures data of interest from that structure for easy access -var publicKeyValidator = { - name: 'SubjectPublicKeyInfo', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.SEQUENCE, - constructed: true, - captureAsn1: 'subjectPublicKeyInfo', - value: [{ - name: 'SubjectPublicKeyInfo.AlgorithmIdentifier', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.SEQUENCE, - constructed: true, - value: [{ - name: 'AlgorithmIdentifier.algorithm', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.OID, - constructed: false, - capture: 'publicKeyOid' - }] - }, { - // subjectPublicKey - name: 'SubjectPublicKeyInfo.subjectPublicKey', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.BITSTRING, - constructed: false, - value: [{ - // RSAPublicKey - name: 'SubjectPublicKeyInfo.subjectPublicKey.RSAPublicKey', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.SEQUENCE, - constructed: true, - optional: true, - captureAsn1: 'rsaPublicKey' - }] - }] -}; - -var capture = {}; -var errors = []; -if(!asn1.validate( - publicKeyValidator, subjectPublicKeyInfo, validator, capture, errors)) { - throw 'ASN.1 object is not a SubjectPublicKeyInfo.'; -} -// capture.subjectPublicKeyInfo contains the full ASN.1 object -// capture.rsaPublicKey contains the full ASN.1 object for the RSA public key -// capture.publicKeyOid only contains the value for the OID -var oid = asn1.derToOid(capture.publicKeyOid); -if(oid !== pki.oids['rsaEncryption']) { - throw 'Unsupported OID.'; -} - -// pretty print an ASN.1 object to a string for debugging purposes -asn1.prettyPrint(object); -``` - ---------------------------------------- -## Message Digests - -<a name="sha1" /> -### SHA1 - -Provides [SHA-1][] message digests. - -__Examples__ - -```js -var md = forge.md.sha1.create(); -md.update('The quick brown fox jumps over the lazy dog'); -console.log(md.digest().toHex()); -// output: 2fd4e1c67a2d28fced849ee1bb76e7391b93eb12 -``` - -<a name="sha256" /> -### SHA256 - -Provides [SHA-256][] message digests. - -__Examples__ - -```js -var md = forge.md.sha256.create(); -md.update('The quick brown fox jumps over the lazy dog'); -console.log(md.digest().toHex()); -// output: d7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592 -``` - -<a name="sha384" /> -### SHA384 - -Provides [SHA-384][] message digests. - -__Examples__ - -```js -var md = forge.md.sha384.create(); -md.update('The quick brown fox jumps over the lazy dog'); -console.log(md.digest().toHex()); -// output: ca737f1014a48f4c0b6dd43cb177b0afd9e5169367544c494011e3317dbf9a509cb1e5dc1e85a941bbee3d7f2afbc9b1 -``` - -<a name="sha512" /> -### SHA512 - -Provides [SHA-512][] message digests. - -__Examples__ - -```js -// SHA-512 -var md = forge.md.sha512.create(); -md.update('The quick brown fox jumps over the lazy dog'); -console.log(md.digest().toHex()); -// output: 07e547d9586f6a73f73fbac0435ed76951218fb7d0c8d788a309d785436bbb642e93a252a954f23912547d1e8a3b5ed6e1bfd7097821233fa0538f3db854fee6 - -// SHA-512/224 -var md = forge.md.sha512.sha224.create(); -md.update('The quick brown fox jumps over the lazy dog'); -console.log(md.digest().toHex()); -// output: 944cd2847fb54558d4775db0485a50003111c8e5daa63fe722c6aa37 - -// SHA-512/256 -var md = forge.md.sha512.sha256.create(); -md.update('The quick brown fox jumps over the lazy dog'); -console.log(md.digest().toHex()); -// output: dd9d67b371519c339ed8dbd25af90e976a1eeefd4ad3d889005e532fc5bef04d -``` - -<a name="md5" /> -### MD5 - -Provides [MD5][] message digests. - -__Examples__ - -```js -var md = forge.md.md5.create(); -md.update('The quick brown fox jumps over the lazy dog'); -console.log(md.digest().toHex()); -// output: 9e107d9d372bb6826bd81d3542a419d6 -``` - -<a name="hmac" /> -### HMAC - -Provides [HMAC][] w/any supported message digest algorithm. - -__Examples__ - -```js -var hmac = forge.hmac.create(); -hmac.start('sha1', 'Jefe'); -hmac.update('what do ya want for nothing?'); -console.log(hmac.digest().toHex()); -// output: effcdf6ae5eb2fa2d27416d5f184df9c259a7c79 -``` - ---------------------------------------- -## Utilities - -<a name="prime" /> -### Prime - -Provides an API for generating large, random, probable primes. - -__Examples__ - -```js -// generate a random prime on the main JS thread -var bits = 1024; -forge.prime.generateProbablePrime(bits, function(err, num) { - console.log('random prime', num.toString(16)); -}); - -// generate a random prime using Web Workers (if available, otherwise -// falls back to the main thread) -var bits = 1024; -var options = { - algorithm: { - name: 'PRIMEINC', - workers: -1 // auto-optimize # of workers - } -}; -forge.prime.generateProbablePrime(bits, options, function(err, num) { - console.log('random prime', num.toString(16)); -}); -``` - -<a name="prng" /> -### PRNG - -Provides a [Fortuna][]-based cryptographically-secure pseudo-random number -generator, to be used with a cryptographic function backend, e.g. [AES][]. An -implementation using [AES][] as a backend is provided. An API for collecting -entropy is given, though if window.crypto.getRandomValues is available, it will -be used automatically. - -__Examples__ - -```js -// get some random bytes synchronously -var bytes = forge.random.getBytesSync(32); -console.log(forge.util.bytesToHex(bytes)); - -// get some random bytes asynchronously -forge.random.getBytes(32, function(err, bytes) { - console.log(forge.util.bytesToHex(bytes)); -}); - -// collect some entropy if you'd like -forge.random.collect(someRandomBytes); -jQuery().mousemove(function(e) { - forge.random.collectInt(e.clientX, 16); - forge.random.collectInt(e.clientY, 16); -}); - -// specify a seed file for use with the synchronous API if you'd like -forge.random.seedFileSync = function(needed) { - // get 'needed' number of random bytes from somewhere - return fetchedRandomBytes; -}; - -// specify a seed file for use with the asynchronous API if you'd like -forge.random.seedFile = function(needed, callback) { - // get the 'needed' number of random bytes from somewhere - callback(null, fetchedRandomBytes); -}); - -// register the main thread to send entropy or a Web Worker to receive -// entropy on demand from the main thread -forge.random.registerWorker(self); - -// generate a new instance of a PRNG with no collected entropy -var myPrng = forge.random.createInstance(); -``` - -<a name="task" /> -### Tasks - -Provides queuing and synchronizing tasks in a web application. - -__Examples__ - -```js -``` - -<a name="util" /> -### Utilities - -Provides utility functions, including byte buffer support, base64, -bytes to/from hex, zlib inflate/deflate, etc. - -__Examples__ - -```js -// encode/decode base64 -var encoded = forge.util.encode64(str); -var str = forge.util.decode64(encoded); - -// encode/decode UTF-8 -var encoded = forge.util.encodeUtf8(str); -var str = forge.util.decodeUtf8(encoded); - -// bytes to/from hex -var bytes = forge.util.hexToBytes(hex); -var hex = forge.util.bytesToHex(bytes); - -// create an empty byte buffer -var buffer = forge.util.createBuffer(); -// create a byte buffer from raw binary bytes -var buffer = forge.util.createBuffer(input, 'raw'); -// create a byte buffer from utf8 bytes -var buffer = forge.util.createBuffer(input, 'utf8'); - -// get the length of the buffer in bytes -buffer.length(); -// put bytes into the buffer -buffer.putBytes(bytes); -// put a 32-bit integer into the buffer -buffer.putInt32(10); -// buffer to hex -buffer.toHex(); -// get a copy of the bytes in the buffer -bytes.bytes(/* count */); -// empty this buffer and get its contents -bytes.getBytes(/* count */); - -// convert a forge buffer into a node.js Buffer -// make sure you specify the encoding as 'binary' -var forgeBuffer = forge.util.createBuffer(); -var nodeBuffer = new Buffer(forgeBuffer.getBytes(), 'binary'); - -// convert a node.js Buffer into a forge buffer -// make sure you specify the encoding as 'binary' -var nodeBuffer = new Buffer(); -var forgeBuffer = forge.util.createBuffer(nodeBuffer.toString('binary')); - -// parse a URL -var parsed = forge.util.parseUrl('http://example.com/foo?bar=baz'); -// parsed.scheme, parsed.host, parsed.port, parsed.path, parsed.fullHost -``` - -<a name="log" /> -### Logging - -Provides logging to a javascript console using various categories and -levels of verbosity. - -__Examples__ - -```js -``` - -<a name="debug" /> -### Debugging - -Provides storage of debugging information normally inaccessible in -closures for viewing/investigation. - -__Examples__ - -```js -``` - -<a name="fsp" /> -### Flash Socket Policy Module - -Provides an [Apache][] module "mod_fsp" that can serve up a Flash Socket -Policy. See `mod_fsp/README` for more details. This module makes it easy to -modify an [Apache][] server to allow cross domain requests to be made to it. - - -Library Details ---------------- - -* http://digitalbazaar.com/2010/07/20/javascript-tls-1/ -* http://digitalbazaar.com/2010/07/20/javascript-tls-2/ - -Contact -------- - -* Code: https://github.com/digitalbazaar/forge -* Bugs: https://github.com/digitalbazaar/forge/issues -* Email: support@digitalbazaar.com - -Donations welcome: - -* Donate: paypal@digitalbazaar.com - -[AES]: http://en.wikipedia.org/wiki/Advanced_Encryption_Standard -[ASN.1]: http://en.wikipedia.org/wiki/ASN.1 -[Apache]: http://httpd.apache.org/ -[CFB]: http://en.wikipedia.org/wiki/Block_cipher_mode_of_operation -[CBC]: http://en.wikipedia.org/wiki/Block_cipher_mode_of_operation -[CTR]: http://en.wikipedia.org/wiki/Block_cipher_mode_of_operation -[3DES]: http://en.wikipedia.org/wiki/Triple_DES -[DES]: http://en.wikipedia.org/wiki/Data_Encryption_Standard -[ECB]: http://en.wikipedia.org/wiki/Block_cipher_mode_of_operation -[Fortuna]: http://en.wikipedia.org/wiki/Fortuna_(PRNG) -[GCM]: http://en.wikipedia.org/wiki/GCM_mode -[HMAC]: http://en.wikipedia.org/wiki/HMAC -[JavaScript]: http://en.wikipedia.org/wiki/JavaScript -[MD5]: http://en.wikipedia.org/wiki/MD5 -[OFB]: http://en.wikipedia.org/wiki/Block_cipher_mode_of_operation -[PKCS#5]: http://en.wikipedia.org/wiki/PKCS -[PKCS#7]: http://en.wikipedia.org/wiki/Cryptographic_Message_Syntax -[PKCS#10]: http://en.wikipedia.org/wiki/Certificate_signing_request -[PKCS#12]: http://en.wikipedia.org/wiki/PKCS_%E2%99%AF12 -[RC2]: http://en.wikipedia.org/wiki/RC2 -[SHA-1]: http://en.wikipedia.org/wiki/SHA-1 -[SHA-256]: http://en.wikipedia.org/wiki/SHA-256 -[SHA-384]: http://en.wikipedia.org/wiki/SHA-384 -[SHA-512]: http://en.wikipedia.org/wiki/SHA-512 -[TLS]: http://en.wikipedia.org/wiki/Transport_Layer_Security -[X.509]: http://en.wikipedia.org/wiki/X.509 -[node.js]: http://nodejs.org/ diff --git a/alarm/node_modules/node-forge/bower.json b/alarm/node_modules/node-forge/bower.json deleted file mode 100644 index 10e6210..0000000 --- a/alarm/node_modules/node-forge/bower.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "name": "forge", - "version": "0.6.33", - "description": "JavaScript implementations of network transports, cryptography, ciphers, PKI, message digests, and various utilities.", - "moduleType": ["amd"], - "authors": [ - "Digital Bazaar, Inc." - ], - "license": "BSD", - "main": ["js/forge.js"], - "dependencies": {}, - "ignore": [ - "node_modules", - "bower_components" - ] -} diff --git a/alarm/node_modules/node-forge/build-flash.xml b/alarm/node_modules/node-forge/build-flash.xml deleted file mode 100644 index 8d8829c..0000000 --- a/alarm/node_modules/node-forge/build-flash.xml +++ /dev/null @@ -1,7 +0,0 @@ -<flex-config> - <compiler> - <source-path> - <path-element>flash</path-element> - </source-path> - </compiler> -</flex-config> diff --git a/alarm/node_modules/node-forge/build-setup b/alarm/node_modules/node-forge/build-setup deleted file mode 100755 index 5c3866e..0000000 --- a/alarm/node_modules/node-forge/build-setup +++ /dev/null @@ -1,46 +0,0 @@ -#!/bin/sh -# -# This shell script sets up the software to be built using 'make'. In -# order to perform a build from a fresh source tree, do the following: -# -# 1. ./build-setup -# 2. make -# -# If you don't want ./configure to be run automatically, you can do -# the following: ./build-setup -s - -# Process command line options -SKIP_CONFIGURE=0 -for arg in "$*" -do - case $arg in - "-s" | "--setup-only" ) SKIP_CONFIGURE=1 ;; - esac -done - -# Check and add potential aclocal dirs -MAYBE_AC_DIRS=" - /usr/local/share/aclocal - /opt/local/share/aclocal - /sw/share/aclocal - " -ACDIRS="-I m4" -for dir in $MAYBE_AC_DIRS; do - if test -d $dir; then - ACDIRS="$ACDIRS -I $dir" - fi -done - -# Run aclocal on the set of local ac scripts -cd setup -aclocal $ACDIRS -# Generate the configure script -autoconf && mv configure .. -cd .. - -# Run the configure script if "-s" isn't a command line option -if [ $SKIP_CONFIGURE -eq 0 ]; then - # Run the configure script in default development mode - ./configure $* -fi - diff --git a/alarm/node_modules/node-forge/end.frag b/alarm/node_modules/node-forge/end.frag deleted file mode 100644 index cbcf226..0000000 --- a/alarm/node_modules/node-forge/end.frag +++ /dev/null @@ -1,4 +0,0 @@ - -return require('js/forge'); - -}); diff --git a/alarm/node_modules/node-forge/flash/PooledSocket.as b/alarm/node_modules/node-forge/flash/PooledSocket.as deleted file mode 100644 index 15e3ae4..0000000 --- a/alarm/node_modules/node-forge/flash/PooledSocket.as +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright (c) 2009 Digital Bazaar, Inc. All rights reserved. - * - * @author Dave Longley - */ -package -{ - import flash.net.Socket; - - /** - * A helper class that contains the ID for a Socket. - */ - public class PooledSocket extends Socket - { - // the ID in the related socket pool - public var id:String; - } -} diff --git a/alarm/node_modules/node-forge/flash/SocketEvent.as b/alarm/node_modules/node-forge/flash/SocketEvent.as deleted file mode 100644 index 56f5e7f..0000000 --- a/alarm/node_modules/node-forge/flash/SocketEvent.as +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2009 Digital Bazaar, Inc. All rights reserved. - * - * @author Dave Longley - */ -package -{ - import flash.events.Event; - - /** - * A helper class that contains the ID for a Socket. - */ - public class SocketEvent extends Event - { - // the associated socket - public var socket:PooledSocket; - // an associated message - public var message:String; - - /** - * Creates a new SocketEvent. - * - * @param type the type of event. - * @param socket the associated PooledSocket. - * @param message an associated message. - */ - public function SocketEvent( - type:String, socket:PooledSocket, message:String = null) - { - super(type, false, false); - this.socket = socket; - this.message = message; - } - } -} - diff --git a/alarm/node_modules/node-forge/flash/SocketPool.as b/alarm/node_modules/node-forge/flash/SocketPool.as deleted file mode 100644 index d99b3ec..0000000 --- a/alarm/node_modules/node-forge/flash/SocketPool.as +++ /dev/null @@ -1,754 +0,0 @@ -/* - * Copyright (c) 2009-2010 Digital Bazaar, Inc. All rights reserved. - * - * @author Dave Longley - */ -package -{ - import flash.display.Sprite; - - /** - * A SocketPool is a flash object that can be embedded in a web page to - * allow javascript access to pools of Sockets. - * - * Javascript can create a pool and then as many Sockets as it desires. Each - * Socket will be assigned a unique ID that allows continued javascript - * access to it. There is no limit on the number of persistent socket - * connections. - */ - public class SocketPool extends Sprite - { - import flash.events.Event; - import flash.events.EventDispatcher; - import flash.errors.IOError; - import flash.events.IOErrorEvent; - import flash.events.ProgressEvent; - import flash.events.SecurityErrorEvent; - import flash.events.TextEvent; - import flash.external.ExternalInterface; - import flash.net.SharedObject; - import flash.system.Security; - import flash.utils.ByteArray; - import mx.utils.Base64Decoder; - import mx.utils.Base64Encoder; - - // a map of ID to Socket - private var mSocketMap:Object; - - // a counter for Socket IDs (Note: assumes there will be no overflow) - private var mNextId:uint; - - // an event dispatcher for sending events to javascript - private var mEventDispatcher:EventDispatcher; - - /** - * Creates a new, unitialized SocketPool. - * - * @throws Error - if no external interface is available to provide - * javascript access. - */ - public function SocketPool() - { - if(!ExternalInterface.available) - { - trace("ExternalInterface is not available"); - throw new Error( - "Flash's ExternalInterface is not available. This is a " + - "requirement of SocketPool and therefore, it will be " + - "unavailable."); - } - else - { - try - { - // set up javascript access: - - // initializes/cleans up the SocketPool - ExternalInterface.addCallback("init", init); - ExternalInterface.addCallback("cleanup", cleanup); - - // creates/destroys a socket - ExternalInterface.addCallback("create", create); - ExternalInterface.addCallback("destroy", destroy); - - // connects/closes a socket - ExternalInterface.addCallback("connect", connect); - ExternalInterface.addCallback("close", close); - - // checks for a connection - ExternalInterface.addCallback("isConnected", isConnected); - - // sends/receives data over the socket - ExternalInterface.addCallback("send", send); - ExternalInterface.addCallback("receive", receive); - - // gets the number of bytes available on a socket - ExternalInterface.addCallback( - "getBytesAvailable", getBytesAvailable); - - // add a callback for subscribing to socket events - ExternalInterface.addCallback("subscribe", subscribe); - - // add callbacks for deflate/inflate - ExternalInterface.addCallback("deflate", deflate); - ExternalInterface.addCallback("inflate", inflate); - - // add callbacks for local disk storage - ExternalInterface.addCallback("setItem", setItem); - ExternalInterface.addCallback("getItem", getItem); - ExternalInterface.addCallback("removeItem", removeItem); - ExternalInterface.addCallback("clearItems", clearItems); - - // socket pool is now ready - ExternalInterface.call("window.forge.socketPool.ready"); - } - catch(e:Error) - { - log("error=" + e.errorID + "," + e.name + "," + e.message); - throw e; - } - - log("ready"); - } - } - - /** - * A debug logging function. - * - * @param obj the string or error to log. - */ - CONFIG::debugging - private function log(obj:Object):void - { - if(obj is String) - { - var str:String = obj as String; - ExternalInterface.call("console.log", "SocketPool", str); - } - else if(obj is Error) - { - var e:Error = obj as Error; - log("error=" + e.errorID + "," + e.name + "," + e.message); - } - } - - CONFIG::release - private function log(obj:Object):void - { - // log nothing in release mode - } - - /** - * Called by javascript to initialize this SocketPool. - * - * @param options: - * marshallExceptions: true to pass exceptions to and from - * javascript. - */ - private function init(... args):void - { - log("init()"); - - // get options from first argument - var options:Object = args.length > 0 ? args[0] : null; - - // create socket map, set next ID, and create event dispatcher - mSocketMap = new Object(); - mNextId = 1; - mEventDispatcher = new EventDispatcher(); - - // enable marshalling exceptions if appropriate - if(options != null && - "marshallExceptions" in options && - options.marshallExceptions === true) - { - try - { - // Note: setting marshallExceptions in IE, even inside of a - // try-catch block will terminate flash. Don't set this on IE. - ExternalInterface.marshallExceptions = true; - } - catch(e:Error) - { - log(e); - } - } - - log("init() done"); - } - - /** - * Called by javascript to clean up a SocketPool. - */ - private function cleanup():void - { - log("cleanup()"); - - mSocketMap = null; - mNextId = 1; - mEventDispatcher = null; - - log("cleanup() done"); - } - - /** - * Handles events. - * - * @param e the event to handle. - */ - private function handleEvent(e:Event):void - { - // dispatch socket event - var message:String = (e is TextEvent) ? (e as TextEvent).text : null; - mEventDispatcher.dispatchEvent( - new SocketEvent(e.type, e.target as PooledSocket, message)); - } - - /** - * Called by javascript to create a Socket. - * - * @return the Socket ID. - */ - private function create():String - { - log("create()"); - - // create a Socket - var id:String = "" + mNextId++; - var s:PooledSocket = new PooledSocket(); - s.id = id; - s.addEventListener(Event.CONNECT, handleEvent); - s.addEventListener(Event.CLOSE, handleEvent); - s.addEventListener(ProgressEvent.SOCKET_DATA, handleEvent); - s.addEventListener(IOErrorEvent.IO_ERROR, handleEvent); - s.addEventListener(SecurityErrorEvent.SECURITY_ERROR, handleEvent); - mSocketMap[id] = s; - - log("socket " + id + " created"); - log("create() done"); - - return id; - } - - /** - * Called by javascript to clean up a Socket. - * - * @param id the ID of the Socket to clean up. - */ - private function destroy(id:String):void - { - log("destroy(" + id + ")"); - - if(id in mSocketMap) - { - // remove Socket - delete mSocketMap[id]; - log("socket " + id + " destroyed"); - } - - log("destroy(" + id + ") done"); - } - - /** - * Connects the Socket with the given ID to the given host and port, - * using the given socket policy port. - * - * @param id the ID of the Socket. - * @param host the host to connect to. - * @param port the port to connect to. - * @param spPort the security policy port to use, 0 to use a url. - * @param spUrl the http URL to the policy file to use, null for default. - */ - private function connect( - id:String, host:String, port:uint, spPort:uint, - spUrl:String = null):void - { - log("connect(" + - id + "," + host + "," + port + "," + spPort + "," + spUrl + ")"); - - if(id in mSocketMap) - { - // get the Socket - var s:PooledSocket = mSocketMap[id]; - - // load socket policy file - // (permits socket access to backend) - if(spPort !== 0) - { - spUrl = "xmlsocket://" + host + ":" + spPort; - log("using cross-domain url: " + spUrl); - Security.loadPolicyFile(spUrl); - } - else if(spUrl !== null && typeof(spUrl) !== undefined) - { - log("using cross-domain url: " + spUrl); - Security.loadPolicyFile(spUrl); - } - else - { - log("not loading any cross-domain url"); - } - - // connect - s.connect(host, port); - } - else - { - // no such socket - log("socket " + id + " does not exist"); - } - - log("connect(" + id + ") done"); - } - - /** - * Closes the Socket with the given ID. - * - * @param id the ID of the Socket. - */ - private function close(id:String):void - { - log("close(" + id + ")"); - - if(id in mSocketMap) - { - // close the Socket - var s:PooledSocket = mSocketMap[id]; - if(s.connected) - { - s.close(); - } - } - else - { - // no such socket - log("socket " + id + " does not exist"); - } - - log("close(" + id + ") done"); - } - - /** - * Determines if the Socket with the given ID is connected or not. - * - * @param id the ID of the Socket. - * - * @return true if the socket is connected, false if not. - */ - private function isConnected(id:String):Boolean - { - var rval:Boolean = false; - log("isConnected(" + id + ")"); - - if(id in mSocketMap) - { - // check the Socket - var s:PooledSocket = mSocketMap[id]; - rval = s.connected; - } - else - { - // no such socket - log("socket " + id + " does not exist"); - } - - log("isConnected(" + id + ") done"); - return rval; - } - - /** - * Writes bytes to a Socket. - * - * @param id the ID of the Socket. - * @param bytes the string of base64-encoded bytes to write. - * - * @return true on success, false on failure. - */ - private function send(id:String, bytes:String):Boolean - { - var rval:Boolean = false; - log("send(" + id + ")"); - - if(id in mSocketMap) - { - // write bytes to socket - var s:PooledSocket = mSocketMap[id]; - try - { - var b64:Base64Decoder = new Base64Decoder(); - b64.decode(bytes); - var b:ByteArray = b64.toByteArray(); - s.writeBytes(b, 0, b.length); - s.flush(); - rval = true; - } - catch(e:IOError) - { - log(e); - - // dispatch IO error event - mEventDispatcher.dispatchEvent(new SocketEvent( - IOErrorEvent.IO_ERROR, s, e.message)); - if(s.connected) - { - s.close(); - } - } - } - else - { - // no such socket - log("socket " + id + " does not exist"); - } - - log("send(" + id + ") done"); - return rval; - } - - /** - * Receives bytes from a Socket. - * - * @param id the ID of the Socket. - * @param count the maximum number of bytes to receive. - * - * @return an object with 'rval' set to the received bytes, - * base64-encoded, or set to null on error. - */ - private function receive(id:String, count:uint):Object - { - var rval:String = null; - log("receive(" + id + "," + count + ")"); - - if(id in mSocketMap) - { - // only read what is available - var s:PooledSocket = mSocketMap[id]; - if(count > s.bytesAvailable) - { - count = s.bytesAvailable; - } - - try - { - // read bytes from socket - var b:ByteArray = new ByteArray(); - s.readBytes(b, 0, count); - b.position = 0; - var b64:Base64Encoder = new Base64Encoder(); - b64.insertNewLines = false; - b64.encodeBytes(b, 0, b.length); - rval = b64.toString(); - } - catch(e:IOError) - { - log(e); - - // dispatch IO error event - mEventDispatcher.dispatchEvent(new SocketEvent( - IOErrorEvent.IO_ERROR, s, e.message)); - if(s.connected) - { - s.close(); - } - } - } - else - { - // no such socket - log("socket " + id + " does not exist"); - } - - log("receive(" + id + "," + count + ") done"); - return {rval: rval}; - } - - /** - * Gets the number of bytes available from a Socket. - * - * @param id the ID of the Socket. - * - * @return the number of available bytes. - */ - private function getBytesAvailable(id:String):uint - { - var rval:uint = 0; - log("getBytesAvailable(" + id + ")"); - - if(id in mSocketMap) - { - var s:PooledSocket = mSocketMap[id]; - rval = s.bytesAvailable; - } - else - { - // no such socket - log("socket " + id + " does not exist"); - } - - log("getBytesAvailable(" + id +") done"); - return rval; - } - - /** - * Registers a javascript function as a callback for an event. - * - * @param eventType the type of event (socket event types). - * @param callback the name of the callback function. - */ - private function subscribe(eventType:String, callback:String):void - { - log("subscribe(" + eventType + "," + callback + ")"); - - switch(eventType) - { - case Event.CONNECT: - case Event.CLOSE: - case IOErrorEvent.IO_ERROR: - case SecurityErrorEvent.SECURITY_ERROR: - case ProgressEvent.SOCKET_DATA: - { - log(eventType + " => " + callback); - mEventDispatcher.addEventListener( - eventType, function(event:SocketEvent):void - { - log("event dispatched: " + eventType); - - // build event for javascript - var e:Object = new Object(); - e.id = event.socket ? event.socket.id : 0; - e.type = eventType; - if(event.socket && event.socket.connected) - { - e.bytesAvailable = event.socket.bytesAvailable; - } - else - { - e.bytesAvailable = 0; - } - if(event.message) - { - e.message = event.message; - } - - // send event to javascript - ExternalInterface.call(callback, e); - }); - break; - } - default: - throw new ArgumentError( - "Could not subscribe to event. " + - "Invalid event type specified: " + eventType); - } - - log("subscribe(" + eventType + "," + callback + ") done"); - } - - /** - * Deflates the given data. - * - * @param data the base64-encoded data to deflate. - * - * @return an object with 'rval' set to deflated data, base64-encoded. - */ - private function deflate(data:String):Object - { - log("deflate"); - - var b64d:Base64Decoder = new Base64Decoder(); - b64d.decode(data); - var b:ByteArray = b64d.toByteArray(); - b.compress(); - b.position = 0; - var b64e:Base64Encoder = new Base64Encoder(); - b64e.insertNewLines = false; - b64e.encodeBytes(b, 0, b.length); - - log("deflate done"); - return {rval: b64e.toString()}; - } - - /** - * Inflates the given data. - * - * @param data the base64-encoded data to inflate. - * - * @return an object with 'rval' set to the inflated data, - * base64-encoded, null on error. - */ - private function inflate(data:String):Object - { - log("inflate"); - var rval:Object = {rval: null}; - - try - { - var b64d:Base64Decoder = new Base64Decoder(); - b64d.decode(data); - var b:ByteArray = b64d.toByteArray(); - b.uncompress(); - b.position = 0; - var b64e:Base64Encoder = new Base64Encoder(); - b64e.insertNewLines = false; - b64e.encodeBytes(b, 0, b.length); - rval.rval = b64e.toString(); - } - catch(e:Error) - { - log(e); - rval.error = { - id: e.errorID, - name: e.name, - message: e.message - }; - } - - log("inflate done"); - return rval; - } - - /** - * Stores an item with a key and arbitrary base64-encoded data on local - * disk. - * - * @param key the key for the item. - * @param data the base64-encoded item data. - * @param storeId the storage ID to use, defaults to "forge.storage". - * - * @return an object with rval set to true on success, false on failure - * with error included. - */ - private function setItem( - key:String, data:String, storeId:String = "forge.storage"):Object - { - var rval:Object = {rval: false}; - try - { - var store:SharedObject = SharedObject.getLocal(storeId); - if(!('keys' in store.data)) - { - store.data.keys = {}; - } - store.data.keys[key] = data; - store.flush(); - rval.rval = true; - } - catch(e:Error) - { - log(e); - rval.error = { - id: e.errorID, - name: e.name, - message: e.message - }; - } - return rval; - } - - /** - * Gets an item from the local disk. - * - * @param key the key for the item. - * @param storeId the storage ID to use, defaults to "forge.storage". - * - * @return an object with rval set to the item data (which may be null), - * check for error object if null. - */ - private function getItem( - key:String, storeId:String = "forge.storage"):Object - { - var rval:Object = {rval: null}; - try - { - var store:SharedObject = SharedObject.getLocal(storeId); - if('keys' in store.data && key in store.data.keys) - { - rval.rval = store.data.keys[key]; - } - } - catch(e:Error) - { - log(e); - rval.error = { - id: e.errorID, - name: e.name, - message: e.message - }; - } - return rval; - } - - /** - * Removes an item from the local disk. - * - * @param key the key for the item. - * @param storeId the storage ID to use, defaults to "forge.storage". - * - * @return an object with rval set to true if removed, false if not. - */ - private function removeItem( - key:String, storeId:String = "forge.storage"):Object - { - var rval:Object = {rval: false}; - try - { - var store:SharedObject = SharedObject.getLocal(storeId); - if('keys' in store.data && key in store.data.keys) - { - delete store.data.keys[key]; - - // clean up storage entirely if empty - var empty:Boolean = true; - for(var prop:String in store.data.keys) - { - empty = false; - break; - } - if(empty) - { - store.clear(); - } - rval.rval = true; - } - } - catch(e:Error) - { - log(e); - rval.error = { - id: e.errorID, - name: e.name, - message: e.message - }; - } - return rval; - } - - /** - * Clears an entire store of all of its items. - * - * @param storeId the storage ID to use, defaults to "forge.storage". - * - * @return an object with rval set to true if cleared, false if not. - */ - private function clearItems(storeId:String = "forge.storage"):Object - { - var rval:Object = {rval: false}; - try - { - var store:SharedObject = SharedObject.getLocal(storeId); - store.clear(); - rval.rval = true; - } - catch(e:Error) - { - log(e); - rval.error = { - id: e.errorID, - name: e.name, - message: e.message - }; - } - return rval; - } - } -} diff --git a/alarm/node_modules/node-forge/js/aes.js b/alarm/node_modules/node-forge/js/aes.js deleted file mode 100644 index d16fc34..0000000 --- a/alarm/node_modules/node-forge/js/aes.js +++ /dev/null @@ -1,1147 +0,0 @@ -/** - * Advanced Encryption Standard (AES) implementation. - * - * This implementation is based on the public domain library 'jscrypto' which - * was written by: - * - * Emily Stark (estark@stanford.edu) - * Mike Hamburg (mhamburg@stanford.edu) - * Dan Boneh (dabo@cs.stanford.edu) - * - * Parts of this code are based on the OpenSSL implementation of AES: - * http://www.openssl.org - * - * @author Dave Longley - * - * Copyright (c) 2010-2014 Digital Bazaar, Inc. - */ -(function() { -/* ########## Begin module implementation ########## */ -function initModule(forge) { - -/* AES API */ -forge.aes = forge.aes || {}; - -/** - * Deprecated. Instead, use: - * - * var cipher = forge.cipher.createCipher('AES-<mode>', key); - * cipher.start({iv: iv}); - * - * Creates an AES cipher object to encrypt data using the given symmetric key. - * The output will be stored in the 'output' member of the returned cipher. - * - * The key and iv may be given as a string of bytes, an array of bytes, - * a byte buffer, or an array of 32-bit words. - * - * @param key the symmetric key to use. - * @param iv the initialization vector to use. - * @param output the buffer to write to, null to create one. - * @param mode the cipher mode to use (default: 'CBC'). - * - * @return the cipher. - */ -forge.aes.startEncrypting = function(key, iv, output, mode) { - var cipher = _createCipher({ - key: key, - output: output, - decrypt: false, - mode: mode - }); - cipher.start(iv); - return cipher; -}; - -/** - * Deprecated. Instead, use: - * - * var cipher = forge.cipher.createCipher('AES-<mode>', key); - * - * Creates an AES cipher object to encrypt data using the given symmetric key. - * - * The key may be given as a string of bytes, an array of bytes, a - * byte buffer, or an array of 32-bit words. - * - * @param key the symmetric key to use. - * @param mode the cipher mode to use (default: 'CBC'). - * - * @return the cipher. - */ -forge.aes.createEncryptionCipher = function(key, mode) { - return _createCipher({ - key: key, - output: null, - decrypt: false, - mode: mode - }); -}; - -/** - * Deprecated. Instead, use: - * - * var decipher = forge.cipher.createDecipher('AES-<mode>', key); - * decipher.start({iv: iv}); - * - * Creates an AES cipher object to decrypt data using the given symmetric key. - * The output will be stored in the 'output' member of the returned cipher. - * - * The key and iv may be given as a string of bytes, an array of bytes, - * a byte buffer, or an array of 32-bit words. - * - * @param key the symmetric key to use. - * @param iv the initialization vector to use. - * @param output the buffer to write to, null to create one. - * @param mode the cipher mode to use (default: 'CBC'). - * - * @return the cipher. - */ -forge.aes.startDecrypting = function(key, iv, output, mode) { - var cipher = _createCipher({ - key: key, - output: output, - decrypt: true, - mode: mode - }); - cipher.start(iv); - return cipher; -}; - -/** - * Deprecated. Instead, use: - * - * var decipher = forge.cipher.createDecipher('AES-<mode>', key); - * - * Creates an AES cipher object to decrypt data using the given symmetric key. - * - * The key may be given as a string of bytes, an array of bytes, a - * byte buffer, or an array of 32-bit words. - * - * @param key the symmetric key to use. - * @param mode the cipher mode to use (default: 'CBC'). - * - * @return the cipher. - */ -forge.aes.createDecryptionCipher = function(key, mode) { - return _createCipher({ - key: key, - output: null, - decrypt: true, - mode: mode - }); -}; - -/** - * Creates a new AES cipher algorithm object. - * - * @param name the name of the algorithm. - * @param mode the mode factory function. - * - * @return the AES algorithm object. - */ -forge.aes.Algorithm = function(name, mode) { - if(!init) { - initialize(); - } - var self = this; - self.name = name; - self.mode = new mode({ - blockSize: 16, - cipher: { - encrypt: function(inBlock, outBlock) { - return _updateBlock(self._w, inBlock, outBlock, false); - }, - decrypt: function(inBlock, outBlock) { - return _updateBlock(self._w, inBlock, outBlock, true); - } - } - }); - self._init = false; -}; - -/** - * Initializes this AES algorithm by expanding its key. - * - * @param options the options to use. - * key the key to use with this algorithm. - * decrypt true if the algorithm should be initialized for decryption, - * false for encryption. - */ -forge.aes.Algorithm.prototype.initialize = function(options) { - if(this._init) { - return; - } - - var key = options.key; - var tmp; - - /* Note: The key may be a string of bytes, an array of bytes, a byte - buffer, or an array of 32-bit integers. If the key is in bytes, then - it must be 16, 24, or 32 bytes in length. If it is in 32-bit - integers, it must be 4, 6, or 8 integers long. */ - - if(typeof key === 'string' && - (key.length === 16 || key.length === 24 || key.length === 32)) { - // convert key string into byte buffer - key = forge.util.createBuffer(key); - } else if(forge.util.isArray(key) && - (key.length === 16 || key.length === 24 || key.length === 32)) { - // convert key integer array into byte buffer - tmp = key; - key = forge.util.createBuffer(); - for(var i = 0; i < tmp.length; ++i) { - key.putByte(tmp[i]); - } - } - - // convert key byte buffer into 32-bit integer array - if(!forge.util.isArray(key)) { - tmp = key; - key = []; - - // key lengths of 16, 24, 32 bytes allowed - var len = tmp.length(); - if(len === 16 || len === 24 || len === 32) { - len = len >>> 2; - for(var i = 0; i < len; ++i) { - key.push(tmp.getInt32()); - } - } - } - - // key must be an array of 32-bit integers by now - if(!forge.util.isArray(key) || - !(key.length === 4 || key.length === 6 || key.length === 8)) { - throw new Error('Invalid key parameter.'); - } - - // encryption operation is always used for these modes - var mode = this.mode.name; - var encryptOp = (['CFB', 'OFB', 'CTR', 'GCM'].indexOf(mode) !== -1); - - // do key expansion - this._w = _expandKey(key, options.decrypt && !encryptOp); - this._init = true; -}; - -/** - * Expands a key. Typically only used for testing. - * - * @param key the symmetric key to expand, as an array of 32-bit words. - * @param decrypt true to expand for decryption, false for encryption. - * - * @return the expanded key. - */ -forge.aes._expandKey = function(key, decrypt) { - if(!init) { - initialize(); - } - return _expandKey(key, decrypt); -}; - -/** - * Updates a single block. Typically only used for testing. - * - * @param w the expanded key to use. - * @param input an array of block-size 32-bit words. - * @param output an array of block-size 32-bit words. - * @param decrypt true to decrypt, false to encrypt. - */ -forge.aes._updateBlock = _updateBlock; - - -/** Register AES algorithms **/ - -registerAlgorithm('AES-ECB', forge.cipher.modes.ecb); -registerAlgorithm('AES-CBC', forge.cipher.modes.cbc); -registerAlgorithm('AES-CFB', forge.cipher.modes.cfb); -registerAlgorithm('AES-OFB', forge.cipher.modes.ofb); -registerAlgorithm('AES-CTR', forge.cipher.modes.ctr); -registerAlgorithm('AES-GCM', forge.cipher.modes.gcm); - -function registerAlgorithm(name, mode) { - var factory = function() { - return new forge.aes.Algorithm(name, mode); - }; - forge.cipher.registerAlgorithm(name, factory); -} - - -/** AES implementation **/ - -var init = false; // not yet initialized -var Nb = 4; // number of words comprising the state (AES = 4) -var sbox; // non-linear substitution table used in key expansion -var isbox; // inversion of sbox -var rcon; // round constant word array -var mix; // mix-columns table -var imix; // inverse mix-columns table - -/** - * Performs initialization, ie: precomputes tables to optimize for speed. - * - * One way to understand how AES works is to imagine that 'addition' and - * 'multiplication' are interfaces that require certain mathematical - * properties to hold true (ie: they are associative) but they might have - * different implementations and produce different kinds of results ... - * provided that their mathematical properties remain true. AES defines - * its own methods of addition and multiplication but keeps some important - * properties the same, ie: associativity and distributivity. The - * explanation below tries to shed some light on how AES defines addition - * and multiplication of bytes and 32-bit words in order to perform its - * encryption and decryption algorithms. - * - * The basics: - * - * The AES algorithm views bytes as binary representations of polynomials - * that have either 1 or 0 as the coefficients. It defines the addition - * or subtraction of two bytes as the XOR operation. It also defines the - * multiplication of two bytes as a finite field referred to as GF(2^8) - * (Note: 'GF' means "Galois Field" which is a field that contains a finite - * number of elements so GF(2^8) has 256 elements). - * - * This means that any two bytes can be represented as binary polynomials; - * when they multiplied together and modularly reduced by an irreducible - * polynomial of the 8th degree, the results are the field GF(2^8). The - * specific irreducible polynomial that AES uses in hexadecimal is 0x11b. - * This multiplication is associative with 0x01 as the identity: - * - * (b * 0x01 = GF(b, 0x01) = b). - * - * The operation GF(b, 0x02) can be performed at the byte level by left - * shifting b once and then XOR'ing it (to perform the modular reduction) - * with 0x11b if b is >= 128. Repeated application of the multiplication - * of 0x02 can be used to implement the multiplication of any two bytes. - * - * For instance, multiplying 0x57 and 0x13, denoted as GF(0x57, 0x13), can - * be performed by factoring 0x13 into 0x01, 0x02, and 0x10. Then these - * factors can each be multiplied by 0x57 and then added together. To do - * the multiplication, values for 0x57 multiplied by each of these 3 factors - * can be precomputed and stored in a table. To add them, the values from - * the table are XOR'd together. - * - * AES also defines addition and multiplication of words, that is 4-byte - * numbers represented as polynomials of 3 degrees where the coefficients - * are the values of the bytes. - * - * The word [a0, a1, a2, a3] is a polynomial a3x^3 + a2x^2 + a1x + a0. - * - * Addition is performed by XOR'ing like powers of x. Multiplication - * is performed in two steps, the first is an algebriac expansion as - * you would do normally (where addition is XOR). But the result is - * a polynomial larger than 3 degrees and thus it cannot fit in a word. So - * next the result is modularly reduced by an AES-specific polynomial of - * degree 4 which will always produce a polynomial of less than 4 degrees - * such that it will fit in a word. In AES, this polynomial is x^4 + 1. - * - * The modular product of two polynomials 'a' and 'b' is thus: - * - * d(x) = d3x^3 + d2x^2 + d1x + d0 - * with - * d0 = GF(a0, b0) ^ GF(a3, b1) ^ GF(a2, b2) ^ GF(a1, b3) - * d1 = GF(a1, b0) ^ GF(a0, b1) ^ GF(a3, b2) ^ GF(a2, b3) - * d2 = GF(a2, b0) ^ GF(a1, b1) ^ GF(a0, b2) ^ GF(a3, b3) - * d3 = GF(a3, b0) ^ GF(a2, b1) ^ GF(a1, b2) ^ GF(a0, b3) - * - * As a matrix: - * - * [d0] = [a0 a3 a2 a1][b0] - * [d1] [a1 a0 a3 a2][b1] - * [d2] [a2 a1 a0 a3][b2] - * [d3] [a3 a2 a1 a0][b3] - * - * Special polynomials defined by AES (0x02 == {02}): - * a(x) = {03}x^3 + {01}x^2 + {01}x + {02} - * a^-1(x) = {0b}x^3 + {0d}x^2 + {09}x + {0e}. - * - * These polynomials are used in the MixColumns() and InverseMixColumns() - * operations, respectively, to cause each element in the state to affect - * the output (referred to as diffusing). - * - * RotWord() uses: a0 = a1 = a2 = {00} and a3 = {01}, which is the - * polynomial x3. - * - * The ShiftRows() method modifies the last 3 rows in the state (where - * the state is 4 words with 4 bytes per word) by shifting bytes cyclically. - * The 1st byte in the second row is moved to the end of the row. The 1st - * and 2nd bytes in the third row are moved to the end of the row. The 1st, - * 2nd, and 3rd bytes are moved in the fourth row. - * - * More details on how AES arithmetic works: - * - * In the polynomial representation of binary numbers, XOR performs addition - * and subtraction and multiplication in GF(2^8) denoted as GF(a, b) - * corresponds with the multiplication of polynomials modulo an irreducible - * polynomial of degree 8. In other words, for AES, GF(a, b) will multiply - * polynomial 'a' with polynomial 'b' and then do a modular reduction by - * an AES-specific irreducible polynomial of degree 8. - * - * A polynomial is irreducible if its only divisors are one and itself. For - * the AES algorithm, this irreducible polynomial is: - * - * m(x) = x^8 + x^4 + x^3 + x + 1, - * - * or {01}{1b} in hexadecimal notation, where each coefficient is a bit: - * 100011011 = 283 = 0x11b. - * - * For example, GF(0x57, 0x83) = 0xc1 because - * - * 0x57 = 87 = 01010111 = x^6 + x^4 + x^2 + x + 1 - * 0x85 = 131 = 10000101 = x^7 + x + 1 - * - * (x^6 + x^4 + x^2 + x + 1) * (x^7 + x + 1) - * = x^13 + x^11 + x^9 + x^8 + x^7 + - * x^7 + x^5 + x^3 + x^2 + x + - * x^6 + x^4 + x^2 + x + 1 - * = x^13 + x^11 + x^9 + x^8 + x^6 + x^5 + x^4 + x^3 + 1 = y - * y modulo (x^8 + x^4 + x^3 + x + 1) - * = x^7 + x^6 + 1. - * - * The modular reduction by m(x) guarantees the result will be a binary - * polynomial of less than degree 8, so that it can fit in a byte. - * - * The operation to multiply a binary polynomial b with x (the polynomial - * x in binary representation is 00000010) is: - * - * b_7x^8 + b_6x^7 + b_5x^6 + b_4x^5 + b_3x^4 + b_2x^3 + b_1x^2 + b_0x^1 - * - * To get GF(b, x) we must reduce that by m(x). If b_7 is 0 (that is the - * most significant bit is 0 in b) then the result is already reduced. If - * it is 1, then we can reduce it by subtracting m(x) via an XOR. - * - * It follows that multiplication by x (00000010 or 0x02) can be implemented - * by performing a left shift followed by a conditional bitwise XOR with - * 0x1b. This operation on bytes is denoted by xtime(). Multiplication by - * higher powers of x can be implemented by repeated application of xtime(). - * - * By adding intermediate results, multiplication by any constant can be - * implemented. For instance: - * - * GF(0x57, 0x13) = 0xfe because: - * - * xtime(b) = (b & 128) ? (b << 1 ^ 0x11b) : (b << 1) - * - * Note: We XOR with 0x11b instead of 0x1b because in javascript our - * datatype for b can be larger than 1 byte, so a left shift will not - * automatically eliminate bits that overflow a byte ... by XOR'ing the - * overflow bit with 1 (the extra one from 0x11b) we zero it out. - * - * GF(0x57, 0x02) = xtime(0x57) = 0xae - * GF(0x57, 0x04) = xtime(0xae) = 0x47 - * GF(0x57, 0x08) = xtime(0x47) = 0x8e - * GF(0x57, 0x10) = xtime(0x8e) = 0x07 - * - * GF(0x57, 0x13) = GF(0x57, (0x01 ^ 0x02 ^ 0x10)) - * - * And by the distributive property (since XOR is addition and GF() is - * multiplication): - * - * = GF(0x57, 0x01) ^ GF(0x57, 0x02) ^ GF(0x57, 0x10) - * = 0x57 ^ 0xae ^ 0x07 - * = 0xfe. - */ -function initialize() { - init = true; - - /* Populate the Rcon table. These are the values given by - [x^(i-1),{00},{00},{00}] where x^(i-1) are powers of x (and x = 0x02) - in the field of GF(2^8), where i starts at 1. - - rcon[0] = [0x00, 0x00, 0x00, 0x00] - rcon[1] = [0x01, 0x00, 0x00, 0x00] 2^(1-1) = 2^0 = 1 - rcon[2] = [0x02, 0x00, 0x00, 0x00] 2^(2-1) = 2^1 = 2 - ... - rcon[9] = [0x1B, 0x00, 0x00, 0x00] 2^(9-1) = 2^8 = 0x1B - rcon[10] = [0x36, 0x00, 0x00, 0x00] 2^(10-1) = 2^9 = 0x36 - - We only store the first byte because it is the only one used. - */ - rcon = [0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1B, 0x36]; - - // compute xtime table which maps i onto GF(i, 0x02) - var xtime = new Array(256); - for(var i = 0; i < 128; ++i) { - xtime[i] = i << 1; - xtime[i + 128] = (i + 128) << 1 ^ 0x11B; - } - - // compute all other tables - sbox = new Array(256); - isbox = new Array(256); - mix = new Array(4); - imix = new Array(4); - for(var i = 0; i < 4; ++i) { - mix[i] = new Array(256); - imix[i] = new Array(256); - } - var e = 0, ei = 0, e2, e4, e8, sx, sx2, me, ime; - for(var i = 0; i < 256; ++i) { - /* We need to generate the SubBytes() sbox and isbox tables so that - we can perform byte substitutions. This requires us to traverse - all of the elements in GF, find their multiplicative inverses, - and apply to each the following affine transformation: - - bi' = bi ^ b(i + 4) mod 8 ^ b(i + 5) mod 8 ^ b(i + 6) mod 8 ^ - b(i + 7) mod 8 ^ ci - for 0 <= i < 8, where bi is the ith bit of the byte, and ci is the - ith bit of a byte c with the value {63} or {01100011}. - - It is possible to traverse every possible value in a Galois field - using what is referred to as a 'generator'. There are many - generators (128 out of 256): 3,5,6,9,11,82 to name a few. To fully - traverse GF we iterate 255 times, multiplying by our generator - each time. - - On each iteration we can determine the multiplicative inverse for - the current element. - - Suppose there is an element in GF 'e'. For a given generator 'g', - e = g^x. The multiplicative inverse of e is g^(255 - x). It turns - out that if use the inverse of a generator as another generator - it will produce all of the corresponding multiplicative inverses - at the same time. For this reason, we choose 5 as our inverse - generator because it only requires 2 multiplies and 1 add and its - inverse, 82, requires relatively few operations as well. - - In order to apply the affine transformation, the multiplicative - inverse 'ei' of 'e' can be repeatedly XOR'd (4 times) with a - bit-cycling of 'ei'. To do this 'ei' is first stored in 's' and - 'x'. Then 's' is left shifted and the high bit of 's' is made the - low bit. The resulting value is stored in 's'. Then 'x' is XOR'd - with 's' and stored in 'x'. On each subsequent iteration the same - operation is performed. When 4 iterations are complete, 'x' is - XOR'd with 'c' (0x63) and the transformed value is stored in 'x'. - For example: - - s = 01000001 - x = 01000001 - - iteration 1: s = 10000010, x ^= s - iteration 2: s = 00000101, x ^= s - iteration 3: s = 00001010, x ^= s - iteration 4: s = 00010100, x ^= s - x ^= 0x63 - - This can be done with a loop where s = (s << 1) | (s >> 7). However, - it can also be done by using a single 16-bit (in this case 32-bit) - number 'sx'. Since XOR is an associative operation, we can set 'sx' - to 'ei' and then XOR it with 'sx' left-shifted 1,2,3, and 4 times. - The most significant bits will flow into the high 8 bit positions - and be correctly XOR'd with one another. All that remains will be - to cycle the high 8 bits by XOR'ing them all with the lower 8 bits - afterwards. - - At the same time we're populating sbox and isbox we can precompute - the multiplication we'll need to do to do MixColumns() later. - */ - - // apply affine transformation - sx = ei ^ (ei << 1) ^ (ei << 2) ^ (ei << 3) ^ (ei << 4); - sx = (sx >> 8) ^ (sx & 255) ^ 0x63; - - // update tables - sbox[e] = sx; - isbox[sx] = e; - - /* Mixing columns is done using matrix multiplication. The columns - that are to be mixed are each a single word in the current state. - The state has Nb columns (4 columns). Therefore each column is a - 4 byte word. So to mix the columns in a single column 'c' where - its rows are r0, r1, r2, and r3, we use the following matrix - multiplication: - - [2 3 1 1]*[r0,c]=[r'0,c] - [1 2 3 1] [r1,c] [r'1,c] - [1 1 2 3] [r2,c] [r'2,c] - [3 1 1 2] [r3,c] [r'3,c] - - r0, r1, r2, and r3 are each 1 byte of one of the words in the - state (a column). To do matrix multiplication for each mixed - column c' we multiply the corresponding row from the left matrix - with the corresponding column from the right matrix. In total, we - get 4 equations: - - r0,c' = 2*r0,c + 3*r1,c + 1*r2,c + 1*r3,c - r1,c' = 1*r0,c + 2*r1,c + 3*r2,c + 1*r3,c - r2,c' = 1*r0,c + 1*r1,c + 2*r2,c + 3*r3,c - r3,c' = 3*r0,c + 1*r1,c + 1*r2,c + 2*r3,c - - As usual, the multiplication is as previously defined and the - addition is XOR. In order to optimize mixing columns we can store - the multiplication results in tables. If you think of the whole - column as a word (it might help to visualize by mentally rotating - the equations above by counterclockwise 90 degrees) then you can - see that it would be useful to map the multiplications performed on - each byte (r0, r1, r2, r3) onto a word as well. For instance, we - could map 2*r0,1*r0,1*r0,3*r0 onto a word by storing 2*r0 in the - highest 8 bits and 3*r0 in the lowest 8 bits (with the other two - respectively in the middle). This means that a table can be - constructed that uses r0 as an index to the word. We can do the - same with r1, r2, and r3, creating a total of 4 tables. - - To construct a full c', we can just look up each byte of c in - their respective tables and XOR the results together. - - Also, to build each table we only have to calculate the word - for 2,1,1,3 for every byte ... which we can do on each iteration - of this loop since we will iterate over every byte. After we have - calculated 2,1,1,3 we can get the results for the other tables - by cycling the byte at the end to the beginning. For instance - we can take the result of table 2,1,1,3 and produce table 3,2,1,1 - by moving the right most byte to the left most position just like - how you can imagine the 3 moved out of 2,1,1,3 and to the front - to produce 3,2,1,1. - - There is another optimization in that the same multiples of - the current element we need in order to advance our generator - to the next iteration can be reused in performing the 2,1,1,3 - calculation. We also calculate the inverse mix column tables, - with e,9,d,b being the inverse of 2,1,1,3. - - When we're done, and we need to actually mix columns, the first - byte of each state word should be put through mix[0] (2,1,1,3), - the second through mix[1] (3,2,1,1) and so forth. Then they should - be XOR'd together to produce the fully mixed column. - */ - - // calculate mix and imix table values - sx2 = xtime[sx]; - e2 = xtime[e]; - e4 = xtime[e2]; - e8 = xtime[e4]; - me = - (sx2 << 24) ^ // 2 - (sx << 16) ^ // 1 - (sx << 8) ^ // 1 - (sx ^ sx2); // 3 - ime = - (e2 ^ e4 ^ e8) << 24 ^ // E (14) - (e ^ e8) << 16 ^ // 9 - (e ^ e4 ^ e8) << 8 ^ // D (13) - (e ^ e2 ^ e8); // B (11) - // produce each of the mix tables by rotating the 2,1,1,3 value - for(var n = 0; n < 4; ++n) { - mix[n][e] = me; - imix[n][sx] = ime; - // cycle the right most byte to the left most position - // ie: 2,1,1,3 becomes 3,2,1,1 - me = me << 24 | me >>> 8; - ime = ime << 24 | ime >>> 8; - } - - // get next element and inverse - if(e === 0) { - // 1 is the inverse of 1 - e = ei = 1; - } else { - // e = 2e + 2*2*2*(10e)) = multiply e by 82 (chosen generator) - // ei = ei + 2*2*ei = multiply ei by 5 (inverse generator) - e = e2 ^ xtime[xtime[xtime[e2 ^ e8]]]; - ei ^= xtime[xtime[ei]]; - } - } -} - -/** - * Generates a key schedule using the AES key expansion algorithm. - * - * The AES algorithm takes the Cipher Key, K, and performs a Key Expansion - * routine to generate a key schedule. The Key Expansion generates a total - * of Nb*(Nr + 1) words: the algorithm requires an initial set of Nb words, - * and each of the Nr rounds requires Nb words of key data. The resulting - * key schedule consists of a linear array of 4-byte words, denoted [wi ], - * with i in the range 0 ≤ i < Nb(Nr + 1). - * - * KeyExpansion(byte key[4*Nk], word w[Nb*(Nr+1)], Nk) - * AES-128 (Nb=4, Nk=4, Nr=10) - * AES-192 (Nb=4, Nk=6, Nr=12) - * AES-256 (Nb=4, Nk=8, Nr=14) - * Note: Nr=Nk+6. - * - * Nb is the number of columns (32-bit words) comprising the State (or - * number of bytes in a block). For AES, Nb=4. - * - * @param key the key to schedule (as an array of 32-bit words). - * @param decrypt true to modify the key schedule to decrypt, false not to. - * - * @return the generated key schedule. - */ -function _expandKey(key, decrypt) { - // copy the key's words to initialize the key schedule - var w = key.slice(0); - - /* RotWord() will rotate a word, moving the first byte to the last - byte's position (shifting the other bytes left). - - We will be getting the value of Rcon at i / Nk. 'i' will iterate - from Nk to (Nb * Nr+1). Nk = 4 (4 byte key), Nb = 4 (4 words in - a block), Nr = Nk + 6 (10). Therefore 'i' will iterate from - 4 to 44 (exclusive). Each time we iterate 4 times, i / Nk will - increase by 1. We use a counter iNk to keep track of this. - */ - - // go through the rounds expanding the key - var temp, iNk = 1; - var Nk = w.length; - var Nr1 = Nk + 6 + 1; - var end = Nb * Nr1; - for(var i = Nk; i < end; ++i) { - temp = w[i - 1]; - if(i % Nk === 0) { - // temp = SubWord(RotWord(temp)) ^ Rcon[i / Nk] - temp = - sbox[temp >>> 16 & 255] << 24 ^ - sbox[temp >>> 8 & 255] << 16 ^ - sbox[temp & 255] << 8 ^ - sbox[temp >>> 24] ^ (rcon[iNk] << 24); - iNk++; - } else if(Nk > 6 && (i % Nk === 4)) { - // temp = SubWord(temp) - temp = - sbox[temp >>> 24] << 24 ^ - sbox[temp >>> 16 & 255] << 16 ^ - sbox[temp >>> 8 & 255] << 8 ^ - sbox[temp & 255]; - } - w[i] = w[i - Nk] ^ temp; - } - - /* When we are updating a cipher block we always use the code path for - encryption whether we are decrypting or not (to shorten code and - simplify the generation of look up tables). However, because there - are differences in the decryption algorithm, other than just swapping - in different look up tables, we must transform our key schedule to - account for these changes: - - 1. The decryption algorithm gets its key rounds in reverse order. - 2. The decryption algorithm adds the round key before mixing columns - instead of afterwards. - - We don't need to modify our key schedule to handle the first case, - we can just traverse the key schedule in reverse order when decrypting. - - The second case requires a little work. - - The tables we built for performing rounds will take an input and then - perform SubBytes() and MixColumns() or, for the decrypt version, - InvSubBytes() and InvMixColumns(). But the decrypt algorithm requires - us to AddRoundKey() before InvMixColumns(). This means we'll need to - apply some transformations to the round key to inverse-mix its columns - so they'll be correct for moving AddRoundKey() to after the state has - had its columns inverse-mixed. - - To inverse-mix the columns of the state when we're decrypting we use a - lookup table that will apply InvSubBytes() and InvMixColumns() at the - same time. However, the round key's bytes are not inverse-substituted - in the decryption algorithm. To get around this problem, we can first - substitute the bytes in the round key so that when we apply the - transformation via the InvSubBytes()+InvMixColumns() table, it will - undo our substitution leaving us with the original value that we - want -- and then inverse-mix that value. - - This change will correctly alter our key schedule so that we can XOR - each round key with our already transformed decryption state. This - allows us to use the same code path as the encryption algorithm. - - We make one more change to the decryption key. Since the decryption - algorithm runs in reverse from the encryption algorithm, we reverse - the order of the round keys to avoid having to iterate over the key - schedule backwards when running the encryption algorithm later in - decryption mode. In addition to reversing the order of the round keys, - we also swap each round key's 2nd and 4th rows. See the comments - section where rounds are performed for more details about why this is - done. These changes are done inline with the other substitution - described above. - */ - if(decrypt) { - var tmp; - var m0 = imix[0]; - var m1 = imix[1]; - var m2 = imix[2]; - var m3 = imix[3]; - var wnew = w.slice(0); - end = w.length; - for(var i = 0, wi = end - Nb; i < end; i += Nb, wi -= Nb) { - // do not sub the first or last round key (round keys are Nb - // words) as no column mixing is performed before they are added, - // but do change the key order - if(i === 0 || i === (end - Nb)) { - wnew[i] = w[wi]; - wnew[i + 1] = w[wi + 3]; - wnew[i + 2] = w[wi + 2]; - wnew[i + 3] = w[wi + 1]; - } else { - // substitute each round key byte because the inverse-mix - // table will inverse-substitute it (effectively cancel the - // substitution because round key bytes aren't sub'd in - // decryption mode) and swap indexes 3 and 1 - for(var n = 0; n < Nb; ++n) { - tmp = w[wi + n]; - wnew[i + (3&-n)] = - m0[sbox[tmp >>> 24]] ^ - m1[sbox[tmp >>> 16 & 255]] ^ - m2[sbox[tmp >>> 8 & 255]] ^ - m3[sbox[tmp & 255]]; - } - } - } - w = wnew; - } - - return w; -} - -/** - * Updates a single block (16 bytes) using AES. The update will either - * encrypt or decrypt the block. - * - * @param w the key schedule. - * @param input the input block (an array of 32-bit words). - * @param output the updated output block. - * @param decrypt true to decrypt the block, false to encrypt it. - */ -function _updateBlock(w, input, output, decrypt) { - /* - Cipher(byte in[4*Nb], byte out[4*Nb], word w[Nb*(Nr+1)]) - begin - byte state[4,Nb] - state = in - AddRoundKey(state, w[0, Nb-1]) - for round = 1 step 1 to Nr–1 - SubBytes(state) - ShiftRows(state) - MixColumns(state) - AddRoundKey(state, w[round*Nb, (round+1)*Nb-1]) - end for - SubBytes(state) - ShiftRows(state) - AddRoundKey(state, w[Nr*Nb, (Nr+1)*Nb-1]) - out = state - end - - InvCipher(byte in[4*Nb], byte out[4*Nb], word w[Nb*(Nr+1)]) - begin - byte state[4,Nb] - state = in - AddRoundKey(state, w[Nr*Nb, (Nr+1)*Nb-1]) - for round = Nr-1 step -1 downto 1 - InvShiftRows(state) - InvSubBytes(state) - AddRoundKey(state, w[round*Nb, (round+1)*Nb-1]) - InvMixColumns(state) - end for - InvShiftRows(state) - InvSubBytes(state) - AddRoundKey(state, w[0, Nb-1]) - out = state - end - */ - - // Encrypt: AddRoundKey(state, w[0, Nb-1]) - // Decrypt: AddRoundKey(state, w[Nr*Nb, (Nr+1)*Nb-1]) - var Nr = w.length / 4 - 1; - var m0, m1, m2, m3, sub; - if(decrypt) { - m0 = imix[0]; - m1 = imix[1]; - m2 = imix[2]; - m3 = imix[3]; - sub = isbox; - } else { - m0 = mix[0]; - m1 = mix[1]; - m2 = mix[2]; - m3 = mix[3]; - sub = sbox; - } - var a, b, c, d, a2, b2, c2; - a = input[0] ^ w[0]; - b = input[decrypt ? 3 : 1] ^ w[1]; - c = input[2] ^ w[2]; - d = input[decrypt ? 1 : 3] ^ w[3]; - var i = 3; - - /* In order to share code we follow the encryption algorithm when both - encrypting and decrypting. To account for the changes required in the - decryption algorithm, we use different lookup tables when decrypting - and use a modified key schedule to account for the difference in the - order of transformations applied when performing rounds. We also get - key rounds in reverse order (relative to encryption). */ - for(var round = 1; round < Nr; ++round) { - /* As described above, we'll be using table lookups to perform the - column mixing. Each column is stored as a word in the state (the - array 'input' has one column as a word at each index). In order to - mix a column, we perform these transformations on each row in c, - which is 1 byte in each word. The new column for c0 is c'0: - - m0 m1 m2 m3 - r0,c'0 = 2*r0,c0 + 3*r1,c0 + 1*r2,c0 + 1*r3,c0 - r1,c'0 = 1*r0,c0 + 2*r1,c0 + 3*r2,c0 + 1*r3,c0 - r2,c'0 = 1*r0,c0 + 1*r1,c0 + 2*r2,c0 + 3*r3,c0 - r3,c'0 = 3*r0,c0 + 1*r1,c0 + 1*r2,c0 + 2*r3,c0 - - So using mix tables where c0 is a word with r0 being its upper - 8 bits and r3 being its lower 8 bits: - - m0[c0 >> 24] will yield this word: [2*r0,1*r0,1*r0,3*r0] - ... - m3[c0 & 255] will yield this word: [1*r3,1*r3,3*r3,2*r3] - - Therefore to mix the columns in each word in the state we - do the following (& 255 omitted for brevity): - c'0,r0 = m0[c0 >> 24] ^ m1[c1 >> 16] ^ m2[c2 >> 8] ^ m3[c3] - c'0,r1 = m0[c0 >> 24] ^ m1[c1 >> 16] ^ m2[c2 >> 8] ^ m3[c3] - c'0,r2 = m0[c0 >> 24] ^ m1[c1 >> 16] ^ m2[c2 >> 8] ^ m3[c3] - c'0,r3 = m0[c0 >> 24] ^ m1[c1 >> 16] ^ m2[c2 >> 8] ^ m3[c3] - - However, before mixing, the algorithm requires us to perform - ShiftRows(). The ShiftRows() transformation cyclically shifts the - last 3 rows of the state over different offsets. The first row - (r = 0) is not shifted. - - s'_r,c = s_r,(c + shift(r, Nb) mod Nb - for 0 < r < 4 and 0 <= c < Nb and - shift(1, 4) = 1 - shift(2, 4) = 2 - shift(3, 4) = 3. - - This causes the first byte in r = 1 to be moved to the end of - the row, the first 2 bytes in r = 2 to be moved to the end of - the row, the first 3 bytes in r = 3 to be moved to the end of - the row: - - r1: [c0 c1 c2 c3] => [c1 c2 c3 c0] - r2: [c0 c1 c2 c3] [c2 c3 c0 c1] - r3: [c0 c1 c2 c3] [c3 c0 c1 c2] - - We can make these substitutions inline with our column mixing to - generate an updated set of equations to produce each word in the - state (note the columns have changed positions): - - c0 c1 c2 c3 => c0 c1 c2 c3 - c0 c1 c2 c3 c1 c2 c3 c0 (cycled 1 byte) - c0 c1 c2 c3 c2 c3 c0 c1 (cycled 2 bytes) - c0 c1 c2 c3 c3 c0 c1 c2 (cycled 3 bytes) - - Therefore: - - c'0 = 2*r0,c0 + 3*r1,c1 + 1*r2,c2 + 1*r3,c3 - c'0 = 1*r0,c0 + 2*r1,c1 + 3*r2,c2 + 1*r3,c3 - c'0 = 1*r0,c0 + 1*r1,c1 + 2*r2,c2 + 3*r3,c3 - c'0 = 3*r0,c0 + 1*r1,c1 + 1*r2,c2 + 2*r3,c3 - - c'1 = 2*r0,c1 + 3*r1,c2 + 1*r2,c3 + 1*r3,c0 - c'1 = 1*r0,c1 + 2*r1,c2 + 3*r2,c3 + 1*r3,c0 - c'1 = 1*r0,c1 + 1*r1,c2 + 2*r2,c3 + 3*r3,c0 - c'1 = 3*r0,c1 + 1*r1,c2 + 1*r2,c3 + 2*r3,c0 - - ... and so forth for c'2 and c'3. The important distinction is - that the columns are cycling, with c0 being used with the m0 - map when calculating c0, but c1 being used with the m0 map when - calculating c1 ... and so forth. - - When performing the inverse we transform the mirror image and - skip the bottom row, instead of the top one, and move upwards: - - c3 c2 c1 c0 => c0 c3 c2 c1 (cycled 3 bytes) *same as encryption - c3 c2 c1 c0 c1 c0 c3 c2 (cycled 2 bytes) - c3 c2 c1 c0 c2 c1 c0 c3 (cycled 1 byte) *same as encryption - c3 c2 c1 c0 c3 c2 c1 c0 - - If you compare the resulting matrices for ShiftRows()+MixColumns() - and for InvShiftRows()+InvMixColumns() the 2nd and 4th columns are - different (in encrypt mode vs. decrypt mode). So in order to use - the same code to handle both encryption and decryption, we will - need to do some mapping. - - If in encryption mode we let a=c0, b=c1, c=c2, d=c3, and r<N> be - a row number in the state, then the resulting matrix in encryption - mode for applying the above transformations would be: - - r1: a b c d - r2: b c d a - r3: c d a b - r4: d a b c - - If we did the same in decryption mode we would get: - - r1: a d c b - r2: b a d c - r3: c b a d - r4: d c b a - - If instead we swap d and b (set b=c3 and d=c1), then we get: - - r1: a b c d - r2: d a b c - r3: c d a b - r4: b c d a - - Now the 1st and 3rd rows are the same as the encryption matrix. All - we need to do then to make the mapping exactly the same is to swap - the 2nd and 4th rows when in decryption mode. To do this without - having to do it on each iteration, we swapped the 2nd and 4th rows - in the decryption key schedule. We also have to do the swap above - when we first pull in the input and when we set the final output. */ - a2 = - m0[a >>> 24] ^ - m1[b >>> 16 & 255] ^ - m2[c >>> 8 & 255] ^ - m3[d & 255] ^ w[++i]; - b2 = - m0[b >>> 24] ^ - m1[c >>> 16 & 255] ^ - m2[d >>> 8 & 255] ^ - m3[a & 255] ^ w[++i]; - c2 = - m0[c >>> 24] ^ - m1[d >>> 16 & 255] ^ - m2[a >>> 8 & 255] ^ - m3[b & 255] ^ w[++i]; - d = - m0[d >>> 24] ^ - m1[a >>> 16 & 255] ^ - m2[b >>> 8 & 255] ^ - m3[c & 255] ^ w[++i]; - a = a2; - b = b2; - c = c2; - } - - /* - Encrypt: - SubBytes(state) - ShiftRows(state) - AddRoundKey(state, w[Nr*Nb, (Nr+1)*Nb-1]) - - Decrypt: - InvShiftRows(state) - InvSubBytes(state) - AddRoundKey(state, w[0, Nb-1]) - */ - // Note: rows are shifted inline - output[0] = - (sub[a >>> 24] << 24) ^ - (sub[b >>> 16 & 255] << 16) ^ - (sub[c >>> 8 & 255] << 8) ^ - (sub[d & 255]) ^ w[++i]; - output[decrypt ? 3 : 1] = - (sub[b >>> 24] << 24) ^ - (sub[c >>> 16 & 255] << 16) ^ - (sub[d >>> 8 & 255] << 8) ^ - (sub[a & 255]) ^ w[++i]; - output[2] = - (sub[c >>> 24] << 24) ^ - (sub[d >>> 16 & 255] << 16) ^ - (sub[a >>> 8 & 255] << 8) ^ - (sub[b & 255]) ^ w[++i]; - output[decrypt ? 1 : 3] = - (sub[d >>> 24] << 24) ^ - (sub[a >>> 16 & 255] << 16) ^ - (sub[b >>> 8 & 255] << 8) ^ - (sub[c & 255]) ^ w[++i]; -} - -/** - * Deprecated. Instead, use: - * - * forge.cipher.createCipher('AES-<mode>', key); - * forge.cipher.createDecipher('AES-<mode>', key); - * - * Creates a deprecated AES cipher object. This object's mode will default to - * CBC (cipher-block-chaining). - * - * The key and iv may be given as a string of bytes, an array of bytes, a - * byte buffer, or an array of 32-bit words. - * - * @param options the options to use. - * key the symmetric key to use. - * output the buffer to write to. - * decrypt true for decryption, false for encryption. - * mode the cipher mode to use (default: 'CBC'). - * - * @return the cipher. - */ -function _createCipher(options) { - options = options || {}; - var mode = (options.mode || 'CBC').toUpperCase(); - var algorithm = 'AES-' + mode; - - var cipher; - if(options.decrypt) { - cipher = forge.cipher.createDecipher(algorithm, options.key); - } else { - cipher = forge.cipher.createCipher(algorithm, options.key); - } - - // backwards compatible start API - var start = cipher.start; - cipher.start = function(iv, options) { - // backwards compatibility: support second arg as output buffer - var output = null; - if(options instanceof forge.util.ByteBuffer) { - output = options; - options = {}; - } - options = options || {}; - options.output = output; - options.iv = iv; - start.call(cipher, options); - }; - - return cipher; -} - -} // end module implementation - -/* ########## Begin module wrapper ########## */ -var name = 'aes'; -if(typeof define !== 'function') { - // NodeJS -> AMD - if(typeof module === 'object' && module.exports) { - var nodeJS = true; - define = function(ids, factory) { - factory(require, module); - }; - } else { - // <script> - if(typeof forge === 'undefined') { - forge = {}; - } - return initModule(forge); - } -} -// AMD -var deps; -var defineFunc = function(require, module) { - module.exports = function(forge) { - var mods = deps.map(function(dep) { - return require(dep); - }).concat(initModule); - // handle circular dependencies - forge = forge || {}; - forge.defined = forge.defined || {}; - if(forge.defined[name]) { - return forge[name]; - } - forge.defined[name] = true; - for(var i = 0; i < mods.length; ++i) { - mods[i](forge); - } - return forge[name]; - }; -}; -var tmpDefine = define; -define = function(ids, factory) { - deps = (typeof ids === 'string') ? factory.slice(2) : ids.slice(2); - if(nodeJS) { - delete define; - return tmpDefine.apply(null, Array.prototype.slice.call(arguments, 0)); - } - define = tmpDefine; - return define.apply(null, Array.prototype.slice.call(arguments, 0)); -}; -define( - ['require', 'module', './cipher', './cipherModes', './util'], function() { - defineFunc.apply(null, Array.prototype.slice.call(arguments, 0)); -}); -})(); diff --git a/alarm/node_modules/node-forge/js/aesCipherSuites.js b/alarm/node_modules/node-forge/js/aesCipherSuites.js deleted file mode 100644 index 7087ca6..0000000 --- a/alarm/node_modules/node-forge/js/aesCipherSuites.js +++ /dev/null @@ -1,338 +0,0 @@ -/** - * A Javascript implementation of AES Cipher Suites for TLS. - * - * @author Dave Longley - * - * Copyright (c) 2009-2015 Digital Bazaar, Inc. - * - */ -(function() { -/* ########## Begin module implementation ########## */ -function initModule(forge) { - -var tls = forge.tls; - -/** - * Supported cipher suites. - */ -tls.CipherSuites['TLS_RSA_WITH_AES_128_CBC_SHA'] = { - id: [0x00,0x2f], - name: 'TLS_RSA_WITH_AES_128_CBC_SHA', - initSecurityParameters: function(sp) { - sp.bulk_cipher_algorithm = tls.BulkCipherAlgorithm.aes; - sp.cipher_type = tls.CipherType.block; - sp.enc_key_length = 16; - sp.block_length = 16; - sp.fixed_iv_length = 16; - sp.record_iv_length = 16; - sp.mac_algorithm = tls.MACAlgorithm.hmac_sha1; - sp.mac_length = 20; - sp.mac_key_length = 20; - }, - initConnectionState: initConnectionState -}; -tls.CipherSuites['TLS_RSA_WITH_AES_256_CBC_SHA'] = { - id: [0x00,0x35], - name: 'TLS_RSA_WITH_AES_256_CBC_SHA', - initSecurityParameters: function(sp) { - sp.bulk_cipher_algorithm = tls.BulkCipherAlgorithm.aes; - sp.cipher_type = tls.CipherType.block; - sp.enc_key_length = 32; - sp.block_length = 16; - sp.fixed_iv_length = 16; - sp.record_iv_length = 16; - sp.mac_algorithm = tls.MACAlgorithm.hmac_sha1; - sp.mac_length = 20; - sp.mac_key_length = 20; - }, - initConnectionState: initConnectionState -}; - -function initConnectionState(state, c, sp) { - var client = (c.entity === forge.tls.ConnectionEnd.client); - - // cipher setup - state.read.cipherState = { - init: false, - cipher: forge.cipher.createDecipher('AES-CBC', client ? - sp.keys.server_write_key : sp.keys.client_write_key), - iv: client ? sp.keys.server_write_IV : sp.keys.client_write_IV - }; - state.write.cipherState = { - init: false, - cipher: forge.cipher.createCipher('AES-CBC', client ? - sp.keys.client_write_key : sp.keys.server_write_key), - iv: client ? sp.keys.client_write_IV : sp.keys.server_write_IV - }; - state.read.cipherFunction = decrypt_aes_cbc_sha1; - state.write.cipherFunction = encrypt_aes_cbc_sha1; - - // MAC setup - state.read.macLength = state.write.macLength = sp.mac_length; - state.read.macFunction = state.write.macFunction = tls.hmac_sha1; -} - -/** - * Encrypts the TLSCompressed record into a TLSCipherText record using AES - * in CBC mode. - * - * @param record the TLSCompressed record to encrypt. - * @param s the ConnectionState to use. - * - * @return true on success, false on failure. - */ -function encrypt_aes_cbc_sha1(record, s) { - var rval = false; - - // append MAC to fragment, update sequence number - var mac = s.macFunction(s.macKey, s.sequenceNumber, record); - record.fragment.putBytes(mac); - s.updateSequenceNumber(); - - // TLS 1.1+ use an explicit IV every time to protect against CBC attacks - var iv; - if(record.version.minor === tls.Versions.TLS_1_0.minor) { - // use the pre-generated IV when initializing for TLS 1.0, otherwise use - // the residue from the previous encryption - iv = s.cipherState.init ? null : s.cipherState.iv; - } else { - iv = forge.random.getBytesSync(16); - } - - s.cipherState.init = true; - - // start cipher - var cipher = s.cipherState.cipher; - cipher.start({iv: iv}); - - // TLS 1.1+ write IV into output - if(record.version.minor >= tls.Versions.TLS_1_1.minor) { - cipher.output.putBytes(iv); - } - - // do encryption (default padding is appropriate) - cipher.update(record.fragment); - if(cipher.finish(encrypt_aes_cbc_sha1_padding)) { - // set record fragment to encrypted output - record.fragment = cipher.output; - record.length = record.fragment.length(); - rval = true; - } - - return rval; -} - -/** - * Handles padding for aes_cbc_sha1 in encrypt mode. - * - * @param blockSize the block size. - * @param input the input buffer. - * @param decrypt true in decrypt mode, false in encrypt mode. - * - * @return true on success, false on failure. - */ -function encrypt_aes_cbc_sha1_padding(blockSize, input, decrypt) { - /* The encrypted data length (TLSCiphertext.length) is one more than the sum - of SecurityParameters.block_length, TLSCompressed.length, - SecurityParameters.mac_length, and padding_length. - - The padding may be any length up to 255 bytes long, as long as it results in - the TLSCiphertext.length being an integral multiple of the block length. - Lengths longer than necessary might be desirable to frustrate attacks on a - protocol based on analysis of the lengths of exchanged messages. Each uint8 - in the padding data vector must be filled with the padding length value. - - The padding length should be such that the total size of the - GenericBlockCipher structure is a multiple of the cipher's block length. - Legal values range from zero to 255, inclusive. This length specifies the - length of the padding field exclusive of the padding_length field itself. - - This is slightly different from PKCS#7 because the padding value is 1 - less than the actual number of padding bytes if you include the - padding_length uint8 itself as a padding byte. */ - if(!decrypt) { - // get the number of padding bytes required to reach the blockSize and - // subtract 1 for the padding value (to make room for the padding_length - // uint8) - var padding = blockSize - (input.length() % blockSize); - input.fillWithByte(padding - 1, padding); - } - return true; -} - -/** - * Handles padding for aes_cbc_sha1 in decrypt mode. - * - * @param blockSize the block size. - * @param output the output buffer. - * @param decrypt true in decrypt mode, false in encrypt mode. - * - * @return true on success, false on failure. - */ -function decrypt_aes_cbc_sha1_padding(blockSize, output, decrypt) { - var rval = true; - if(decrypt) { - /* The last byte in the output specifies the number of padding bytes not - including itself. Each of the padding bytes has the same value as that - last byte (known as the padding_length). Here we check all padding - bytes to ensure they have the value of padding_length even if one of - them is bad in order to ward-off timing attacks. */ - var len = output.length(); - var paddingLength = output.last(); - for(var i = len - 1 - paddingLength; i < len - 1; ++i) { - rval = rval && (output.at(i) == paddingLength); - } - if(rval) { - // trim off padding bytes and last padding length byte - output.truncate(paddingLength + 1); - } - } - return rval; -} - -/** - * Decrypts a TLSCipherText record into a TLSCompressed record using - * AES in CBC mode. - * - * @param record the TLSCipherText record to decrypt. - * @param s the ConnectionState to use. - * - * @return true on success, false on failure. - */ -var count = 0; -function decrypt_aes_cbc_sha1(record, s) { - var rval = false; - ++count; - - var iv; - if(record.version.minor === tls.Versions.TLS_1_0.minor) { - // use pre-generated IV when initializing for TLS 1.0, otherwise use the - // residue from the previous decryption - iv = s.cipherState.init ? null : s.cipherState.iv; - } else { - // TLS 1.1+ use an explicit IV every time to protect against CBC attacks - // that is appended to the record fragment - iv = record.fragment.getBytes(16); - } - - s.cipherState.init = true; - - // start cipher - var cipher = s.cipherState.cipher; - cipher.start({iv: iv}); - - // do decryption - cipher.update(record.fragment); - rval = cipher.finish(decrypt_aes_cbc_sha1_padding); - - // even if decryption fails, keep going to minimize timing attacks - - // decrypted data: - // first (len - 20) bytes = application data - // last 20 bytes = MAC - var macLen = s.macLength; - - // create a random MAC to check against should the mac length check fail - // Note: do this regardless of the failure to keep timing consistent - var mac = forge.random.getBytesSync(macLen); - - // get fragment and mac - var len = cipher.output.length(); - if(len >= macLen) { - record.fragment = cipher.output.getBytes(len - macLen); - mac = cipher.output.getBytes(macLen); - } else { - // bad data, but get bytes anyway to try to keep timing consistent - record.fragment = cipher.output.getBytes(); - } - record.fragment = forge.util.createBuffer(record.fragment); - record.length = record.fragment.length(); - - // see if data integrity checks out, update sequence number - var mac2 = s.macFunction(s.macKey, s.sequenceNumber, record); - s.updateSequenceNumber(); - rval = compareMacs(s.macKey, mac, mac2) && rval; - return rval; -} - -/** - * Safely compare two MACs. This function will compare two MACs in a way - * that protects against timing attacks. - * - * TODO: Expose elsewhere as a utility API. - * - * See: https://www.nccgroup.trust/us/about-us/newsroom-and-events/blog/2011/february/double-hmac-verification/ - * - * @param key the MAC key to use. - * @param mac1 as a binary-encoded string of bytes. - * @param mac2 as a binary-encoded string of bytes. - * - * @return true if the MACs are the same, false if not. - */ -function compareMacs(key, mac1, mac2) { - var hmac = forge.hmac.create(); - - hmac.start('SHA1', key); - hmac.update(mac1); - mac1 = hmac.digest().getBytes(); - - hmac.start(null, null); - hmac.update(mac2); - mac2 = hmac.digest().getBytes(); - - return mac1 === mac2; -} - -} // end module implementation - -/* ########## Begin module wrapper ########## */ -var name = 'aesCipherSuites'; -if(typeof define !== 'function') { - // NodeJS -> AMD - if(typeof module === 'object' && module.exports) { - var nodeJS = true; - define = function(ids, factory) { - factory(require, module); - }; - } else { - // <script> - if(typeof forge === 'undefined') { - forge = {}; - } - return initModule(forge); - } -} -// AMD -var deps; -var defineFunc = function(require, module) { - module.exports = function(forge) { - var mods = deps.map(function(dep) { - return require(dep); - }).concat(initModule); - // handle circular dependencies - forge = forge || {}; - forge.defined = forge.defined || {}; - if(forge.defined[name]) { - return forge[name]; - } - forge.defined[name] = true; - for(var i = 0; i < mods.length; ++i) { - mods[i](forge); - } - return forge[name]; - }; -}; -var tmpDefine = define; -define = function(ids, factory) { - deps = (typeof ids === 'string') ? factory.slice(2) : ids.slice(2); - if(nodeJS) { - delete define; - return tmpDefine.apply(null, Array.prototype.slice.call(arguments, 0)); - } - define = tmpDefine; - return define.apply(null, Array.prototype.slice.call(arguments, 0)); -}; -define(['require', 'module', './aes', './tls'], function() { - defineFunc.apply(null, Array.prototype.slice.call(arguments, 0)); -}); -})(); diff --git a/alarm/node_modules/node-forge/js/asn1.js b/alarm/node_modules/node-forge/js/asn1.js deleted file mode 100644 index 9ac7df4..0000000 --- a/alarm/node_modules/node-forge/js/asn1.js +++ /dev/null @@ -1,1114 +0,0 @@ -/** - * Javascript implementation of Abstract Syntax Notation Number One. - * - * @author Dave Longley - * - * Copyright (c) 2010-2014 Digital Bazaar, Inc. - * - * An API for storing data using the Abstract Syntax Notation Number One - * format using DER (Distinguished Encoding Rules) encoding. This encoding is - * commonly used to store data for PKI, i.e. X.509 Certificates, and this - * implementation exists for that purpose. - * - * Abstract Syntax Notation Number One (ASN.1) is used to define the abstract - * syntax of information without restricting the way the information is encoded - * for transmission. It provides a standard that allows for open systems - * communication. ASN.1 defines the syntax of information data and a number of - * simple data types as well as a notation for describing them and specifying - * values for them. - * - * The RSA algorithm creates public and private keys that are often stored in - * X.509 or PKCS#X formats -- which use ASN.1 (encoded in DER format). This - * class provides the most basic functionality required to store and load DSA - * keys that are encoded according to ASN.1. - * - * The most common binary encodings for ASN.1 are BER (Basic Encoding Rules) - * and DER (Distinguished Encoding Rules). DER is just a subset of BER that - * has stricter requirements for how data must be encoded. - * - * Each ASN.1 structure has a tag (a byte identifying the ASN.1 structure type) - * and a byte array for the value of this ASN1 structure which may be data or a - * list of ASN.1 structures. - * - * Each ASN.1 structure using BER is (Tag-Length-Value): - * - * | byte 0 | bytes X | bytes Y | - * |--------|---------|---------- - * | tag | length | value | - * - * ASN.1 allows for tags to be of "High-tag-number form" which allows a tag to - * be two or more octets, but that is not supported by this class. A tag is - * only 1 byte. Bits 1-5 give the tag number (ie the data type within a - * particular 'class'), 6 indicates whether or not the ASN.1 value is - * constructed from other ASN.1 values, and bits 7 and 8 give the 'class'. If - * bits 7 and 8 are both zero, the class is UNIVERSAL. If only bit 7 is set, - * then the class is APPLICATION. If only bit 8 is set, then the class is - * CONTEXT_SPECIFIC. If both bits 7 and 8 are set, then the class is PRIVATE. - * The tag numbers for the data types for the class UNIVERSAL are listed below: - * - * UNIVERSAL 0 Reserved for use by the encoding rules - * UNIVERSAL 1 Boolean type - * UNIVERSAL 2 Integer type - * UNIVERSAL 3 Bitstring type - * UNIVERSAL 4 Octetstring type - * UNIVERSAL 5 Null type - * UNIVERSAL 6 Object identifier type - * UNIVERSAL 7 Object descriptor type - * UNIVERSAL 8 External type and Instance-of type - * UNIVERSAL 9 Real type - * UNIVERSAL 10 Enumerated type - * UNIVERSAL 11 Embedded-pdv type - * UNIVERSAL 12 UTF8String type - * UNIVERSAL 13 Relative object identifier type - * UNIVERSAL 14-15 Reserved for future editions - * UNIVERSAL 16 Sequence and Sequence-of types - * UNIVERSAL 17 Set and Set-of types - * UNIVERSAL 18-22, 25-30 Character string types - * UNIVERSAL 23-24 Time types - * - * The length of an ASN.1 structure is specified after the tag identifier. - * There is a definite form and an indefinite form. The indefinite form may - * be used if the encoding is constructed and not all immediately available. - * The indefinite form is encoded using a length byte with only the 8th bit - * set. The end of the constructed object is marked using end-of-contents - * octets (two zero bytes). - * - * The definite form looks like this: - * - * The length may take up 1 or more bytes, it depends on the length of the - * value of the ASN.1 structure. DER encoding requires that if the ASN.1 - * structure has a value that has a length greater than 127, more than 1 byte - * will be used to store its length, otherwise just one byte will be used. - * This is strict. - * - * In the case that the length of the ASN.1 value is less than 127, 1 octet - * (byte) is used to store the "short form" length. The 8th bit has a value of - * 0 indicating the length is "short form" and not "long form" and bits 7-1 - * give the length of the data. (The 8th bit is the left-most, most significant - * bit: also known as big endian or network format). - * - * In the case that the length of the ASN.1 value is greater than 127, 2 to - * 127 octets (bytes) are used to store the "long form" length. The first - * byte's 8th bit is set to 1 to indicate the length is "long form." Bits 7-1 - * give the number of additional octets. All following octets are in base 256 - * with the most significant digit first (typical big-endian binary unsigned - * integer storage). So, for instance, if the length of a value was 257, the - * first byte would be set to: - * - * 10000010 = 130 = 0x82. - * - * This indicates there are 2 octets (base 256) for the length. The second and - * third bytes (the octets just mentioned) would store the length in base 256: - * - * octet 2: 00000001 = 1 * 256^1 = 256 - * octet 3: 00000001 = 1 * 256^0 = 1 - * total = 257 - * - * The algorithm for converting a js integer value of 257 to base-256 is: - * - * var value = 257; - * var bytes = []; - * bytes[0] = (value >>> 8) & 0xFF; // most significant byte first - * bytes[1] = value & 0xFF; // least significant byte last - * - * On the ASN.1 UNIVERSAL Object Identifier (OID) type: - * - * An OID can be written like: "value1.value2.value3...valueN" - * - * The DER encoding rules: - * - * The first byte has the value 40 * value1 + value2. - * The following bytes, if any, encode the remaining values. Each value is - * encoded in base 128, most significant digit first (big endian), with as - * few digits as possible, and the most significant bit of each byte set - * to 1 except the last in each value's encoding. For example: Given the - * OID "1.2.840.113549", its DER encoding is (remember each byte except the - * last one in each encoding is OR'd with 0x80): - * - * byte 1: 40 * 1 + 2 = 42 = 0x2A. - * bytes 2-3: 128 * 6 + 72 = 840 = 6 72 = 6 72 = 0x0648 = 0x8648 - * bytes 4-6: 16384 * 6 + 128 * 119 + 13 = 6 119 13 = 0x06770D = 0x86F70D - * - * The final value is: 0x2A864886F70D. - * The full OID (including ASN.1 tag and length of 6 bytes) is: - * 0x06062A864886F70D - */ -(function() { -/* ########## Begin module implementation ########## */ -function initModule(forge) { - -/* ASN.1 API */ -var asn1 = forge.asn1 = forge.asn1 || {}; - -/** - * ASN.1 classes. - */ -asn1.Class = { - UNIVERSAL: 0x00, - APPLICATION: 0x40, - CONTEXT_SPECIFIC: 0x80, - PRIVATE: 0xC0 -}; - -/** - * ASN.1 types. Not all types are supported by this implementation, only - * those necessary to implement a simple PKI are implemented. - */ -asn1.Type = { - NONE: 0, - BOOLEAN: 1, - INTEGER: 2, - BITSTRING: 3, - OCTETSTRING: 4, - NULL: 5, - OID: 6, - ODESC: 7, - EXTERNAL: 8, - REAL: 9, - ENUMERATED: 10, - EMBEDDED: 11, - UTF8: 12, - ROID: 13, - SEQUENCE: 16, - SET: 17, - PRINTABLESTRING: 19, - IA5STRING: 22, - UTCTIME: 23, - GENERALIZEDTIME: 24, - BMPSTRING: 30 -}; - -/** - * Creates a new asn1 object. - * - * @param tagClass the tag class for the object. - * @param type the data type (tag number) for the object. - * @param constructed true if the asn1 object is in constructed form. - * @param value the value for the object, if it is not constructed. - * - * @return the asn1 object. - */ -asn1.create = function(tagClass, type, constructed, value) { - /* An asn1 object has a tagClass, a type, a constructed flag, and a - value. The value's type depends on the constructed flag. If - constructed, it will contain a list of other asn1 objects. If not, - it will contain the ASN.1 value as an array of bytes formatted - according to the ASN.1 data type. */ - - // remove undefined values - if(forge.util.isArray(value)) { - var tmp = []; - for(var i = 0; i < value.length; ++i) { - if(value[i] !== undefined) { - tmp.push(value[i]); - } - } - value = tmp; - } - - return { - tagClass: tagClass, - type: type, - constructed: constructed, - composed: constructed || forge.util.isArray(value), - value: value - }; -}; - -/** - * Gets the length of an ASN.1 value. - * - * In case the length is not specified, undefined is returned. - * - * @param b the ASN.1 byte buffer. - * - * @return the length of the ASN.1 value. - */ -var _getValueLength = function(b) { - var b2 = b.getByte(); - if(b2 === 0x80) { - return undefined; - } - - // see if the length is "short form" or "long form" (bit 8 set) - var length; - var longForm = b2 & 0x80; - if(!longForm) { - // length is just the first byte - length = b2; - } else { - // the number of bytes the length is specified in bits 7 through 1 - // and each length byte is in big-endian base-256 - length = b.getInt((b2 & 0x7F) << 3); - } - return length; -}; - -/** - * Parses an asn1 object from a byte buffer in DER format. - * - * @param bytes the byte buffer to parse from. - * @param strict true to be strict when checking value lengths, false to - * allow truncated values (default: true). - * - * @return the parsed asn1 object. - */ -asn1.fromDer = function(bytes, strict) { - if(strict === undefined) { - strict = true; - } - - // wrap in buffer if needed - if(typeof bytes === 'string') { - bytes = forge.util.createBuffer(bytes); - } - - // minimum length for ASN.1 DER structure is 2 - if(bytes.length() < 2) { - var error = new Error('Too few bytes to parse DER.'); - error.bytes = bytes.length(); - throw error; - } - - // get the first byte - var b1 = bytes.getByte(); - - // get the tag class - var tagClass = (b1 & 0xC0); - - // get the type (bits 1-5) - var type = b1 & 0x1F; - - // get the value length - var length = _getValueLength(bytes); - - // ensure there are enough bytes to get the value - if(bytes.length() < length) { - if(strict) { - var error = new Error('Too few bytes to read ASN.1 value.'); - error.detail = bytes.length() + ' < ' + length; - throw error; - } - // Note: be lenient with truncated values - length = bytes.length(); - } - - // prepare to get value - var value; - - // constructed flag is bit 6 (32 = 0x20) of the first byte - var constructed = ((b1 & 0x20) === 0x20); - - // determine if the value is composed of other ASN.1 objects (if its - // constructed it will be and if its a BITSTRING it may be) - var composed = constructed; - if(!composed && tagClass === asn1.Class.UNIVERSAL && - type === asn1.Type.BITSTRING && length > 1) { - /* The first octet gives the number of bits by which the length of the - bit string is less than the next multiple of eight (this is called - the "number of unused bits"). - - The second and following octets give the value of the bit string - converted to an octet string. */ - // if there are no unused bits, maybe the bitstring holds ASN.1 objs - var read = bytes.read; - var unused = bytes.getByte(); - if(unused === 0) { - // if the first byte indicates UNIVERSAL or CONTEXT_SPECIFIC, - // and the length is valid, assume we've got an ASN.1 object - b1 = bytes.getByte(); - var tc = (b1 & 0xC0); - if(tc === asn1.Class.UNIVERSAL || tc === asn1.Class.CONTEXT_SPECIFIC) { - try { - var len = _getValueLength(bytes); - composed = (len === length - (bytes.read - read)); - if(composed) { - // adjust read/length to account for unused bits byte - ++read; - --length; - } - } catch(ex) {} - } - } - // restore read pointer - bytes.read = read; - } - - if(composed) { - // parse child asn1 objects from the value - value = []; - if(length === undefined) { - // asn1 object of indefinite length, read until end tag - for(;;) { - if(bytes.bytes(2) === String.fromCharCode(0, 0)) { - bytes.getBytes(2); - break; - } - value.push(asn1.fromDer(bytes, strict)); - } - } else { - // parsing asn1 object of definite length - var start = bytes.length(); - while(length > 0) { - value.push(asn1.fromDer(bytes, strict)); - length -= start - bytes.length(); - start = bytes.length(); - } - } - } else { - // asn1 not composed, get raw value - // TODO: do DER to OID conversion and vice-versa in .toDer? - - if(length === undefined) { - if(strict) { - throw new Error('Non-constructed ASN.1 object of indefinite length.'); - } - // be lenient and use remaining bytes - length = bytes.length(); - } - - if(type === asn1.Type.BMPSTRING) { - value = ''; - for(var i = 0; i < length; i += 2) { - value += String.fromCharCode(bytes.getInt16()); - } - } else { - value = bytes.getBytes(length); - } - } - - // create and return asn1 object - return asn1.create(tagClass, type, constructed, value); -}; - -/** - * Converts the given asn1 object to a buffer of bytes in DER format. - * - * @param asn1 the asn1 object to convert to bytes. - * - * @return the buffer of bytes. - */ -asn1.toDer = function(obj) { - var bytes = forge.util.createBuffer(); - - // build the first byte - var b1 = obj.tagClass | obj.type; - - // for storing the ASN.1 value - var value = forge.util.createBuffer(); - - // if composed, use each child asn1 object's DER bytes as value - if(obj.composed) { - // turn on 6th bit (0x20 = 32) to indicate asn1 is constructed - // from other asn1 objects - if(obj.constructed) { - b1 |= 0x20; - } else { - // type is a bit string, add unused bits of 0x00 - value.putByte(0x00); - } - - // add all of the child DER bytes together - for(var i = 0; i < obj.value.length; ++i) { - if(obj.value[i] !== undefined) { - value.putBuffer(asn1.toDer(obj.value[i])); - } - } - } else { - // use asn1.value directly - if(obj.type === asn1.Type.BMPSTRING) { - for(var i = 0; i < obj.value.length; ++i) { - value.putInt16(obj.value.charCodeAt(i)); - } - } else { - value.putBytes(obj.value); - } - } - - // add tag byte - bytes.putByte(b1); - - // use "short form" encoding - if(value.length() <= 127) { - // one byte describes the length - // bit 8 = 0 and bits 7-1 = length - bytes.putByte(value.length() & 0x7F); - } else { - // use "long form" encoding - // 2 to 127 bytes describe the length - // first byte: bit 8 = 1 and bits 7-1 = # of additional bytes - // other bytes: length in base 256, big-endian - var len = value.length(); - var lenBytes = ''; - do { - lenBytes += String.fromCharCode(len & 0xFF); - len = len >>> 8; - } while(len > 0); - - // set first byte to # bytes used to store the length and turn on - // bit 8 to indicate long-form length is used - bytes.putByte(lenBytes.length | 0x80); - - // concatenate length bytes in reverse since they were generated - // little endian and we need big endian - for(var i = lenBytes.length - 1; i >= 0; --i) { - bytes.putByte(lenBytes.charCodeAt(i)); - } - } - - // concatenate value bytes - bytes.putBuffer(value); - return bytes; -}; - -/** - * Converts an OID dot-separated string to a byte buffer. The byte buffer - * contains only the DER-encoded value, not any tag or length bytes. - * - * @param oid the OID dot-separated string. - * - * @return the byte buffer. - */ -asn1.oidToDer = function(oid) { - // split OID into individual values - var values = oid.split('.'); - var bytes = forge.util.createBuffer(); - - // first byte is 40 * value1 + value2 - bytes.putByte(40 * parseInt(values[0], 10) + parseInt(values[1], 10)); - // other bytes are each value in base 128 with 8th bit set except for - // the last byte for each value - var last, valueBytes, value, b; - for(var i = 2; i < values.length; ++i) { - // produce value bytes in reverse because we don't know how many - // bytes it will take to store the value - last = true; - valueBytes = []; - value = parseInt(values[i], 10); - do { - b = value & 0x7F; - value = value >>> 7; - // if value is not last, then turn on 8th bit - if(!last) { - b |= 0x80; - } - valueBytes.push(b); - last = false; - } while(value > 0); - - // add value bytes in reverse (needs to be in big endian) - for(var n = valueBytes.length - 1; n >= 0; --n) { - bytes.putByte(valueBytes[n]); - } - } - - return bytes; -}; - -/** - * Converts a DER-encoded byte buffer to an OID dot-separated string. The - * byte buffer should contain only the DER-encoded value, not any tag or - * length bytes. - * - * @param bytes the byte buffer. - * - * @return the OID dot-separated string. - */ -asn1.derToOid = function(bytes) { - var oid; - - // wrap in buffer if needed - if(typeof bytes === 'string') { - bytes = forge.util.createBuffer(bytes); - } - - // first byte is 40 * value1 + value2 - var b = bytes.getByte(); - oid = Math.floor(b / 40) + '.' + (b % 40); - - // other bytes are each value in base 128 with 8th bit set except for - // the last byte for each value - var value = 0; - while(bytes.length() > 0) { - b = bytes.getByte(); - value = value << 7; - // not the last byte for the value - if(b & 0x80) { - value += b & 0x7F; - } else { - // last byte - oid += '.' + (value + b); - value = 0; - } - } - - return oid; -}; - -/** - * Converts a UTCTime value to a date. - * - * Note: GeneralizedTime has 4 digits for the year and is used for X.509 - * dates passed 2049. Parsing that structure hasn't been implemented yet. - * - * @param utc the UTCTime value to convert. - * - * @return the date. - */ -asn1.utcTimeToDate = function(utc) { - /* The following formats can be used: - - YYMMDDhhmmZ - YYMMDDhhmm+hh'mm' - YYMMDDhhmm-hh'mm' - YYMMDDhhmmssZ - YYMMDDhhmmss+hh'mm' - YYMMDDhhmmss-hh'mm' - - Where: - - YY is the least significant two digits of the year - MM is the month (01 to 12) - DD is the day (01 to 31) - hh is the hour (00 to 23) - mm are the minutes (00 to 59) - ss are the seconds (00 to 59) - Z indicates that local time is GMT, + indicates that local time is - later than GMT, and - indicates that local time is earlier than GMT - hh' is the absolute value of the offset from GMT in hours - mm' is the absolute value of the offset from GMT in minutes */ - var date = new Date(); - - // if YY >= 50 use 19xx, if YY < 50 use 20xx - var year = parseInt(utc.substr(0, 2), 10); - year = (year >= 50) ? 1900 + year : 2000 + year; - var MM = parseInt(utc.substr(2, 2), 10) - 1; // use 0-11 for month - var DD = parseInt(utc.substr(4, 2), 10); - var hh = parseInt(utc.substr(6, 2), 10); - var mm = parseInt(utc.substr(8, 2), 10); - var ss = 0; - - // not just YYMMDDhhmmZ - if(utc.length > 11) { - // get character after minutes - var c = utc.charAt(10); - var end = 10; - - // see if seconds are present - if(c !== '+' && c !== '-') { - // get seconds - ss = parseInt(utc.substr(10, 2), 10); - end += 2; - } - } - - // update date - date.setUTCFullYear(year, MM, DD); - date.setUTCHours(hh, mm, ss, 0); - - if(end) { - // get +/- after end of time - c = utc.charAt(end); - if(c === '+' || c === '-') { - // get hours+minutes offset - var hhoffset = parseInt(utc.substr(end + 1, 2), 10); - var mmoffset = parseInt(utc.substr(end + 4, 2), 10); - - // calculate offset in milliseconds - var offset = hhoffset * 60 + mmoffset; - offset *= 60000; - - // apply offset - if(c === '+') { - date.setTime(+date - offset); - } else { - date.setTime(+date + offset); - } - } - } - - return date; -}; - -/** - * Converts a GeneralizedTime value to a date. - * - * @param gentime the GeneralizedTime value to convert. - * - * @return the date. - */ -asn1.generalizedTimeToDate = function(gentime) { - /* The following formats can be used: - - YYYYMMDDHHMMSS - YYYYMMDDHHMMSS.fff - YYYYMMDDHHMMSSZ - YYYYMMDDHHMMSS.fffZ - YYYYMMDDHHMMSS+hh'mm' - YYYYMMDDHHMMSS.fff+hh'mm' - YYYYMMDDHHMMSS-hh'mm' - YYYYMMDDHHMMSS.fff-hh'mm' - - Where: - - YYYY is the year - MM is the month (01 to 12) - DD is the day (01 to 31) - hh is the hour (00 to 23) - mm are the minutes (00 to 59) - ss are the seconds (00 to 59) - .fff is the second fraction, accurate to three decimal places - Z indicates that local time is GMT, + indicates that local time is - later than GMT, and - indicates that local time is earlier than GMT - hh' is the absolute value of the offset from GMT in hours - mm' is the absolute value of the offset from GMT in minutes */ - var date = new Date(); - - var YYYY = parseInt(gentime.substr(0, 4), 10); - var MM = parseInt(gentime.substr(4, 2), 10) - 1; // use 0-11 for month - var DD = parseInt(gentime.substr(6, 2), 10); - var hh = parseInt(gentime.substr(8, 2), 10); - var mm = parseInt(gentime.substr(10, 2), 10); - var ss = parseInt(gentime.substr(12, 2), 10); - var fff = 0; - var offset = 0; - var isUTC = false; - - if(gentime.charAt(gentime.length - 1) === 'Z') { - isUTC = true; - } - - var end = gentime.length - 5, c = gentime.charAt(end); - if(c === '+' || c === '-') { - // get hours+minutes offset - var hhoffset = parseInt(gentime.substr(end + 1, 2), 10); - var mmoffset = parseInt(gentime.substr(end + 4, 2), 10); - - // calculate offset in milliseconds - offset = hhoffset * 60 + mmoffset; - offset *= 60000; - - // apply offset - if(c === '+') { - offset *= -1; - } - - isUTC = true; - } - - // check for second fraction - if(gentime.charAt(14) === '.') { - fff = parseFloat(gentime.substr(14), 10) * 1000; - } - - if(isUTC) { - date.setUTCFullYear(YYYY, MM, DD); - date.setUTCHours(hh, mm, ss, fff); - - // apply offset - date.setTime(+date + offset); - } else { - date.setFullYear(YYYY, MM, DD); - date.setHours(hh, mm, ss, fff); - } - - return date; -}; - - -/** - * Converts a date to a UTCTime value. - * - * Note: GeneralizedTime has 4 digits for the year and is used for X.509 - * dates passed 2049. Converting to a GeneralizedTime hasn't been - * implemented yet. - * - * @param date the date to convert. - * - * @return the UTCTime value. - */ -asn1.dateToUtcTime = function(date) { - var rval = ''; - - // create format YYMMDDhhmmssZ - var format = []; - format.push(('' + date.getUTCFullYear()).substr(2)); - format.push('' + (date.getUTCMonth() + 1)); - format.push('' + date.getUTCDate()); - format.push('' + date.getUTCHours()); - format.push('' + date.getUTCMinutes()); - format.push('' + date.getUTCSeconds()); - - // ensure 2 digits are used for each format entry - for(var i = 0; i < format.length; ++i) { - if(format[i].length < 2) { - rval += '0'; - } - rval += format[i]; - } - rval += 'Z'; - - return rval; -}; - -/** - * Converts a javascript integer to a DER-encoded byte buffer to be used - * as the value for an INTEGER type. - * - * @param x the integer. - * - * @return the byte buffer. - */ -asn1.integerToDer = function(x) { - var rval = forge.util.createBuffer(); - if(x >= -0x80 && x < 0x80) { - return rval.putSignedInt(x, 8); - } - if(x >= -0x8000 && x < 0x8000) { - return rval.putSignedInt(x, 16); - } - if(x >= -0x800000 && x < 0x800000) { - return rval.putSignedInt(x, 24); - } - if(x >= -0x80000000 && x < 0x80000000) { - return rval.putSignedInt(x, 32); - } - var error = new Error('Integer too large; max is 32-bits.'); - error.integer = x; - throw error; -}; - -/** - * Converts a DER-encoded byte buffer to a javascript integer. This is - * typically used to decode the value of an INTEGER type. - * - * @param bytes the byte buffer. - * - * @return the integer. - */ -asn1.derToInteger = function(bytes) { - // wrap in buffer if needed - if(typeof bytes === 'string') { - bytes = forge.util.createBuffer(bytes); - } - - var n = bytes.length() * 8; - if(n > 32) { - throw new Error('Integer too large; max is 32-bits.'); - } - return bytes.getSignedInt(n); -}; - -/** - * Validates the that given ASN.1 object is at least a super set of the - * given ASN.1 structure. Only tag classes and types are checked. An - * optional map may also be provided to capture ASN.1 values while the - * structure is checked. - * - * To capture an ASN.1 value, set an object in the validator's 'capture' - * parameter to the key to use in the capture map. To capture the full - * ASN.1 object, specify 'captureAsn1'. - * - * Objects in the validator may set a field 'optional' to true to indicate - * that it isn't necessary to pass validation. - * - * @param obj the ASN.1 object to validate. - * @param v the ASN.1 structure validator. - * @param capture an optional map to capture values in. - * @param errors an optional array for storing validation errors. - * - * @return true on success, false on failure. - */ -asn1.validate = function(obj, v, capture, errors) { - var rval = false; - - // ensure tag class and type are the same if specified - if((obj.tagClass === v.tagClass || typeof(v.tagClass) === 'undefined') && - (obj.type === v.type || typeof(v.type) === 'undefined')) { - // ensure constructed flag is the same if specified - if(obj.constructed === v.constructed || - typeof(v.constructed) === 'undefined') { - rval = true; - - // handle sub values - if(v.value && forge.util.isArray(v.value)) { - var j = 0; - for(var i = 0; rval && i < v.value.length; ++i) { - rval = v.value[i].optional || false; - if(obj.value[j]) { - rval = asn1.validate(obj.value[j], v.value[i], capture, errors); - if(rval) { - ++j; - } else if(v.value[i].optional) { - rval = true; - } - } - if(!rval && errors) { - errors.push( - '[' + v.name + '] ' + - 'Tag class "' + v.tagClass + '", type "' + - v.type + '" expected value length "' + - v.value.length + '", got "' + - obj.value.length + '"'); - } - } - } - - if(rval && capture) { - if(v.capture) { - capture[v.capture] = obj.value; - } - if(v.captureAsn1) { - capture[v.captureAsn1] = obj; - } - } - } else if(errors) { - errors.push( - '[' + v.name + '] ' + - 'Expected constructed "' + v.constructed + '", got "' + - obj.constructed + '"'); - } - } else if(errors) { - if(obj.tagClass !== v.tagClass) { - errors.push( - '[' + v.name + '] ' + - 'Expected tag class "' + v.tagClass + '", got "' + - obj.tagClass + '"'); - } - if(obj.type !== v.type) { - errors.push( - '[' + v.name + '] ' + - 'Expected type "' + v.type + '", got "' + obj.type + '"'); - } - } - return rval; -}; - -// regex for testing for non-latin characters -var _nonLatinRegex = /[^\\u0000-\\u00ff]/; - -/** - * Pretty prints an ASN.1 object to a string. - * - * @param obj the object to write out. - * @param level the level in the tree. - * @param indentation the indentation to use. - * - * @return the string. - */ -asn1.prettyPrint = function(obj, level, indentation) { - var rval = ''; - - // set default level and indentation - level = level || 0; - indentation = indentation || 2; - - // start new line for deep levels - if(level > 0) { - rval += '\n'; - } - - // create indent - var indent = ''; - for(var i = 0; i < level * indentation; ++i) { - indent += ' '; - } - - // print class:type - rval += indent + 'Tag: '; - switch(obj.tagClass) { - case asn1.Class.UNIVERSAL: - rval += 'Universal:'; - break; - case asn1.Class.APPLICATION: - rval += 'Application:'; - break; - case asn1.Class.CONTEXT_SPECIFIC: - rval += 'Context-Specific:'; - break; - case asn1.Class.PRIVATE: - rval += 'Private:'; - break; - } - - if(obj.tagClass === asn1.Class.UNIVERSAL) { - rval += obj.type; - - // known types - switch(obj.type) { - case asn1.Type.NONE: - rval += ' (None)'; - break; - case asn1.Type.BOOLEAN: - rval += ' (Boolean)'; - break; - case asn1.Type.BITSTRING: - rval += ' (Bit string)'; - break; - case asn1.Type.INTEGER: - rval += ' (Integer)'; - break; - case asn1.Type.OCTETSTRING: - rval += ' (Octet string)'; - break; - case asn1.Type.NULL: - rval += ' (Null)'; - break; - case asn1.Type.OID: - rval += ' (Object Identifier)'; - break; - case asn1.Type.ODESC: - rval += ' (Object Descriptor)'; - break; - case asn1.Type.EXTERNAL: - rval += ' (External or Instance of)'; - break; - case asn1.Type.REAL: - rval += ' (Real)'; - break; - case asn1.Type.ENUMERATED: - rval += ' (Enumerated)'; - break; - case asn1.Type.EMBEDDED: - rval += ' (Embedded PDV)'; - break; - case asn1.Type.UTF8: - rval += ' (UTF8)'; - break; - case asn1.Type.ROID: - rval += ' (Relative Object Identifier)'; - break; - case asn1.Type.SEQUENCE: - rval += ' (Sequence)'; - break; - case asn1.Type.SET: - rval += ' (Set)'; - break; - case asn1.Type.PRINTABLESTRING: - rval += ' (Printable String)'; - break; - case asn1.Type.IA5String: - rval += ' (IA5String (ASCII))'; - break; - case asn1.Type.UTCTIME: - rval += ' (UTC time)'; - break; - case asn1.Type.GENERALIZEDTIME: - rval += ' (Generalized time)'; - break; - case asn1.Type.BMPSTRING: - rval += ' (BMP String)'; - break; - } - } else { - rval += obj.type; - } - - rval += '\n'; - rval += indent + 'Constructed: ' + obj.constructed + '\n'; - - if(obj.composed) { - var subvalues = 0; - var sub = ''; - for(var i = 0; i < obj.value.length; ++i) { - if(obj.value[i] !== undefined) { - subvalues += 1; - sub += asn1.prettyPrint(obj.value[i], level + 1, indentation); - if((i + 1) < obj.value.length) { - sub += ','; - } - } - } - rval += indent + 'Sub values: ' + subvalues + sub; - } else { - rval += indent + 'Value: '; - if(obj.type === asn1.Type.OID) { - var oid = asn1.derToOid(obj.value); - rval += oid; - if(forge.pki && forge.pki.oids) { - if(oid in forge.pki.oids) { - rval += ' (' + forge.pki.oids[oid] + ') '; - } - } - } - if(obj.type === asn1.Type.INTEGER) { - try { - rval += asn1.derToInteger(obj.value); - } catch(ex) { - rval += '0x' + forge.util.bytesToHex(obj.value); - } - } else if(obj.type === asn1.Type.OCTETSTRING) { - if(!_nonLatinRegex.test(obj.value)) { - rval += '(' + obj.value + ') '; - } - rval += '0x' + forge.util.bytesToHex(obj.value); - } else if(obj.type === asn1.Type.UTF8) { - rval += forge.util.decodeUtf8(obj.value); - } else if(obj.type === asn1.Type.PRINTABLESTRING || - obj.type === asn1.Type.IA5String) { - rval += obj.value; - } else if(_nonLatinRegex.test(obj.value)) { - rval += '0x' + forge.util.bytesToHex(obj.value); - } else if(obj.value.length === 0) { - rval += '[null]'; - } else { - rval += obj.value; - } - } - - return rval; -}; - -} // end module implementation - -/* ########## Begin module wrapper ########## */ -var name = 'asn1'; -if(typeof define !== 'function') { - // NodeJS -> AMD - if(typeof module === 'object' && module.exports) { - var nodeJS = true; - define = function(ids, factory) { - factory(require, module); - }; - } else { - // <script> - if(typeof forge === 'undefined') { - forge = {}; - } - return initModule(forge); - } -} -// AMD -var deps; -var defineFunc = function(require, module) { - module.exports = function(forge) { - var mods = deps.map(function(dep) { - return require(dep); - }).concat(initModule); - // handle circular dependencies - forge = forge || {}; - forge.defined = forge.defined || {}; - if(forge.defined[name]) { - return forge[name]; - } - forge.defined[name] = true; - for(var i = 0; i < mods.length; ++i) { - mods[i](forge); - } - return forge[name]; - }; -}; -var tmpDefine = define; -define = function(ids, factory) { - deps = (typeof ids === 'string') ? factory.slice(2) : ids.slice(2); - if(nodeJS) { - delete define; - return tmpDefine.apply(null, Array.prototype.slice.call(arguments, 0)); - } - define = tmpDefine; - return define.apply(null, Array.prototype.slice.call(arguments, 0)); -}; -define(['require', 'module', './util', './oids'], function() { - defineFunc.apply(null, Array.prototype.slice.call(arguments, 0)); -}); -})(); diff --git a/alarm/node_modules/node-forge/js/cipher.js b/alarm/node_modules/node-forge/js/cipher.js deleted file mode 100644 index ca44246..0000000 --- a/alarm/node_modules/node-forge/js/cipher.js +++ /dev/null @@ -1,286 +0,0 @@ -/** - * Cipher base API. - * - * @author Dave Longley - * - * Copyright (c) 2010-2014 Digital Bazaar, Inc. - */ -(function() { -/* ########## Begin module implementation ########## */ -function initModule(forge) { - -forge.cipher = forge.cipher || {}; - -// registered algorithms -forge.cipher.algorithms = forge.cipher.algorithms || {}; - -/** - * Creates a cipher object that can be used to encrypt data using the given - * algorithm and key. The algorithm may be provided as a string value for a - * previously registered algorithm or it may be given as a cipher algorithm - * API object. - * - * @param algorithm the algorithm to use, either a string or an algorithm API - * object. - * @param key the key to use, as a binary-encoded string of bytes or a - * byte buffer. - * - * @return the cipher. - */ -forge.cipher.createCipher = function(algorithm, key) { - var api = algorithm; - if(typeof api === 'string') { - api = forge.cipher.getAlgorithm(api); - if(api) { - api = api(); - } - } - if(!api) { - throw new Error('Unsupported algorithm: ' + algorithm); - } - - // assume block cipher - return new forge.cipher.BlockCipher({ - algorithm: api, - key: key, - decrypt: false - }); -}; - -/** - * Creates a decipher object that can be used to decrypt data using the given - * algorithm and key. The algorithm may be provided as a string value for a - * previously registered algorithm or it may be given as a cipher algorithm - * API object. - * - * @param algorithm the algorithm to use, either a string or an algorithm API - * object. - * @param key the key to use, as a binary-encoded string of bytes or a - * byte buffer. - * - * @return the cipher. - */ -forge.cipher.createDecipher = function(algorithm, key) { - var api = algorithm; - if(typeof api === 'string') { - api = forge.cipher.getAlgorithm(api); - if(api) { - api = api(); - } - } - if(!api) { - throw new Error('Unsupported algorithm: ' + algorithm); - } - - // assume block cipher - return new forge.cipher.BlockCipher({ - algorithm: api, - key: key, - decrypt: true - }); -}; - -/** - * Registers an algorithm by name. If the name was already registered, the - * algorithm API object will be overwritten. - * - * @param name the name of the algorithm. - * @param algorithm the algorithm API object. - */ -forge.cipher.registerAlgorithm = function(name, algorithm) { - name = name.toUpperCase(); - forge.cipher.algorithms[name] = algorithm; -}; - -/** - * Gets a registered algorithm by name. - * - * @param name the name of the algorithm. - * - * @return the algorithm, if found, null if not. - */ -forge.cipher.getAlgorithm = function(name) { - name = name.toUpperCase(); - if(name in forge.cipher.algorithms) { - return forge.cipher.algorithms[name]; - } - return null; -}; - -var BlockCipher = forge.cipher.BlockCipher = function(options) { - this.algorithm = options.algorithm; - this.mode = this.algorithm.mode; - this.blockSize = this.mode.blockSize; - this._finish = false; - this._input = null; - this.output = null; - this._op = options.decrypt ? this.mode.decrypt : this.mode.encrypt; - this._decrypt = options.decrypt; - this.algorithm.initialize(options); -}; - -/** - * Starts or restarts the encryption or decryption process, whichever - * was previously configured. - * - * For non-GCM mode, the IV may be a binary-encoded string of bytes, an array - * of bytes, a byte buffer, or an array of 32-bit integers. If the IV is in - * bytes, then it must be Nb (16) bytes in length. If the IV is given in as - * 32-bit integers, then it must be 4 integers long. - * - * Note: an IV is not required or used in ECB mode. - * - * For GCM-mode, the IV must be given as a binary-encoded string of bytes or - * a byte buffer. The number of bytes should be 12 (96 bits) as recommended - * by NIST SP-800-38D but another length may be given. - * - * @param options the options to use: - * iv the initialization vector to use as a binary-encoded string of - * bytes, null to reuse the last ciphered block from a previous - * update() (this "residue" method is for legacy support only). - * additionalData additional authentication data as a binary-encoded - * string of bytes, for 'GCM' mode, (default: none). - * tagLength desired length of authentication tag, in bits, for - * 'GCM' mode (0-128, default: 128). - * tag the authentication tag to check if decrypting, as a - * binary-encoded string of bytes. - * output the output the buffer to write to, null to create one. - */ -BlockCipher.prototype.start = function(options) { - options = options || {}; - var opts = {}; - for(var key in options) { - opts[key] = options[key]; - } - opts.decrypt = this._decrypt; - this._finish = false; - this._input = forge.util.createBuffer(); - this.output = options.output || forge.util.createBuffer(); - this.mode.start(opts); -}; - -/** - * Updates the next block according to the cipher mode. - * - * @param input the buffer to read from. - */ -BlockCipher.prototype.update = function(input) { - if(input) { - // input given, so empty it into the input buffer - this._input.putBuffer(input); - } - - // do cipher operation until it needs more input and not finished - while(!this._op.call(this.mode, this._input, this.output, this._finish) && - !this._finish) {} - - // free consumed memory from input buffer - this._input.compact(); -}; - -/** - * Finishes encrypting or decrypting. - * - * @param pad a padding function to use in CBC mode, null for default, - * signature(blockSize, buffer, decrypt). - * - * @return true if successful, false on error. - */ -BlockCipher.prototype.finish = function(pad) { - // backwards-compatibility w/deprecated padding API - // Note: will overwrite padding functions even after another start() call - if(pad && (this.mode.name === 'ECB' || this.mode.name === 'CBC')) { - this.mode.pad = function(input) { - return pad(this.blockSize, input, false); - }; - this.mode.unpad = function(output) { - return pad(this.blockSize, output, true); - }; - } - - // build options for padding and afterFinish functions - var options = {}; - options.decrypt = this._decrypt; - - // get # of bytes that won't fill a block - options.overflow = this._input.length() % this.blockSize; - - if(!this._decrypt && this.mode.pad) { - if(!this.mode.pad(this._input, options)) { - return false; - } - } - - // do final update - this._finish = true; - this.update(); - - if(this._decrypt && this.mode.unpad) { - if(!this.mode.unpad(this.output, options)) { - return false; - } - } - - if(this.mode.afterFinish) { - if(!this.mode.afterFinish(this.output, options)) { - return false; - } - } - - return true; -}; - - -} // end module implementation - -/* ########## Begin module wrapper ########## */ -var name = 'cipher'; -if(typeof define !== 'function') { - // NodeJS -> AMD - if(typeof module === 'object' && module.exports) { - var nodeJS = true; - define = function(ids, factory) { - factory(require, module); - }; - } else { - // <script> - if(typeof forge === 'undefined') { - forge = {}; - } - return initModule(forge); - } -} -// AMD -var deps; -var defineFunc = function(require, module) { - module.exports = function(forge) { - var mods = deps.map(function(dep) { - return require(dep); - }).concat(initModule); - // handle circular dependencies - forge = forge || {}; - forge.defined = forge.defined || {}; - if(forge.defined[name]) { - return forge[name]; - } - forge.defined[name] = true; - for(var i = 0; i < mods.length; ++i) { - mods[i](forge); - } - return forge[name]; - }; -}; -var tmpDefine = define; -define = function(ids, factory) { - deps = (typeof ids === 'string') ? factory.slice(2) : ids.slice(2); - if(nodeJS) { - delete define; - return tmpDefine.apply(null, Array.prototype.slice.call(arguments, 0)); - } - define = tmpDefine; - return define.apply(null, Array.prototype.slice.call(arguments, 0)); -}; -define(['require', 'module', './util'], function() { - defineFunc.apply(null, Array.prototype.slice.call(arguments, 0)); -}); -})(); diff --git a/alarm/node_modules/node-forge/js/cipherModes.js b/alarm/node_modules/node-forge/js/cipherModes.js deleted file mode 100644 index 2d64211..0000000 --- a/alarm/node_modules/node-forge/js/cipherModes.js +++ /dev/null @@ -1,1049 +0,0 @@ -/** - * Supported cipher modes. - * - * @author Dave Longley - * - * Copyright (c) 2010-2014 Digital Bazaar, Inc. - */ -(function() { -/* ########## Begin module implementation ########## */ -function initModule(forge) { - -forge.cipher = forge.cipher || {}; - -// supported cipher modes -var modes = forge.cipher.modes = forge.cipher.modes || {}; - - -/** Electronic codebook (ECB) (Don't use this; it's not secure) **/ - -modes.ecb = function(options) { - options = options || {}; - this.name = 'ECB'; - this.cipher = options.cipher; - this.blockSize = options.blockSize || 16; - this._ints = this.blockSize / 4; - this._inBlock = new Array(this._ints); - this._outBlock = new Array(this._ints); -}; - -modes.ecb.prototype.start = function(options) {}; - -modes.ecb.prototype.encrypt = function(input, output, finish) { - // not enough input to encrypt - if(input.length() < this.blockSize && !(finish && input.length() > 0)) { - return true; - } - - // get next block - for(var i = 0; i < this._ints; ++i) { - this._inBlock[i] = input.getInt32(); - } - - // encrypt block - this.cipher.encrypt(this._inBlock, this._outBlock); - - // write output - for(var i = 0; i < this._ints; ++i) { - output.putInt32(this._outBlock[i]); - } -}; - -modes.ecb.prototype.decrypt = function(input, output, finish) { - // not enough input to decrypt - if(input.length() < this.blockSize && !(finish && input.length() > 0)) { - return true; - } - - // get next block - for(var i = 0; i < this._ints; ++i) { - this._inBlock[i] = input.getInt32(); - } - - // decrypt block - this.cipher.decrypt(this._inBlock, this._outBlock); - - // write output - for(var i = 0; i < this._ints; ++i) { - output.putInt32(this._outBlock[i]); - } -}; - -modes.ecb.prototype.pad = function(input, options) { - // add PKCS#7 padding to block (each pad byte is the - // value of the number of pad bytes) - var padding = (input.length() === this.blockSize ? - this.blockSize : (this.blockSize - input.length())); - input.fillWithByte(padding, padding); - return true; -}; - -modes.ecb.prototype.unpad = function(output, options) { - // check for error: input data not a multiple of blockSize - if(options.overflow > 0) { - return false; - } - - // ensure padding byte count is valid - var len = output.length(); - var count = output.at(len - 1); - if(count > (this.blockSize << 2)) { - return false; - } - - // trim off padding bytes - output.truncate(count); - return true; -}; - - -/** Cipher-block Chaining (CBC) **/ - -modes.cbc = function(options) { - options = options || {}; - this.name = 'CBC'; - this.cipher = options.cipher; - this.blockSize = options.blockSize || 16; - this._ints = this.blockSize / 4; - this._inBlock = new Array(this._ints); - this._outBlock = new Array(this._ints); -}; - -modes.cbc.prototype.start = function(options) { - // Note: legacy support for using IV residue (has security flaws) - // if IV is null, reuse block from previous processing - if(options.iv === null) { - // must have a previous block - if(!this._prev) { - throw new Error('Invalid IV parameter.'); - } - this._iv = this._prev.slice(0); - } else if(!('iv' in options)) { - throw new Error('Invalid IV parameter.'); - } else { - // save IV as "previous" block - this._iv = transformIV(options.iv); - this._prev = this._iv.slice(0); - } -}; - -modes.cbc.prototype.encrypt = function(input, output, finish) { - // not enough input to encrypt - if(input.length() < this.blockSize && !(finish && input.length() > 0)) { - return true; - } - - // get next block - // CBC XOR's IV (or previous block) with plaintext - for(var i = 0; i < this._ints; ++i) { - this._inBlock[i] = this._prev[i] ^ input.getInt32(); - } - - // encrypt block - this.cipher.encrypt(this._inBlock, this._outBlock); - - // write output, save previous block - for(var i = 0; i < this._ints; ++i) { - output.putInt32(this._outBlock[i]); - } - this._prev = this._outBlock; -}; - -modes.cbc.prototype.decrypt = function(input, output, finish) { - // not enough input to decrypt - if(input.length() < this.blockSize && !(finish && input.length() > 0)) { - return true; - } - - // get next block - for(var i = 0; i < this._ints; ++i) { - this._inBlock[i] = input.getInt32(); - } - - // decrypt block - this.cipher.decrypt(this._inBlock, this._outBlock); - - // write output, save previous ciphered block - // CBC XOR's IV (or previous block) with ciphertext - for(var i = 0; i < this._ints; ++i) { - output.putInt32(this._prev[i] ^ this._outBlock[i]); - } - this._prev = this._inBlock.slice(0); -}; - -modes.cbc.prototype.pad = function(input, options) { - // add PKCS#7 padding to block (each pad byte is the - // value of the number of pad bytes) - var padding = (input.length() === this.blockSize ? - this.blockSize : (this.blockSize - input.length())); - input.fillWithByte(padding, padding); - return true; -}; - -modes.cbc.prototype.unpad = function(output, options) { - // check for error: input data not a multiple of blockSize - if(options.overflow > 0) { - return false; - } - - // ensure padding byte count is valid - var len = output.length(); - var count = output.at(len - 1); - if(count > (this.blockSize << 2)) { - return false; - } - - // trim off padding bytes - output.truncate(count); - return true; -}; - - -/** Cipher feedback (CFB) **/ - -modes.cfb = function(options) { - options = options || {}; - this.name = 'CFB'; - this.cipher = options.cipher; - this.blockSize = options.blockSize || 16; - this._ints = this.blockSize / 4; - this._inBlock = null; - this._outBlock = new Array(this._ints); - this._partialBlock = new Array(this._ints); - this._partialOutput = forge.util.createBuffer(); - this._partialBytes = 0; -}; - -modes.cfb.prototype.start = function(options) { - if(!('iv' in options)) { - throw new Error('Invalid IV parameter.'); - } - // use IV as first input - this._iv = transformIV(options.iv); - this._inBlock = this._iv.slice(0); - this._partialBytes = 0; -}; - -modes.cfb.prototype.encrypt = function(input, output, finish) { - // not enough input to encrypt - var inputLength = input.length(); - if(inputLength === 0) { - return true; - } - - // encrypt block - this.cipher.encrypt(this._inBlock, this._outBlock); - - // handle full block - if(this._partialBytes === 0 && inputLength >= this.blockSize) { - // XOR input with output, write input as output - for(var i = 0; i < this._ints; ++i) { - this._inBlock[i] = input.getInt32() ^ this._outBlock[i]; - output.putInt32(this._inBlock[i]); - } - return; - } - - // handle partial block - var partialBytes = (this.blockSize - inputLength) % this.blockSize; - if(partialBytes > 0) { - partialBytes = this.blockSize - partialBytes; - } - - // XOR input with output, write input as partial output - this._partialOutput.clear(); - for(var i = 0; i < this._ints; ++i) { - this._partialBlock[i] = input.getInt32() ^ this._outBlock[i]; - this._partialOutput.putInt32(this._partialBlock[i]); - } - - if(partialBytes > 0) { - // block still incomplete, restore input buffer - input.read -= this.blockSize; - } else { - // block complete, update input block - for(var i = 0; i < this._ints; ++i) { - this._inBlock[i] = this._partialBlock[i]; - } - } - - // skip any previous partial bytes - if(this._partialBytes > 0) { - this._partialOutput.getBytes(this._partialBytes); - } - - if(partialBytes > 0 && !finish) { - output.putBytes(this._partialOutput.getBytes( - partialBytes - this._partialBytes)); - this._partialBytes = partialBytes; - return true; - } - - output.putBytes(this._partialOutput.getBytes( - inputLength - this._partialBytes)); - this._partialBytes = 0; -}; - -modes.cfb.prototype.decrypt = function(input, output, finish) { - // not enough input to decrypt - var inputLength = input.length(); - if(inputLength === 0) { - return true; - } - - // encrypt block (CFB always uses encryption mode) - this.cipher.encrypt(this._inBlock, this._outBlock); - - // handle full block - if(this._partialBytes === 0 && inputLength >= this.blockSize) { - // XOR input with output, write input as output - for(var i = 0; i < this._ints; ++i) { - this._inBlock[i] = input.getInt32(); - output.putInt32(this._inBlock[i] ^ this._outBlock[i]); - } - return; - } - - // handle partial block - var partialBytes = (this.blockSize - inputLength) % this.blockSize; - if(partialBytes > 0) { - partialBytes = this.blockSize - partialBytes; - } - - // XOR input with output, write input as partial output - this._partialOutput.clear(); - for(var i = 0; i < this._ints; ++i) { - this._partialBlock[i] = input.getInt32(); - this._partialOutput.putInt32(this._partialBlock[i] ^ this._outBlock[i]); - } - - if(partialBytes > 0) { - // block still incomplete, restore input buffer - input.read -= this.blockSize; - } else { - // block complete, update input block - for(var i = 0; i < this._ints; ++i) { - this._inBlock[i] = this._partialBlock[i]; - } - } - - // skip any previous partial bytes - if(this._partialBytes > 0) { - this._partialOutput.getBytes(this._partialBytes); - } - - if(partialBytes > 0 && !finish) { - output.putBytes(this._partialOutput.getBytes( - partialBytes - this._partialBytes)); - this._partialBytes = partialBytes; - return true; - } - - output.putBytes(this._partialOutput.getBytes( - inputLength - this._partialBytes)); - this._partialBytes = 0; -}; - -/** Output feedback (OFB) **/ - -modes.ofb = function(options) { - options = options || {}; - this.name = 'OFB'; - this.cipher = options.cipher; - this.blockSize = options.blockSize || 16; - this._ints = this.blockSize / 4; - this._inBlock = null; - this._outBlock = new Array(this._ints); - this._partialOutput = forge.util.createBuffer(); - this._partialBytes = 0; -}; - -modes.ofb.prototype.start = function(options) { - if(!('iv' in options)) { - throw new Error('Invalid IV parameter.'); - } - // use IV as first input - this._iv = transformIV(options.iv); - this._inBlock = this._iv.slice(0); - this._partialBytes = 0; -}; - -modes.ofb.prototype.encrypt = function(input, output, finish) { - // not enough input to encrypt - var inputLength = input.length(); - if(input.length() === 0) { - return true; - } - - // encrypt block (OFB always uses encryption mode) - this.cipher.encrypt(this._inBlock, this._outBlock); - - // handle full block - if(this._partialBytes === 0 && inputLength >= this.blockSize) { - // XOR input with output and update next input - for(var i = 0; i < this._ints; ++i) { - output.putInt32(input.getInt32() ^ this._outBlock[i]); - this._inBlock[i] = this._outBlock[i]; - } - return; - } - - // handle partial block - var partialBytes = (this.blockSize - inputLength) % this.blockSize; - if(partialBytes > 0) { - partialBytes = this.blockSize - partialBytes; - } - - // XOR input with output - this._partialOutput.clear(); - for(var i = 0; i < this._ints; ++i) { - this._partialOutput.putInt32(input.getInt32() ^ this._outBlock[i]); - } - - if(partialBytes > 0) { - // block still incomplete, restore input buffer - input.read -= this.blockSize; - } else { - // block complete, update input block - for(var i = 0; i < this._ints; ++i) { - this._inBlock[i] = this._outBlock[i]; - } - } - - // skip any previous partial bytes - if(this._partialBytes > 0) { - this._partialOutput.getBytes(this._partialBytes); - } - - if(partialBytes > 0 && !finish) { - output.putBytes(this._partialOutput.getBytes( - partialBytes - this._partialBytes)); - this._partialBytes = partialBytes; - return true; - } - - output.putBytes(this._partialOutput.getBytes( - inputLength - this._partialBytes)); - this._partialBytes = 0; -}; - -modes.ofb.prototype.decrypt = modes.ofb.prototype.encrypt; - - -/** Counter (CTR) **/ - -modes.ctr = function(options) { - options = options || {}; - this.name = 'CTR'; - this.cipher = options.cipher; - this.blockSize = options.blockSize || 16; - this._ints = this.blockSize / 4; - this._inBlock = null; - this._outBlock = new Array(this._ints); - this._partialOutput = forge.util.createBuffer(); - this._partialBytes = 0; -}; - -modes.ctr.prototype.start = function(options) { - if(!('iv' in options)) { - throw new Error('Invalid IV parameter.'); - } - // use IV as first input - this._iv = transformIV(options.iv); - this._inBlock = this._iv.slice(0); - this._partialBytes = 0; -}; - -modes.ctr.prototype.encrypt = function(input, output, finish) { - // not enough input to encrypt - var inputLength = input.length(); - if(inputLength === 0) { - return true; - } - - // encrypt block (CTR always uses encryption mode) - this.cipher.encrypt(this._inBlock, this._outBlock); - - // handle full block - if(this._partialBytes === 0 && inputLength >= this.blockSize) { - // XOR input with output - for(var i = 0; i < this._ints; ++i) { - output.putInt32(input.getInt32() ^ this._outBlock[i]); - } - } else { - // handle partial block - var partialBytes = (this.blockSize - inputLength) % this.blockSize; - if(partialBytes > 0) { - partialBytes = this.blockSize - partialBytes; - } - - // XOR input with output - this._partialOutput.clear(); - for(var i = 0; i < this._ints; ++i) { - this._partialOutput.putInt32(input.getInt32() ^ this._outBlock[i]); - } - - if(partialBytes > 0) { - // block still incomplete, restore input buffer - input.read -= this.blockSize; - } - - // skip any previous partial bytes - if(this._partialBytes > 0) { - this._partialOutput.getBytes(this._partialBytes); - } - - if(partialBytes > 0 && !finish) { - output.putBytes(this._partialOutput.getBytes( - partialBytes - this._partialBytes)); - this._partialBytes = partialBytes; - return true; - } - - output.putBytes(this._partialOutput.getBytes( - inputLength - this._partialBytes)); - this._partialBytes = 0; - } - - // block complete, increment counter (input block) - inc32(this._inBlock); -}; - -modes.ctr.prototype.decrypt = modes.ctr.prototype.encrypt; - - -/** Galois/Counter Mode (GCM) **/ - -modes.gcm = function(options) { - options = options || {}; - this.name = 'GCM'; - this.cipher = options.cipher; - this.blockSize = options.blockSize || 16; - this._ints = this.blockSize / 4; - this._inBlock = new Array(this._ints); - this._outBlock = new Array(this._ints); - this._partialOutput = forge.util.createBuffer(); - this._partialBytes = 0; - - // R is actually this value concatenated with 120 more zero bits, but - // we only XOR against R so the other zeros have no effect -- we just - // apply this value to the first integer in a block - this._R = 0xE1000000; -}; - -modes.gcm.prototype.start = function(options) { - if(!('iv' in options)) { - throw new Error('Invalid IV parameter.'); - } - // ensure IV is a byte buffer - var iv = forge.util.createBuffer(options.iv); - - // no ciphered data processed yet - this._cipherLength = 0; - - // default additional data is none - var additionalData; - if('additionalData' in options) { - additionalData = forge.util.createBuffer(options.additionalData); - } else { - additionalData = forge.util.createBuffer(); - } - - // default tag length is 128 bits - if('tagLength' in options) { - this._tagLength = options.tagLength; - } else { - this._tagLength = 128; - } - - // if tag is given, ensure tag matches tag length - this._tag = null; - if(options.decrypt) { - // save tag to check later - this._tag = forge.util.createBuffer(options.tag).getBytes(); - if(this._tag.length !== (this._tagLength / 8)) { - throw new Error('Authentication tag does not match tag length.'); - } - } - - // create tmp storage for hash calculation - this._hashBlock = new Array(this._ints); - - // no tag generated yet - this.tag = null; - - // generate hash subkey - // (apply block cipher to "zero" block) - this._hashSubkey = new Array(this._ints); - this.cipher.encrypt([0, 0, 0, 0], this._hashSubkey); - - // generate table M - // use 4-bit tables (32 component decomposition of a 16 byte value) - // 8-bit tables take more space and are known to have security - // vulnerabilities (in native implementations) - this.componentBits = 4; - this._m = this.generateHashTable(this._hashSubkey, this.componentBits); - - // Note: support IV length different from 96 bits? (only supporting - // 96 bits is recommended by NIST SP-800-38D) - // generate J_0 - var ivLength = iv.length(); - if(ivLength === 12) { - // 96-bit IV - this._j0 = [iv.getInt32(), iv.getInt32(), iv.getInt32(), 1]; - } else { - // IV is NOT 96-bits - this._j0 = [0, 0, 0, 0]; - while(iv.length() > 0) { - this._j0 = this.ghash( - this._hashSubkey, this._j0, - [iv.getInt32(), iv.getInt32(), iv.getInt32(), iv.getInt32()]); - } - this._j0 = this.ghash( - this._hashSubkey, this._j0, [0, 0].concat(from64To32(ivLength * 8))); - } - - // generate ICB (initial counter block) - this._inBlock = this._j0.slice(0); - inc32(this._inBlock); - this._partialBytes = 0; - - // consume authentication data - additionalData = forge.util.createBuffer(additionalData); - // save additional data length as a BE 64-bit number - this._aDataLength = from64To32(additionalData.length() * 8); - // pad additional data to 128 bit (16 byte) block size - var overflow = additionalData.length() % this.blockSize; - if(overflow) { - additionalData.fillWithByte(0, this.blockSize - overflow); - } - this._s = [0, 0, 0, 0]; - while(additionalData.length() > 0) { - this._s = this.ghash(this._hashSubkey, this._s, [ - additionalData.getInt32(), - additionalData.getInt32(), - additionalData.getInt32(), - additionalData.getInt32() - ]); - } -}; - -modes.gcm.prototype.encrypt = function(input, output, finish) { - // not enough input to encrypt - var inputLength = input.length(); - if(inputLength === 0) { - return true; - } - - // encrypt block - this.cipher.encrypt(this._inBlock, this._outBlock); - - // handle full block - if(this._partialBytes === 0 && inputLength >= this.blockSize) { - // XOR input with output - for(var i = 0; i < this._ints; ++i) { - output.putInt32(this._outBlock[i] ^= input.getInt32()); - } - this._cipherLength += this.blockSize; - } else { - // handle partial block - var partialBytes = (this.blockSize - inputLength) % this.blockSize; - if(partialBytes > 0) { - partialBytes = this.blockSize - partialBytes; - } - - // XOR input with output - this._partialOutput.clear(); - for(var i = 0; i < this._ints; ++i) { - this._partialOutput.putInt32(input.getInt32() ^ this._outBlock[i]); - } - - if(partialBytes === 0 || finish) { - // handle overflow prior to hashing - if(finish) { - // get block overflow - var overflow = inputLength % this.blockSize; - this._cipherLength += overflow; - // truncate for hash function - this._partialOutput.truncate(this.blockSize - overflow); - } else { - this._cipherLength += this.blockSize; - } - - // get output block for hashing - for(var i = 0; i < this._ints; ++i) { - this._outBlock[i] = this._partialOutput.getInt32(); - } - this._partialOutput.read -= this.blockSize; - } - - // skip any previous partial bytes - if(this._partialBytes > 0) { - this._partialOutput.getBytes(this._partialBytes); - } - - if(partialBytes > 0 && !finish) { - // block still incomplete, restore input buffer, get partial output, - // and return early - input.read -= this.blockSize; - output.putBytes(this._partialOutput.getBytes( - partialBytes - this._partialBytes)); - this._partialBytes = partialBytes; - return true; - } - - output.putBytes(this._partialOutput.getBytes( - inputLength - this._partialBytes)); - this._partialBytes = 0; - } - - // update hash block S - this._s = this.ghash(this._hashSubkey, this._s, this._outBlock); - - // increment counter (input block) - inc32(this._inBlock); -}; - -modes.gcm.prototype.decrypt = function(input, output, finish) { - // not enough input to decrypt - var inputLength = input.length(); - if(inputLength < this.blockSize && !(finish && inputLength > 0)) { - return true; - } - - // encrypt block (GCM always uses encryption mode) - this.cipher.encrypt(this._inBlock, this._outBlock); - - // increment counter (input block) - inc32(this._inBlock); - - // update hash block S - this._hashBlock[0] = input.getInt32(); - this._hashBlock[1] = input.getInt32(); - this._hashBlock[2] = input.getInt32(); - this._hashBlock[3] = input.getInt32(); - this._s = this.ghash(this._hashSubkey, this._s, this._hashBlock); - - // XOR hash input with output - for(var i = 0; i < this._ints; ++i) { - output.putInt32(this._outBlock[i] ^ this._hashBlock[i]); - } - - // increment cipher data length - if(inputLength < this.blockSize) { - this._cipherLength += inputLength % this.blockSize; - } else { - this._cipherLength += this.blockSize; - } -}; - -modes.gcm.prototype.afterFinish = function(output, options) { - var rval = true; - - // handle overflow - if(options.decrypt && options.overflow) { - output.truncate(this.blockSize - options.overflow); - } - - // handle authentication tag - this.tag = forge.util.createBuffer(); - - // concatenate additional data length with cipher length - var lengths = this._aDataLength.concat(from64To32(this._cipherLength * 8)); - - // include lengths in hash - this._s = this.ghash(this._hashSubkey, this._s, lengths); - - // do GCTR(J_0, S) - var tag = []; - this.cipher.encrypt(this._j0, tag); - for(var i = 0; i < this._ints; ++i) { - this.tag.putInt32(this._s[i] ^ tag[i]); - } - - // trim tag to length - this.tag.truncate(this.tag.length() % (this._tagLength / 8)); - - // check authentication tag - if(options.decrypt && this.tag.bytes() !== this._tag) { - rval = false; - } - - return rval; -}; - -/** - * See NIST SP-800-38D 6.3 (Algorithm 1). This function performs Galois - * field multiplication. The field, GF(2^128), is defined by the polynomial: - * - * x^128 + x^7 + x^2 + x + 1 - * - * Which is represented in little-endian binary form as: 11100001 (0xe1). When - * the value of a coefficient is 1, a bit is set. The value R, is the - * concatenation of this value and 120 zero bits, yielding a 128-bit value - * which matches the block size. - * - * This function will multiply two elements (vectors of bytes), X and Y, in - * the field GF(2^128). The result is initialized to zero. For each bit of - * X (out of 128), x_i, if x_i is set, then the result is multiplied (XOR'd) - * by the current value of Y. For each bit, the value of Y will be raised by - * a power of x (multiplied by the polynomial x). This can be achieved by - * shifting Y once to the right. If the current value of Y, prior to being - * multiplied by x, has 0 as its LSB, then it is a 127th degree polynomial. - * Otherwise, we must divide by R after shifting to find the remainder. - * - * @param x the first block to multiply by the second. - * @param y the second block to multiply by the first. - * - * @return the block result of the multiplication. - */ -modes.gcm.prototype.multiply = function(x, y) { - var z_i = [0, 0, 0, 0]; - var v_i = y.slice(0); - - // calculate Z_128 (block has 128 bits) - for(var i = 0; i < 128; ++i) { - // if x_i is 0, Z_{i+1} = Z_i (unchanged) - // else Z_{i+1} = Z_i ^ V_i - // get x_i by finding 32-bit int position, then left shift 1 by remainder - var x_i = x[(i / 32) | 0] & (1 << (31 - i % 32)); - if(x_i) { - z_i[0] ^= v_i[0]; - z_i[1] ^= v_i[1]; - z_i[2] ^= v_i[2]; - z_i[3] ^= v_i[3]; - } - - // if LSB(V_i) is 1, V_i = V_i >> 1 - // else V_i = (V_i >> 1) ^ R - this.pow(v_i, v_i); - } - - return z_i; -}; - -modes.gcm.prototype.pow = function(x, out) { - // if LSB(x) is 1, x = x >>> 1 - // else x = (x >>> 1) ^ R - var lsb = x[3] & 1; - - // always do x >>> 1: - // starting with the rightmost integer, shift each integer to the right - // one bit, pulling in the bit from the integer to the left as its top - // most bit (do this for the last 3 integers) - for(var i = 3; i > 0; --i) { - out[i] = (x[i] >>> 1) | ((x[i - 1] & 1) << 31); - } - // shift the first integer normally - out[0] = x[0] >>> 1; - - // if lsb was not set, then polynomial had a degree of 127 and doesn't - // need to divided; otherwise, XOR with R to find the remainder; we only - // need to XOR the first integer since R technically ends w/120 zero bits - if(lsb) { - out[0] ^= this._R; - } -}; - -modes.gcm.prototype.tableMultiply = function(x) { - // assumes 4-bit tables are used - var z = [0, 0, 0, 0]; - for(var i = 0; i < 32; ++i) { - var idx = (i / 8) | 0; - var x_i = (x[idx] >>> ((7 - (i % 8)) * 4)) & 0xF; - var ah = this._m[i][x_i]; - z[0] ^= ah[0]; - z[1] ^= ah[1]; - z[2] ^= ah[2]; - z[3] ^= ah[3]; - } - return z; -}; - -/** - * A continuing version of the GHASH algorithm that operates on a single - * block. The hash block, last hash value (Ym) and the new block to hash - * are given. - * - * @param h the hash block. - * @param y the previous value for Ym, use [0, 0, 0, 0] for a new hash. - * @param x the block to hash. - * - * @return the hashed value (Ym). - */ -modes.gcm.prototype.ghash = function(h, y, x) { - y[0] ^= x[0]; - y[1] ^= x[1]; - y[2] ^= x[2]; - y[3] ^= x[3]; - return this.tableMultiply(y); - //return this.multiply(y, h); -}; - -/** - * Precomputes a table for multiplying against the hash subkey. This - * mechanism provides a substantial speed increase over multiplication - * performed without a table. The table-based multiplication this table is - * for solves X * H by multiplying each component of X by H and then - * composing the results together using XOR. - * - * This function can be used to generate tables with different bit sizes - * for the components, however, this implementation assumes there are - * 32 components of X (which is a 16 byte vector), therefore each component - * takes 4-bits (so the table is constructed with bits=4). - * - * @param h the hash subkey. - * @param bits the bit size for a component. - */ -modes.gcm.prototype.generateHashTable = function(h, bits) { - // TODO: There are further optimizations that would use only the - // first table M_0 (or some variant) along with a remainder table; - // this can be explored in the future - var multiplier = 8 / bits; - var perInt = 4 * multiplier; - var size = 16 * multiplier; - var m = new Array(size); - for(var i = 0; i < size; ++i) { - var tmp = [0, 0, 0, 0]; - var idx = (i / perInt) | 0; - var shft = ((perInt - 1 - (i % perInt)) * bits); - tmp[idx] = (1 << (bits - 1)) << shft; - m[i] = this.generateSubHashTable(this.multiply(tmp, h), bits); - } - return m; -}; - -/** - * Generates a table for multiplying against the hash subkey for one - * particular component (out of all possible component values). - * - * @param mid the pre-multiplied value for the middle key of the table. - * @param bits the bit size for a component. - */ -modes.gcm.prototype.generateSubHashTable = function(mid, bits) { - // compute the table quickly by minimizing the number of - // POW operations -- they only need to be performed for powers of 2, - // all other entries can be composed from those powers using XOR - var size = 1 << bits; - var half = size >>> 1; - var m = new Array(size); - m[half] = mid.slice(0); - var i = half >>> 1; - while(i > 0) { - // raise m0[2 * i] and store in m0[i] - this.pow(m[2 * i], m[i] = []); - i >>= 1; - } - i = 2; - while(i < half) { - for(var j = 1; j < i; ++j) { - var m_i = m[i]; - var m_j = m[j]; - m[i + j] = [ - m_i[0] ^ m_j[0], - m_i[1] ^ m_j[1], - m_i[2] ^ m_j[2], - m_i[3] ^ m_j[3] - ]; - } - i *= 2; - } - m[0] = [0, 0, 0, 0]; - /* Note: We could avoid storing these by doing composition during multiply - calculate top half using composition by speed is preferred. */ - for(i = half + 1; i < size; ++i) { - var c = m[i ^ half]; - m[i] = [mid[0] ^ c[0], mid[1] ^ c[1], mid[2] ^ c[2], mid[3] ^ c[3]]; - } - return m; -}; - - -/** Utility functions */ - -function transformIV(iv) { - if(typeof iv === 'string') { - // convert iv string into byte buffer - iv = forge.util.createBuffer(iv); - } - - if(forge.util.isArray(iv) && iv.length > 4) { - // convert iv byte array into byte buffer - var tmp = iv; - iv = forge.util.createBuffer(); - for(var i = 0; i < tmp.length; ++i) { - iv.putByte(tmp[i]); - } - } - if(!forge.util.isArray(iv)) { - // convert iv byte buffer into 32-bit integer array - iv = [iv.getInt32(), iv.getInt32(), iv.getInt32(), iv.getInt32()]; - } - - return iv; -} - -function inc32(block) { - // increment last 32 bits of block only - block[block.length - 1] = (block[block.length - 1] + 1) & 0xFFFFFFFF; -} - -function from64To32(num) { - // convert 64-bit number to two BE Int32s - return [(num / 0x100000000) | 0, num & 0xFFFFFFFF]; -} - - -} // end module implementation - -/* ########## Begin module wrapper ########## */ -var name = 'cipherModes'; -if(typeof define !== 'function') { - // NodeJS -> AMD - if(typeof module === 'object' && module.exports) { - var nodeJS = true; - define = function(ids, factory) { - factory(require, module); - }; - } else { - // <script> - if(typeof forge === 'undefined') { - forge = {}; - } - return initModule(forge); - } -} -// AMD -var deps; -var defineFunc = function(require, module) { - module.exports = function(forge) { - var mods = deps.map(function(dep) { - return require(dep); - }).concat(initModule); - // handle circular dependencies - forge = forge || {}; - forge.defined = forge.defined || {}; - if(forge.defined[name]) { - return forge[name]; - } - forge.defined[name] = true; - for(var i = 0; i < mods.length; ++i) { - mods[i](forge); - } - return forge[name]; - }; -}; -var tmpDefine = define; -define = function(ids, factory) { - deps = (typeof ids === 'string') ? factory.slice(2) : ids.slice(2); - if(nodeJS) { - delete define; - return tmpDefine.apply(null, Array.prototype.slice.call(arguments, 0)); - } - define = tmpDefine; - return define.apply(null, Array.prototype.slice.call(arguments, 0)); -}; -define(['require', 'module', './util'], function() { - defineFunc.apply(null, Array.prototype.slice.call(arguments, 0)); -}); -})(); diff --git a/alarm/node_modules/node-forge/js/debug.js b/alarm/node_modules/node-forge/js/debug.js deleted file mode 100644 index 4f7c13d..0000000 --- a/alarm/node_modules/node-forge/js/debug.js +++ /dev/null @@ -1,134 +0,0 @@ -/** - * Debugging support for web applications. - * - * @author David I. Lehn <dlehn@digitalbazaar.com> - * - * Copyright 2008-2013 Digital Bazaar, Inc. - */ -(function() { -/* ########## Begin module implementation ########## */ -function initModule(forge) { - -/* DEBUG API */ -forge.debug = forge.debug || {}; - -// Private storage for debugging. -// Useful to expose data that is otherwise unviewable behind closures. -// NOTE: remember that this can hold references to data and cause leaks! -// format is "forge._debug.<modulename>.<dataname> = data" -// Example: -// (function() { -// var cat = 'forge.test.Test'; // debugging category -// var sState = {...}; // local state -// forge.debug.set(cat, 'sState', sState); -// })(); -forge.debug.storage = {}; - -/** - * Gets debug data. Omit name for all cat data Omit name and cat for - * all data. - * - * @param cat name of debugging category. - * @param name name of data to get (optional). - * @return object with requested debug data or undefined. - */ -forge.debug.get = function(cat, name) { - var rval; - if(typeof(cat) === 'undefined') { - rval = forge.debug.storage; - } else if(cat in forge.debug.storage) { - if(typeof(name) === 'undefined') { - rval = forge.debug.storage[cat]; - } else { - rval = forge.debug.storage[cat][name]; - } - } - return rval; -}; - -/** - * Sets debug data. - * - * @param cat name of debugging category. - * @param name name of data to set. - * @param data data to set. - */ -forge.debug.set = function(cat, name, data) { - if(!(cat in forge.debug.storage)) { - forge.debug.storage[cat] = {}; - } - forge.debug.storage[cat][name] = data; -}; - -/** - * Clears debug data. Omit name for all cat data. Omit name and cat for - * all data. - * - * @param cat name of debugging category. - * @param name name of data to clear or omit to clear entire category. - */ -forge.debug.clear = function(cat, name) { - if(typeof(cat) === 'undefined') { - forge.debug.storage = {}; - } else if(cat in forge.debug.storage) { - if(typeof(name) === 'undefined') { - delete forge.debug.storage[cat]; - } else { - delete forge.debug.storage[cat][name]; - } - } -}; - -} // end module implementation - -/* ########## Begin module wrapper ########## */ -var name = 'debug'; -if(typeof define !== 'function') { - // NodeJS -> AMD - if(typeof module === 'object' && module.exports) { - var nodeJS = true; - define = function(ids, factory) { - factory(require, module); - }; - } else { - // <script> - if(typeof forge === 'undefined') { - forge = {}; - } - return initModule(forge); - } -} -// AMD -var deps; -var defineFunc = function(require, module) { - module.exports = function(forge) { - var mods = deps.map(function(dep) { - return require(dep); - }).concat(initModule); - // handle circular dependencies - forge = forge || {}; - forge.defined = forge.defined || {}; - if(forge.defined[name]) { - return forge[name]; - } - forge.defined[name] = true; - for(var i = 0; i < mods.length; ++i) { - mods[i](forge); - } - return forge[name]; - }; -}; -var tmpDefine = define; -define = function(ids, factory) { - deps = (typeof ids === 'string') ? factory.slice(2) : ids.slice(2); - if(nodeJS) { - delete define; - return tmpDefine.apply(null, Array.prototype.slice.call(arguments, 0)); - } - define = tmpDefine; - return define.apply(null, Array.prototype.slice.call(arguments, 0)); -}; -define(['require', 'module'], function() { - defineFunc.apply(null, Array.prototype.slice.call(arguments, 0)); -}); -})(); diff --git a/alarm/node_modules/node-forge/js/des.js b/alarm/node_modules/node-forge/js/des.js deleted file mode 100644 index bf6d477..0000000 --- a/alarm/node_modules/node-forge/js/des.js +++ /dev/null @@ -1,552 +0,0 @@ -/** - * DES (Data Encryption Standard) implementation. - * - * This implementation supports DES as well as 3DES-EDE in ECB and CBC mode. - * It is based on the BSD-licensed implementation by Paul Tero: - * - * Paul Tero, July 2001 - * http://www.tero.co.uk/des/ - * - * Optimised for performance with large blocks by Michael Hayworth, November 2001 - * http://www.netdealing.com - * - * THIS SOFTWARE IS PROVIDED "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @author Stefan Siegl - * @author Dave Longley - * - * Copyright (c) 2012 Stefan Siegl <stesie@brokenpipe.de> - * Copyright (c) 2012-2014 Digital Bazaar, Inc. - */ -(function() { -/* ########## Begin module implementation ########## */ -function initModule(forge) { - -/* DES API */ -forge.des = forge.des || {}; - -/** - * Deprecated. Instead, use: - * - * var cipher = forge.cipher.createCipher('DES-<mode>', key); - * cipher.start({iv: iv}); - * - * Creates an DES cipher object to encrypt data using the given symmetric key. - * The output will be stored in the 'output' member of the returned cipher. - * - * The key and iv may be given as binary-encoded strings of bytes or - * byte buffers. - * - * @param key the symmetric key to use (64 or 192 bits). - * @param iv the initialization vector to use. - * @param output the buffer to write to, null to create one. - * @param mode the cipher mode to use (default: 'CBC' if IV is - * given, 'ECB' if null). - * - * @return the cipher. - */ -forge.des.startEncrypting = function(key, iv, output, mode) { - var cipher = _createCipher({ - key: key, - output: output, - decrypt: false, - mode: mode || (iv === null ? 'ECB' : 'CBC') - }); - cipher.start(iv); - return cipher; -}; - -/** - * Deprecated. Instead, use: - * - * var cipher = forge.cipher.createCipher('DES-<mode>', key); - * - * Creates an DES cipher object to encrypt data using the given symmetric key. - * - * The key may be given as a binary-encoded string of bytes or a byte buffer. - * - * @param key the symmetric key to use (64 or 192 bits). - * @param mode the cipher mode to use (default: 'CBC'). - * - * @return the cipher. - */ -forge.des.createEncryptionCipher = function(key, mode) { - return _createCipher({ - key: key, - output: null, - decrypt: false, - mode: mode - }); -}; - -/** - * Deprecated. Instead, use: - * - * var decipher = forge.cipher.createDecipher('DES-<mode>', key); - * decipher.start({iv: iv}); - * - * Creates an DES cipher object to decrypt data using the given symmetric key. - * The output will be stored in the 'output' member of the returned cipher. - * - * The key and iv may be given as binary-encoded strings of bytes or - * byte buffers. - * - * @param key the symmetric key to use (64 or 192 bits). - * @param iv the initialization vector to use. - * @param output the buffer to write to, null to create one. - * @param mode the cipher mode to use (default: 'CBC' if IV is - * given, 'ECB' if null). - * - * @return the cipher. - */ -forge.des.startDecrypting = function(key, iv, output, mode) { - var cipher = _createCipher({ - key: key, - output: output, - decrypt: true, - mode: mode || (iv === null ? 'ECB' : 'CBC') - }); - cipher.start(iv); - return cipher; -}; - -/** - * Deprecated. Instead, use: - * - * var decipher = forge.cipher.createDecipher('DES-<mode>', key); - * - * Creates an DES cipher object to decrypt data using the given symmetric key. - * - * The key may be given as a binary-encoded string of bytes or a byte buffer. - * - * @param key the symmetric key to use (64 or 192 bits). - * @param mode the cipher mode to use (default: 'CBC'). - * - * @return the cipher. - */ -forge.des.createDecryptionCipher = function(key, mode) { - return _createCipher({ - key: key, - output: null, - decrypt: true, - mode: mode - }); -}; - -/** - * Creates a new DES cipher algorithm object. - * - * @param name the name of the algorithm. - * @param mode the mode factory function. - * - * @return the DES algorithm object. - */ -forge.des.Algorithm = function(name, mode) { - var self = this; - self.name = name; - self.mode = new mode({ - blockSize: 8, - cipher: { - encrypt: function(inBlock, outBlock) { - return _updateBlock(self._keys, inBlock, outBlock, false); - }, - decrypt: function(inBlock, outBlock) { - return _updateBlock(self._keys, inBlock, outBlock, true); - } - } - }); - self._init = false; -}; - -/** - * Initializes this DES algorithm by expanding its key. - * - * @param options the options to use. - * key the key to use with this algorithm. - * decrypt true if the algorithm should be initialized for decryption, - * false for encryption. - */ -forge.des.Algorithm.prototype.initialize = function(options) { - if(this._init) { - return; - } - - var key = forge.util.createBuffer(options.key); - if(this.name.indexOf('3DES') === 0) { - if(key.length() !== 24) { - throw new Error('Invalid Triple-DES key size: ' + key.length() * 8); - } - } - - // do key expansion to 16 or 48 subkeys (single or triple DES) - this._keys = _createKeys(key); - this._init = true; -}; - - -/** Register DES algorithms **/ - -registerAlgorithm('DES-ECB', forge.cipher.modes.ecb); -registerAlgorithm('DES-CBC', forge.cipher.modes.cbc); -registerAlgorithm('DES-CFB', forge.cipher.modes.cfb); -registerAlgorithm('DES-OFB', forge.cipher.modes.ofb); -registerAlgorithm('DES-CTR', forge.cipher.modes.ctr); - -registerAlgorithm('3DES-ECB', forge.cipher.modes.ecb); -registerAlgorithm('3DES-CBC', forge.cipher.modes.cbc); -registerAlgorithm('3DES-CFB', forge.cipher.modes.cfb); -registerAlgorithm('3DES-OFB', forge.cipher.modes.ofb); -registerAlgorithm('3DES-CTR', forge.cipher.modes.ctr); - -function registerAlgorithm(name, mode) { - var factory = function() { - return new forge.des.Algorithm(name, mode); - }; - forge.cipher.registerAlgorithm(name, factory); -} - - -/** DES implementation **/ - -var spfunction1 = [0x1010400,0,0x10000,0x1010404,0x1010004,0x10404,0x4,0x10000,0x400,0x1010400,0x1010404,0x400,0x1000404,0x1010004,0x1000000,0x4,0x404,0x1000400,0x1000400,0x10400,0x10400,0x1010000,0x1010000,0x1000404,0x10004,0x1000004,0x1000004,0x10004,0,0x404,0x10404,0x1000000,0x10000,0x1010404,0x4,0x1010000,0x1010400,0x1000000,0x1000000,0x400,0x1010004,0x10000,0x10400,0x1000004,0x400,0x4,0x1000404,0x10404,0x1010404,0x10004,0x1010000,0x1000404,0x1000004,0x404,0x10404,0x1010400,0x404,0x1000400,0x1000400,0,0x10004,0x10400,0,0x1010004]; -var spfunction2 = [-0x7fef7fe0,-0x7fff8000,0x8000,0x108020,0x100000,0x20,-0x7fefffe0,-0x7fff7fe0,-0x7fffffe0,-0x7fef7fe0,-0x7fef8000,-0x80000000,-0x7fff8000,0x100000,0x20,-0x7fefffe0,0x108000,0x100020,-0x7fff7fe0,0,-0x80000000,0x8000,0x108020,-0x7ff00000,0x100020,-0x7fffffe0,0,0x108000,0x8020,-0x7fef8000,-0x7ff00000,0x8020,0,0x108020,-0x7fefffe0,0x100000,-0x7fff7fe0,-0x7ff00000,-0x7fef8000,0x8000,-0x7ff00000,-0x7fff8000,0x20,-0x7fef7fe0,0x108020,0x20,0x8000,-0x80000000,0x8020,-0x7fef8000,0x100000,-0x7fffffe0,0x100020,-0x7fff7fe0,-0x7fffffe0,0x100020,0x108000,0,-0x7fff8000,0x8020,-0x80000000,-0x7fefffe0,-0x7fef7fe0,0x108000]; -var spfunction3 = [0x208,0x8020200,0,0x8020008,0x8000200,0,0x20208,0x8000200,0x20008,0x8000008,0x8000008,0x20000,0x8020208,0x20008,0x8020000,0x208,0x8000000,0x8,0x8020200,0x200,0x20200,0x8020000,0x8020008,0x20208,0x8000208,0x20200,0x20000,0x8000208,0x8,0x8020208,0x200,0x8000000,0x8020200,0x8000000,0x20008,0x208,0x20000,0x8020200,0x8000200,0,0x200,0x20008,0x8020208,0x8000200,0x8000008,0x200,0,0x8020008,0x8000208,0x20000,0x8000000,0x8020208,0x8,0x20208,0x20200,0x8000008,0x8020000,0x8000208,0x208,0x8020000,0x20208,0x8,0x8020008,0x20200]; -var spfunction4 = [0x802001,0x2081,0x2081,0x80,0x802080,0x800081,0x800001,0x2001,0,0x802000,0x802000,0x802081,0x81,0,0x800080,0x800001,0x1,0x2000,0x800000,0x802001,0x80,0x800000,0x2001,0x2080,0x800081,0x1,0x2080,0x800080,0x2000,0x802080,0x802081,0x81,0x800080,0x800001,0x802000,0x802081,0x81,0,0,0x802000,0x2080,0x800080,0x800081,0x1,0x802001,0x2081,0x2081,0x80,0x802081,0x81,0x1,0x2000,0x800001,0x2001,0x802080,0x800081,0x2001,0x2080,0x800000,0x802001,0x80,0x800000,0x2000,0x802080]; -var spfunction5 = [0x100,0x2080100,0x2080000,0x42000100,0x80000,0x100,0x40000000,0x2080000,0x40080100,0x80000,0x2000100,0x40080100,0x42000100,0x42080000,0x80100,0x40000000,0x2000000,0x40080000,0x40080000,0,0x40000100,0x42080100,0x42080100,0x2000100,0x42080000,0x40000100,0,0x42000000,0x2080100,0x2000000,0x42000000,0x80100,0x80000,0x42000100,0x100,0x2000000,0x40000000,0x2080000,0x42000100,0x40080100,0x2000100,0x40000000,0x42080000,0x2080100,0x40080100,0x100,0x2000000,0x42080000,0x42080100,0x80100,0x42000000,0x42080100,0x2080000,0,0x40080000,0x42000000,0x80100,0x2000100,0x40000100,0x80000,0,0x40080000,0x2080100,0x40000100]; -var spfunction6 = [0x20000010,0x20400000,0x4000,0x20404010,0x20400000,0x10,0x20404010,0x400000,0x20004000,0x404010,0x400000,0x20000010,0x400010,0x20004000,0x20000000,0x4010,0,0x400010,0x20004010,0x4000,0x404000,0x20004010,0x10,0x20400010,0x20400010,0,0x404010,0x20404000,0x4010,0x404000,0x20404000,0x20000000,0x20004000,0x10,0x20400010,0x404000,0x20404010,0x400000,0x4010,0x20000010,0x400000,0x20004000,0x20000000,0x4010,0x20000010,0x20404010,0x404000,0x20400000,0x404010,0x20404000,0,0x20400010,0x10,0x4000,0x20400000,0x404010,0x4000,0x400010,0x20004010,0,0x20404000,0x20000000,0x400010,0x20004010]; -var spfunction7 = [0x200000,0x4200002,0x4000802,0,0x800,0x4000802,0x200802,0x4200800,0x4200802,0x200000,0,0x4000002,0x2,0x4000000,0x4200002,0x802,0x4000800,0x200802,0x200002,0x4000800,0x4000002,0x4200000,0x4200800,0x200002,0x4200000,0x800,0x802,0x4200802,0x200800,0x2,0x4000000,0x200800,0x4000000,0x200800,0x200000,0x4000802,0x4000802,0x4200002,0x4200002,0x2,0x200002,0x4000000,0x4000800,0x200000,0x4200800,0x802,0x200802,0x4200800,0x802,0x4000002,0x4200802,0x4200000,0x200800,0,0x2,0x4200802,0,0x200802,0x4200000,0x800,0x4000002,0x4000800,0x800,0x200002]; -var spfunction8 = [0x10001040,0x1000,0x40000,0x10041040,0x10000000,0x10001040,0x40,0x10000000,0x40040,0x10040000,0x10041040,0x41000,0x10041000,0x41040,0x1000,0x40,0x10040000,0x10000040,0x10001000,0x1040,0x41000,0x40040,0x10040040,0x10041000,0x1040,0,0,0x10040040,0x10000040,0x10001000,0x41040,0x40000,0x41040,0x40000,0x10041000,0x1000,0x40,0x10040040,0x1000,0x41040,0x10001000,0x40,0x10000040,0x10040000,0x10040040,0x10000000,0x40000,0x10001040,0,0x10041040,0x40040,0x10000040,0x10040000,0x10001000,0x10001040,0,0x10041040,0x41000,0x41000,0x1040,0x1040,0x40040,0x10000000,0x10041000]; - -/** - * Create necessary sub keys. - * - * @param key the 64-bit or 192-bit key. - * - * @return the expanded keys. - */ -function _createKeys(key) { - var pc2bytes0 = [0,0x4,0x20000000,0x20000004,0x10000,0x10004,0x20010000,0x20010004,0x200,0x204,0x20000200,0x20000204,0x10200,0x10204,0x20010200,0x20010204], - pc2bytes1 = [0,0x1,0x100000,0x100001,0x4000000,0x4000001,0x4100000,0x4100001,0x100,0x101,0x100100,0x100101,0x4000100,0x4000101,0x4100100,0x4100101], - pc2bytes2 = [0,0x8,0x800,0x808,0x1000000,0x1000008,0x1000800,0x1000808,0,0x8,0x800,0x808,0x1000000,0x1000008,0x1000800,0x1000808], - pc2bytes3 = [0,0x200000,0x8000000,0x8200000,0x2000,0x202000,0x8002000,0x8202000,0x20000,0x220000,0x8020000,0x8220000,0x22000,0x222000,0x8022000,0x8222000], - pc2bytes4 = [0,0x40000,0x10,0x40010,0,0x40000,0x10,0x40010,0x1000,0x41000,0x1010,0x41010,0x1000,0x41000,0x1010,0x41010], - pc2bytes5 = [0,0x400,0x20,0x420,0,0x400,0x20,0x420,0x2000000,0x2000400,0x2000020,0x2000420,0x2000000,0x2000400,0x2000020,0x2000420], - pc2bytes6 = [0,0x10000000,0x80000,0x10080000,0x2,0x10000002,0x80002,0x10080002,0,0x10000000,0x80000,0x10080000,0x2,0x10000002,0x80002,0x10080002], - pc2bytes7 = [0,0x10000,0x800,0x10800,0x20000000,0x20010000,0x20000800,0x20010800,0x20000,0x30000,0x20800,0x30800,0x20020000,0x20030000,0x20020800,0x20030800], - pc2bytes8 = [0,0x40000,0,0x40000,0x2,0x40002,0x2,0x40002,0x2000000,0x2040000,0x2000000,0x2040000,0x2000002,0x2040002,0x2000002,0x2040002], - pc2bytes9 = [0,0x10000000,0x8,0x10000008,0,0x10000000,0x8,0x10000008,0x400,0x10000400,0x408,0x10000408,0x400,0x10000400,0x408,0x10000408], - pc2bytes10 = [0,0x20,0,0x20,0x100000,0x100020,0x100000,0x100020,0x2000,0x2020,0x2000,0x2020,0x102000,0x102020,0x102000,0x102020], - pc2bytes11 = [0,0x1000000,0x200,0x1000200,0x200000,0x1200000,0x200200,0x1200200,0x4000000,0x5000000,0x4000200,0x5000200,0x4200000,0x5200000,0x4200200,0x5200200], - pc2bytes12 = [0,0x1000,0x8000000,0x8001000,0x80000,0x81000,0x8080000,0x8081000,0x10,0x1010,0x8000010,0x8001010,0x80010,0x81010,0x8080010,0x8081010], - pc2bytes13 = [0,0x4,0x100,0x104,0,0x4,0x100,0x104,0x1,0x5,0x101,0x105,0x1,0x5,0x101,0x105]; - - // how many iterations (1 for des, 3 for triple des) - // changed by Paul 16/6/2007 to use Triple DES for 9+ byte keys - var iterations = key.length() > 8 ? 3 : 1; - - // stores the return keys - var keys = []; - - // now define the left shifts which need to be done - var shifts = [0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0]; - - var n = 0, tmp; - for(var j = 0; j < iterations; j ++) { - var left = key.getInt32(); - var right = key.getInt32(); - - tmp = ((left >>> 4) ^ right) & 0x0f0f0f0f; - right ^= tmp; - left ^= (tmp << 4); - - tmp = ((right >>> -16) ^ left) & 0x0000ffff; - left ^= tmp; - right ^= (tmp << -16); - - tmp = ((left >>> 2) ^ right) & 0x33333333; - right ^= tmp; - left ^= (tmp << 2); - - tmp = ((right >>> -16) ^ left) & 0x0000ffff; - left ^= tmp; - right ^= (tmp << -16); - - tmp = ((left >>> 1) ^ right) & 0x55555555; - right ^= tmp; - left ^= (tmp << 1); - - tmp = ((right >>> 8) ^ left) & 0x00ff00ff; - left ^= tmp; - right ^= (tmp << 8); - - tmp = ((left >>> 1) ^ right) & 0x55555555; - right ^= tmp; - left ^= (tmp << 1); - - // right needs to be shifted and OR'd with last four bits of left - tmp = (left << 8) | ((right >>> 20) & 0x000000f0); - - // left needs to be put upside down - left = ((right << 24) | ((right << 8) & 0xff0000) | - ((right >>> 8) & 0xff00) | ((right >>> 24) & 0xf0)); - right = tmp; - - // now go through and perform these shifts on the left and right keys - for(var i = 0; i < shifts.length; ++i) { - //shift the keys either one or two bits to the left - if(shifts[i]) { - left = (left << 2) | (left >>> 26); - right = (right << 2) | (right >>> 26); - } else { - left = (left << 1) | (left >>> 27); - right = (right << 1) | (right >>> 27); - } - left &= -0xf; - right &= -0xf; - - // now apply PC-2, in such a way that E is easier when encrypting or - // decrypting this conversion will look like PC-2 except only the last 6 - // bits of each byte are used rather than 48 consecutive bits and the - // order of lines will be according to how the S selection functions will - // be applied: S2, S4, S6, S8, S1, S3, S5, S7 - var lefttmp = ( - pc2bytes0[left >>> 28] | pc2bytes1[(left >>> 24) & 0xf] | - pc2bytes2[(left >>> 20) & 0xf] | pc2bytes3[(left >>> 16) & 0xf] | - pc2bytes4[(left >>> 12) & 0xf] | pc2bytes5[(left >>> 8) & 0xf] | - pc2bytes6[(left >>> 4) & 0xf]); - var righttmp = ( - pc2bytes7[right >>> 28] | pc2bytes8[(right >>> 24) & 0xf] | - pc2bytes9[(right >>> 20) & 0xf] | pc2bytes10[(right >>> 16) & 0xf] | - pc2bytes11[(right >>> 12) & 0xf] | pc2bytes12[(right >>> 8) & 0xf] | - pc2bytes13[(right >>> 4) & 0xf]); - tmp = ((righttmp >>> 16) ^ lefttmp) & 0x0000ffff; - keys[n++] = lefttmp ^ tmp; - keys[n++] = righttmp ^ (tmp << 16); - } - } - - return keys; -} - -/** - * Updates a single block (1 byte) using DES. The update will either - * encrypt or decrypt the block. - * - * @param keys the expanded keys. - * @param input the input block (an array of 32-bit words). - * @param output the updated output block. - * @param decrypt true to decrypt the block, false to encrypt it. - */ -function _updateBlock(keys, input, output, decrypt) { - // set up loops for single or triple DES - var iterations = keys.length === 32 ? 3 : 9; - var looping; - if(iterations === 3) { - looping = decrypt ? [30, -2, -2] : [0, 32, 2]; - } else { - looping = (decrypt ? - [94, 62, -2, 32, 64, 2, 30, -2, -2] : - [0, 32, 2, 62, 30, -2, 64, 96, 2]); - } - - var tmp; - - var left = input[0]; - var right = input[1]; - - // first each 64 bit chunk of the message must be permuted according to IP - tmp = ((left >>> 4) ^ right) & 0x0f0f0f0f; - right ^= tmp; - left ^= (tmp << 4); - - tmp = ((left >>> 16) ^ right) & 0x0000ffff; - right ^= tmp; - left ^= (tmp << 16); - - tmp = ((right >>> 2) ^ left) & 0x33333333; - left ^= tmp; - right ^= (tmp << 2); - - tmp = ((right >>> 8) ^ left) & 0x00ff00ff; - left ^= tmp; - right ^= (tmp << 8); - - tmp = ((left >>> 1) ^ right) & 0x55555555; - right ^= tmp; - left ^= (tmp << 1); - - // rotate left 1 bit - left = ((left << 1) | (left >>> 31)); - right = ((right << 1) | (right >>> 31)); - - for(var j = 0; j < iterations; j += 3) { - var endloop = looping[j + 1]; - var loopinc = looping[j + 2]; - - // now go through and perform the encryption or decryption - for(var i = looping[j]; i != endloop; i += loopinc) { - var right1 = right ^ keys[i]; - var right2 = ((right >>> 4) | (right << 28)) ^ keys[i + 1]; - - // passing these bytes through the S selection functions - tmp = left; - left = right; - right = tmp ^ ( - spfunction2[(right1 >>> 24) & 0x3f] | - spfunction4[(right1 >>> 16) & 0x3f] | - spfunction6[(right1 >>> 8) & 0x3f] | - spfunction8[right1 & 0x3f] | - spfunction1[(right2 >>> 24) & 0x3f] | - spfunction3[(right2 >>> 16) & 0x3f] | - spfunction5[(right2 >>> 8) & 0x3f] | - spfunction7[right2 & 0x3f]); - } - // unreverse left and right - tmp = left; - left = right; - right = tmp; - } - - // rotate right 1 bit - left = ((left >>> 1) | (left << 31)); - right = ((right >>> 1) | (right << 31)); - - // now perform IP-1, which is IP in the opposite direction - tmp = ((left >>> 1) ^ right) & 0x55555555; - right ^= tmp; - left ^= (tmp << 1); - - tmp = ((right >>> 8) ^ left) & 0x00ff00ff; - left ^= tmp; - right ^= (tmp << 8); - - tmp = ((right >>> 2) ^ left) & 0x33333333; - left ^= tmp; - right ^= (tmp << 2); - - tmp = ((left >>> 16) ^ right) & 0x0000ffff; - right ^= tmp; - left ^= (tmp << 16); - - tmp = ((left >>> 4) ^ right) & 0x0f0f0f0f; - right ^= tmp; - left ^= (tmp << 4); - - output[0] = left; - output[1] = right; -} - -/** - * Deprecated. Instead, use: - * - * forge.cipher.createCipher('DES-<mode>', key); - * forge.cipher.createDecipher('DES-<mode>', key); - * - * Creates a deprecated DES cipher object. This object's mode will default to - * CBC (cipher-block-chaining). - * - * The key may be given as a binary-encoded string of bytes or a byte buffer. - * - * @param options the options to use. - * key the symmetric key to use (64 or 192 bits). - * output the buffer to write to. - * decrypt true for decryption, false for encryption. - * mode the cipher mode to use (default: 'CBC'). - * - * @return the cipher. - */ -function _createCipher(options) { - options = options || {}; - var mode = (options.mode || 'CBC').toUpperCase(); - var algorithm = 'DES-' + mode; - - var cipher; - if(options.decrypt) { - cipher = forge.cipher.createDecipher(algorithm, options.key); - } else { - cipher = forge.cipher.createCipher(algorithm, options.key); - } - - // backwards compatible start API - var start = cipher.start; - cipher.start = function(iv, options) { - // backwards compatibility: support second arg as output buffer - var output = null; - if(options instanceof forge.util.ByteBuffer) { - output = options; - options = {}; - } - options = options || {}; - options.output = output; - options.iv = iv; - start.call(cipher, options); - }; - - return cipher; -} - - -} // end module implementation - -/* ########## Begin module wrapper ########## */ -var name = 'des'; -if(typeof define !== 'function') { - // NodeJS -> AMD - if(typeof module === 'object' && module.exports) { - var nodeJS = true; - define = function(ids, factory) { - factory(require, module); - }; - } else { - // <script> - if(typeof forge === 'undefined') { - forge = {}; - } - return initModule(forge); - } -} -// AMD -var deps; -var defineFunc = function(require, module) { - module.exports = function(forge) { - var mods = deps.map(function(dep) { - return require(dep); - }).concat(initModule); - // handle circular dependencies - forge = forge || {}; - forge.defined = forge.defined || {}; - if(forge.defined[name]) { - return forge[name]; - } - forge.defined[name] = true; - for(var i = 0; i < mods.length; ++i) { - mods[i](forge); - } - return forge[name]; - }; -}; -var tmpDefine = define; -define = function(ids, factory) { - deps = (typeof ids === 'string') ? factory.slice(2) : ids.slice(2); - if(nodeJS) { - delete define; - return tmpDefine.apply(null, Array.prototype.slice.call(arguments, 0)); - } - define = tmpDefine; - return define.apply(null, Array.prototype.slice.call(arguments, 0)); -}; -define( - ['require', 'module', './cipher', './cipherModes', './util'], function() { - defineFunc.apply(null, Array.prototype.slice.call(arguments, 0)); -}); -})(); diff --git a/alarm/node_modules/node-forge/js/forge.js b/alarm/node_modules/node-forge/js/forge.js deleted file mode 100644 index b314e22..0000000 --- a/alarm/node_modules/node-forge/js/forge.js +++ /dev/null @@ -1,92 +0,0 @@ -/** - * Node.js module for Forge. - * - * @author Dave Longley - * - * Copyright 2011-2014 Digital Bazaar, Inc. - */ -(function() { -var name = 'forge'; -if(typeof define !== 'function') { - // NodeJS -> AMD - if(typeof module === 'object' && module.exports) { - var nodeJS = true; - define = function(ids, factory) { - factory(require, module); - }; - } else { - // <script> - if(typeof forge === 'undefined') { - // set to true to disable native code if even it's available - forge = {disableNativeCode: false}; - } - return; - } -} -// AMD -var deps; -var defineFunc = function(require, module) { - module.exports = function(forge) { - var mods = deps.map(function(dep) { - return require(dep); - }); - // handle circular dependencies - forge = forge || {}; - forge.defined = forge.defined || {}; - if(forge.defined[name]) { - return forge[name]; - } - forge.defined[name] = true; - for(var i = 0; i < mods.length; ++i) { - mods[i](forge); - } - return forge; - }; - // set to true to disable native code if even it's available - module.exports.disableNativeCode = false; - module.exports(module.exports); -}; -var tmpDefine = define; -define = function(ids, factory) { - deps = (typeof ids === 'string') ? factory.slice(2) : ids.slice(2); - if(nodeJS) { - delete define; - return tmpDefine.apply(null, Array.prototype.slice.call(arguments, 0)); - } - define = tmpDefine; - return define.apply(null, Array.prototype.slice.call(arguments, 0)); -}; -define([ - 'require', - 'module', - './aes', - './aesCipherSuites', - './asn1', - './cipher', - './cipherModes', - './debug', - './des', - './hmac', - './kem', - './log', - './md', - './mgf1', - './pbkdf2', - './pem', - './pkcs7', - './pkcs1', - './pkcs12', - './pki', - './prime', - './prng', - './pss', - './random', - './rc2', - './ssh', - './task', - './tls', - './util' -], function() { - defineFunc.apply(null, Array.prototype.slice.call(arguments, 0)); -}); -})(); diff --git a/alarm/node_modules/node-forge/js/form.js b/alarm/node_modules/node-forge/js/form.js deleted file mode 100644 index 62d4424..0000000 --- a/alarm/node_modules/node-forge/js/form.js +++ /dev/null @@ -1,157 +0,0 @@ -/** - * Functions for manipulating web forms. - * - * @author David I. Lehn <dlehn@digitalbazaar.com> - * @author Dave Longley - * @author Mike Johnson - * - * Copyright (c) 2011-2014 Digital Bazaar, Inc. All rights reserved. - */ -(function($) { - -/** - * The form namespace. - */ -var form = {}; - -/** - * Regex for parsing a single name property (handles array brackets). - */ -var _regex = /(.*?)\[(.*?)\]/g; - -/** - * Parses a single name property into an array with the name and any - * array indices. - * - * @param name the name to parse. - * - * @return the array of the name and its array indices in order. - */ -var _parseName = function(name) { - var rval = []; - - var matches; - while(!!(matches = _regex.exec(name))) { - if(matches[1].length > 0) { - rval.push(matches[1]); - } - if(matches.length >= 2) { - rval.push(matches[2]); - } - } - if(rval.length === 0) { - rval.push(name); - } - - return rval; -}; - -/** - * Adds a field from the given form to the given object. - * - * @param obj the object. - * @param names the field as an array of object property names. - * @param value the value of the field. - * @param dict a dictionary of names to replace. - */ -var _addField = function(obj, names, value, dict) { - // combine array names that fall within square brackets - var tmp = []; - for(var i = 0; i < names.length; ++i) { - // check name for starting square bracket but no ending one - var name = names[i]; - if(name.indexOf('[') !== -1 && name.indexOf(']') === -1 && - i < names.length - 1) { - do { - name += '.' + names[++i]; - } while(i < names.length - 1 && names[i].indexOf(']') === -1); - } - tmp.push(name); - } - names = tmp; - - // split out array indexes - var tmp = []; - $.each(names, function(n, name) { - tmp = tmp.concat(_parseName(name)); - }); - names = tmp; - - // iterate over object property names until value is set - $.each(names, function(n, name) { - // do dictionary name replacement - if(dict && name.length !== 0 && name in dict) { - name = dict[name]; - } - - // blank name indicates appending to an array, set name to - // new last index of array - if(name.length === 0) { - name = obj.length; - } - - // value already exists, append value - if(obj[name]) { - // last name in the field - if(n == names.length - 1) { - // more than one value, so convert into an array - if(!$.isArray(obj[name])) { - obj[name] = [obj[name]]; - } - obj[name].push(value); - } else { - // not last name, go deeper into object - obj = obj[name]; - } - } else if(n == names.length - 1) { - // new value, last name in the field, set value - obj[name] = value; - } else { - // new value, not last name, go deeper - // get next name - var next = names[n + 1]; - - // blank next value indicates array-appending, so create array - if(next.length === 0) { - obj[name] = []; - } else { - // if next name is a number create an array, otherwise a map - var isNum = ((next - 0) == next && next.length > 0); - obj[name] = isNum ? [] : {}; - } - obj = obj[name]; - } - }); -}; - -/** - * Serializes a form to a JSON object. Object properties will be separated - * using the given separator (defaults to '.') and by square brackets. - * - * @param input the jquery form to serialize. - * @param sep the object-property separator (defaults to '.'). - * @param dict a dictionary of names to replace (name=replace). - * - * @return the JSON-serialized form. - */ -form.serialize = function(input, sep, dict) { - var rval = {}; - - // add all fields in the form to the object - sep = sep || '.'; - $.each(input.serializeArray(), function() { - _addField(rval, this.name.split(sep), this.value || '', dict); - }); - - return rval; -}; - -/** - * The forge namespace and form API. - */ -if(typeof forge === 'undefined') { - forge = {}; -} -forge.form = form; - -})(jQuery); diff --git a/alarm/node_modules/node-forge/js/hmac.js b/alarm/node_modules/node-forge/js/hmac.js deleted file mode 100644 index eee58bc..0000000 --- a/alarm/node_modules/node-forge/js/hmac.js +++ /dev/null @@ -1,200 +0,0 @@ -/** - * Hash-based Message Authentication Code implementation. Requires a message - * digest object that can be obtained, for example, from forge.md.sha1 or - * forge.md.md5. - * - * @author Dave Longley - * - * Copyright (c) 2010-2012 Digital Bazaar, Inc. All rights reserved. - */ -(function() { -/* ########## Begin module implementation ########## */ -function initModule(forge) { - -/* HMAC API */ -var hmac = forge.hmac = forge.hmac || {}; - -/** - * Creates an HMAC object that uses the given message digest object. - * - * @return an HMAC object. - */ -hmac.create = function() { - // the hmac key to use - var _key = null; - - // the message digest to use - var _md = null; - - // the inner padding - var _ipadding = null; - - // the outer padding - var _opadding = null; - - // hmac context - var ctx = {}; - - /** - * Starts or restarts the HMAC with the given key and message digest. - * - * @param md the message digest to use, null to reuse the previous one, - * a string to use builtin 'sha1', 'md5', 'sha256'. - * @param key the key to use as a string, array of bytes, byte buffer, - * or null to reuse the previous key. - */ - ctx.start = function(md, key) { - if(md !== null) { - if(typeof md === 'string') { - // create builtin message digest - md = md.toLowerCase(); - if(md in forge.md.algorithms) { - _md = forge.md.algorithms[md].create(); - } else { - throw new Error('Unknown hash algorithm "' + md + '"'); - } - } else { - // store message digest - _md = md; - } - } - - if(key === null) { - // reuse previous key - key = _key; - } else { - if(typeof key === 'string') { - // convert string into byte buffer - key = forge.util.createBuffer(key); - } else if(forge.util.isArray(key)) { - // convert byte array into byte buffer - var tmp = key; - key = forge.util.createBuffer(); - for(var i = 0; i < tmp.length; ++i) { - key.putByte(tmp[i]); - } - } - - // if key is longer than blocksize, hash it - var keylen = key.length(); - if(keylen > _md.blockLength) { - _md.start(); - _md.update(key.bytes()); - key = _md.digest(); - } - - // mix key into inner and outer padding - // ipadding = [0x36 * blocksize] ^ key - // opadding = [0x5C * blocksize] ^ key - _ipadding = forge.util.createBuffer(); - _opadding = forge.util.createBuffer(); - keylen = key.length(); - for(var i = 0; i < keylen; ++i) { - var tmp = key.at(i); - _ipadding.putByte(0x36 ^ tmp); - _opadding.putByte(0x5C ^ tmp); - } - - // if key is shorter than blocksize, add additional padding - if(keylen < _md.blockLength) { - var tmp = _md.blockLength - keylen; - for(var i = 0; i < tmp; ++i) { - _ipadding.putByte(0x36); - _opadding.putByte(0x5C); - } - } - _key = key; - _ipadding = _ipadding.bytes(); - _opadding = _opadding.bytes(); - } - - // digest is done like so: hash(opadding | hash(ipadding | message)) - - // prepare to do inner hash - // hash(ipadding | message) - _md.start(); - _md.update(_ipadding); - }; - - /** - * Updates the HMAC with the given message bytes. - * - * @param bytes the bytes to update with. - */ - ctx.update = function(bytes) { - _md.update(bytes); - }; - - /** - * Produces the Message Authentication Code (MAC). - * - * @return a byte buffer containing the digest value. - */ - ctx.getMac = function() { - // digest is done like so: hash(opadding | hash(ipadding | message)) - // here we do the outer hashing - var inner = _md.digest().bytes(); - _md.start(); - _md.update(_opadding); - _md.update(inner); - return _md.digest(); - }; - // alias for getMac - ctx.digest = ctx.getMac; - - return ctx; -}; - -} // end module implementation - -/* ########## Begin module wrapper ########## */ -var name = 'hmac'; -if(typeof define !== 'function') { - // NodeJS -> AMD - if(typeof module === 'object' && module.exports) { - var nodeJS = true; - define = function(ids, factory) { - factory(require, module); - }; - } else { - // <script> - if(typeof forge === 'undefined') { - forge = {}; - } - return initModule(forge); - } -} -// AMD -var deps; -var defineFunc = function(require, module) { - module.exports = function(forge) { - var mods = deps.map(function(dep) { - return require(dep); - }).concat(initModule); - // handle circular dependencies - forge = forge || {}; - forge.defined = forge.defined || {}; - if(forge.defined[name]) { - return forge[name]; - } - forge.defined[name] = true; - for(var i = 0; i < mods.length; ++i) { - mods[i](forge); - } - return forge[name]; - }; -}; -var tmpDefine = define; -define = function(ids, factory) { - deps = (typeof ids === 'string') ? factory.slice(2) : ids.slice(2); - if(nodeJS) { - delete define; - return tmpDefine.apply(null, Array.prototype.slice.call(arguments, 0)); - } - define = tmpDefine; - return define.apply(null, Array.prototype.slice.call(arguments, 0)); -}; -define(['require', 'module', './md', './util'], function() { - defineFunc.apply(null, Array.prototype.slice.call(arguments, 0)); -}); -})(); diff --git a/alarm/node_modules/node-forge/js/http.js b/alarm/node_modules/node-forge/js/http.js deleted file mode 100644 index fa01aed..0000000 --- a/alarm/node_modules/node-forge/js/http.js +++ /dev/null @@ -1,1369 +0,0 @@ -/** - * HTTP client-side implementation that uses forge.net sockets. - * - * @author Dave Longley - * - * Copyright (c) 2010-2014 Digital Bazaar, Inc. All rights reserved. - */ -(function() { - -// define http namespace -var http = {}; - -// logging category -var cat = 'forge.http'; - -// add array of clients to debug storage -if(forge.debug) { - forge.debug.set('forge.http', 'clients', []); -} - -// normalizes an http header field name -var _normalize = function(name) { - return name.toLowerCase().replace(/(^.)|(-.)/g, - function(a){return a.toUpperCase();}); -}; - -/** - * Gets the local storage ID for the given client. - * - * @param client the client to get the local storage ID for. - * - * @return the local storage ID to use. - */ -var _getStorageId = function(client) { - // TODO: include browser in ID to avoid sharing cookies between - // browsers (if this is undesirable) - // navigator.userAgent - return 'forge.http.' + - client.url.scheme + '.' + - client.url.host + '.' + - client.url.port; -}; - -/** - * Loads persistent cookies from disk for the given client. - * - * @param client the client. - */ -var _loadCookies = function(client) { - if(client.persistCookies) { - try { - var cookies = forge.util.getItem( - client.socketPool.flashApi, - _getStorageId(client), 'cookies'); - client.cookies = cookies || {}; - } catch(ex) { - // no flash storage available, just silently fail - // TODO: i assume we want this logged somewhere or - // should it actually generate an error - //forge.log.error(cat, ex); - } - } -}; - -/** - * Saves persistent cookies on disk for the given client. - * - * @param client the client. - */ -var _saveCookies = function(client) { - if(client.persistCookies) { - try { - forge.util.setItem( - client.socketPool.flashApi, - _getStorageId(client), 'cookies', client.cookies); - } catch(ex) { - // no flash storage available, just silently fail - // TODO: i assume we want this logged somewhere or - // should it actually generate an error - //forge.log.error(cat, ex); - } - } - - // FIXME: remove me - _loadCookies(client); -}; - -/** - * Clears persistent cookies on disk for the given client. - * - * @param client the client. - */ -var _clearCookies = function(client) { - if(client.persistCookies) { - try { - // only thing stored is 'cookies', so clear whole storage - forge.util.clearItems( - client.socketPool.flashApi, - _getStorageId(client)); - } catch(ex) { - // no flash storage available, just silently fail - // TODO: i assume we want this logged somewhere or - // should it actually generate an error - //forge.log.error(cat, ex); - } - } -}; - -/** - * Connects and sends a request. - * - * @param client the http client. - * @param socket the socket to use. - */ -var _doRequest = function(client, socket) { - if(socket.isConnected()) { - // already connected - socket.options.request.connectTime = +new Date(); - socket.connected({ - type: 'connect', - id: socket.id - }); - } else { - // connect - socket.options.request.connectTime = +new Date(); - socket.connect({ - host: client.url.host, - port: client.url.port, - policyPort: client.policyPort, - policyUrl: client.policyUrl - }); - } -}; - -/** - * Handles the next request or marks a socket as idle. - * - * @param client the http client. - * @param socket the socket. - */ -var _handleNextRequest = function(client, socket) { - // clear buffer - socket.buffer.clear(); - - // get pending request - var pending = null; - while(pending === null && client.requests.length > 0) { - pending = client.requests.shift(); - if(pending.request.aborted) { - pending = null; - } - } - - // mark socket idle if no pending requests - if(pending === null) { - if(socket.options !== null) { - socket.options = null; - } - client.idle.push(socket); - } else { - // handle pending request, allow 1 retry - socket.retries = 1; - socket.options = pending; - _doRequest(client, socket); - } -}; - -/** - * Sets up a socket for use with an http client. - * - * @param client the parent http client. - * @param socket the socket to set up. - * @param tlsOptions if the socket must use TLS, the TLS options. - */ -var _initSocket = function(client, socket, tlsOptions) { - // no socket options yet - socket.options = null; - - // set up handlers - socket.connected = function(e) { - // socket primed by caching TLS session, handle next request - if(socket.options === null) { - _handleNextRequest(client, socket); - } else { - // socket in use - var request = socket.options.request; - request.connectTime = +new Date() - request.connectTime; - e.socket = socket; - socket.options.connected(e); - if(request.aborted) { - socket.close(); - } else { - var out = request.toString(); - if(request.body) { - out += request.body; - } - request.time = +new Date(); - socket.send(out); - request.time = +new Date() - request.time; - socket.options.response.time = +new Date(); - socket.sending = true; - } - } - }; - socket.closed = function(e) { - if(socket.sending) { - socket.sending = false; - if(socket.retries > 0) { - --socket.retries; - _doRequest(client, socket); - } else { - // error, closed during send - socket.error({ - id: socket.id, - type: 'ioError', - message: 'Connection closed during send. Broken pipe.', - bytesAvailable: 0 - }); - } - } else { - // handle unspecified content-length transfer - var response = socket.options.response; - if(response.readBodyUntilClose) { - response.time = +new Date() - response.time; - response.bodyReceived = true; - socket.options.bodyReady({ - request: socket.options.request, - response: response, - socket: socket - }); - } - socket.options.closed(e); - _handleNextRequest(client, socket); - } - }; - socket.data = function(e) { - socket.sending = false; - var request = socket.options.request; - if(request.aborted) { - socket.close(); - } else { - // receive all bytes available - var response = socket.options.response; - var bytes = socket.receive(e.bytesAvailable); - if(bytes !== null) { - // receive header and then body - socket.buffer.putBytes(bytes); - if(!response.headerReceived) { - response.readHeader(socket.buffer); - if(response.headerReceived) { - socket.options.headerReady({ - request: socket.options.request, - response: response, - socket: socket - }); - } - } - if(response.headerReceived && !response.bodyReceived) { - response.readBody(socket.buffer); - } - if(response.bodyReceived) { - socket.options.bodyReady({ - request: socket.options.request, - response: response, - socket: socket - }); - // close connection if requested or by default on http/1.0 - var value = response.getField('Connection') || ''; - if(value.indexOf('close') != -1 || - (response.version === 'HTTP/1.0' && - response.getField('Keep-Alive') === null)) { - socket.close(); - } else { - _handleNextRequest(client, socket); - } - } - } - } - }; - socket.error = function(e) { - // do error callback, include request - socket.options.error({ - type: e.type, - message: e.message, - request: socket.options.request, - response: socket.options.response, - socket: socket - }); - socket.close(); - }; - - // wrap socket for TLS - if(tlsOptions) { - socket = forge.tls.wrapSocket({ - sessionId: null, - sessionCache: {}, - caStore: tlsOptions.caStore, - cipherSuites: tlsOptions.cipherSuites, - socket: socket, - virtualHost: tlsOptions.virtualHost, - verify: tlsOptions.verify, - getCertificate: tlsOptions.getCertificate, - getPrivateKey: tlsOptions.getPrivateKey, - getSignature: tlsOptions.getSignature, - deflate: tlsOptions.deflate || null, - inflate: tlsOptions.inflate || null - }); - - socket.options = null; - socket.buffer = forge.util.createBuffer(); - client.sockets.push(socket); - if(tlsOptions.prime) { - // prime socket by connecting and caching TLS session, will do - // next request from there - socket.connect({ - host: client.url.host, - port: client.url.port, - policyPort: client.policyPort, - policyUrl: client.policyUrl - }); - } else { - // do not prime socket, just add as idle - client.idle.push(socket); - } - } else { - // no need to prime non-TLS sockets - socket.buffer = forge.util.createBuffer(); - client.sockets.push(socket); - client.idle.push(socket); - } -}; - -/** - * Checks to see if the given cookie has expired. If the cookie's max-age - * plus its created time is less than the time now, it has expired, unless - * its max-age is set to -1 which indicates it will never expire. - * - * @param cookie the cookie to check. - * - * @return true if it has expired, false if not. - */ -var _hasCookieExpired = function(cookie) { - var rval = false; - - if(cookie.maxAge !== -1) { - var now = _getUtcTime(new Date()); - var expires = cookie.created + cookie.maxAge; - if(expires <= now) { - rval = true; - } - } - - return rval; -}; - -/** - * Adds cookies in the given client to the given request. - * - * @param client the client. - * @param request the request. - */ -var _writeCookies = function(client, request) { - var expired = []; - var url = client.url; - var cookies = client.cookies; - for(var name in cookies) { - // get cookie paths - var paths = cookies[name]; - for(var p in paths) { - var cookie = paths[p]; - if(_hasCookieExpired(cookie)) { - // store for clean up - expired.push(cookie); - } else if(request.path.indexOf(cookie.path) === 0) { - // path or path's ancestor must match cookie.path - request.addCookie(cookie); - } - } - } - - // clean up expired cookies - for(var i = 0; i < expired.length; ++i) { - var cookie = expired[i]; - client.removeCookie(cookie.name, cookie.path); - } -}; - -/** - * Gets cookies from the given response and adds the to the given client. - * - * @param client the client. - * @param response the response. - */ -var _readCookies = function(client, response) { - var cookies = response.getCookies(); - for(var i = 0; i < cookies.length; ++i) { - try { - client.setCookie(cookies[i]); - } catch(ex) { - // ignore failure to add other-domain, etc. cookies - } - } -}; - -/** - * Creates an http client that uses forge.net sockets as a backend and - * forge.tls for security. - * - * @param options: - * url: the url to connect to (scheme://host:port). - * socketPool: the flash socket pool to use. - * policyPort: the flash policy port to use (if other than the - * socket pool default), use 0 for flash default. - * policyUrl: the flash policy file URL to use (if provided will - * be used instead of a policy port). - * connections: number of connections to use to handle requests. - * caCerts: an array of certificates to trust for TLS, certs may - * be PEM-formatted or cert objects produced via forge.pki. - * cipherSuites: an optional array of cipher suites to use, - * see forge.tls.CipherSuites. - * virtualHost: the virtual server name to use in a TLS SNI - * extension, if not provided the url host will be used. - * verify: a custom TLS certificate verify callback to use. - * getCertificate: an optional callback used to get a client-side - * certificate (see forge.tls for details). - * getPrivateKey: an optional callback used to get a client-side - * private key (see forge.tls for details). - * getSignature: an optional callback used to get a client-side - * signature (see forge.tls for details). - * persistCookies: true to use persistent cookies via flash local - * storage, false to only keep cookies in javascript. - * primeTlsSockets: true to immediately connect TLS sockets on - * their creation so that they will cache TLS sessions for reuse. - * - * @return the client. - */ -http.createClient = function(options) { - // create CA store to share with all TLS connections - var caStore = null; - if(options.caCerts) { - caStore = forge.pki.createCaStore(options.caCerts); - } - - // get scheme, host, and port from url - options.url = (options.url || - window.location.protocol + '//' + window.location.host); - var url = http.parseUrl(options.url); - if(!url) { - var error = new Error('Invalid url.'); - error.details = {url: options.url}; - throw error; - } - - // default to 1 connection - options.connections = options.connections || 1; - - // create client - var sp = options.socketPool; - var client = { - // url - url: url, - // socket pool - socketPool: sp, - // the policy port to use - policyPort: options.policyPort, - // policy url to use - policyUrl: options.policyUrl, - // queue of requests to service - requests: [], - // all sockets - sockets: [], - // idle sockets - idle: [], - // whether or not the connections are secure - secure: (url.scheme === 'https'), - // cookie jar (key'd off of name and then path, there is only 1 domain - // and one setting for secure per client so name+path is unique) - cookies: {}, - // default to flash storage of cookies - persistCookies: (typeof(options.persistCookies) === 'undefined') ? - true : options.persistCookies - }; - - // add client to debug storage - if(forge.debug) { - forge.debug.get('forge.http', 'clients').push(client); - } - - // load cookies from disk - _loadCookies(client); - - /** - * A default certificate verify function that checks a certificate common - * name against the client's URL host. - * - * @param c the TLS connection. - * @param verified true if cert is verified, otherwise alert number. - * @param depth the chain depth. - * @param certs the cert chain. - * - * @return true if verified and the common name matches the host, error - * otherwise. - */ - var _defaultCertificateVerify = function(c, verified, depth, certs) { - if(depth === 0 && verified === true) { - // compare common name to url host - var cn = certs[depth].subject.getField('CN'); - if(cn === null || client.url.host !== cn.value) { - verified = { - message: 'Certificate common name does not match url host.' - }; - } - } - return verified; - }; - - // determine if TLS is used - var tlsOptions = null; - if(client.secure) { - tlsOptions = { - caStore: caStore, - cipherSuites: options.cipherSuites || null, - virtualHost: options.virtualHost || url.host, - verify: options.verify || _defaultCertificateVerify, - getCertificate: options.getCertificate || null, - getPrivateKey: options.getPrivateKey || null, - getSignature: options.getSignature || null, - prime: options.primeTlsSockets || false - }; - - // if socket pool uses a flash api, then add deflate support to TLS - if(sp.flashApi !== null) { - tlsOptions.deflate = function(bytes) { - // strip 2 byte zlib header and 4 byte trailer - return forge.util.deflate(sp.flashApi, bytes, true); - }; - tlsOptions.inflate = function(bytes) { - return forge.util.inflate(sp.flashApi, bytes, true); - }; - } - } - - // create and initialize sockets - for(var i = 0; i < options.connections; ++i) { - _initSocket(client, sp.createSocket(), tlsOptions); - } - - /** - * Sends a request. A method 'abort' will be set on the request that - * can be called to attempt to abort the request. - * - * @param options: - * request: the request to send. - * connected: a callback for when the connection is open. - * closed: a callback for when the connection is closed. - * headerReady: a callback for when the response header arrives. - * bodyReady: a callback for when the response body arrives. - * error: a callback for if an error occurs. - */ - client.send = function(options) { - // add host header if not set - if(options.request.getField('Host') === null) { - options.request.setField('Host', client.url.fullHost); - } - - // set default dummy handlers - var opts = {}; - opts.request = options.request; - opts.connected = options.connected || function(){}; - opts.closed = options.close || function(){}; - opts.headerReady = function(e) { - // read cookies - _readCookies(client, e.response); - if(options.headerReady) { - options.headerReady(e); - } - }; - opts.bodyReady = options.bodyReady || function(){}; - opts.error = options.error || function(){}; - - // create response - opts.response = http.createResponse(); - opts.response.time = 0; - opts.response.flashApi = client.socketPool.flashApi; - opts.request.flashApi = client.socketPool.flashApi; - - // create abort function - opts.request.abort = function() { - // set aborted, clear handlers - opts.request.aborted = true; - opts.connected = function(){}; - opts.closed = function(){}; - opts.headerReady = function(){}; - opts.bodyReady = function(){}; - opts.error = function(){}; - }; - - // add cookies to request - _writeCookies(client, opts.request); - - // queue request options if there are no idle sockets - if(client.idle.length === 0) { - client.requests.push(opts); - } else { - // use an idle socket, prefer an idle *connected* socket first - var socket = null; - var len = client.idle.length; - for(var i = 0; socket === null && i < len; ++i) { - socket = client.idle[i]; - if(socket.isConnected()) { - client.idle.splice(i, 1); - } else { - socket = null; - } - } - // no connected socket available, get unconnected socket - if(socket === null) { - socket = client.idle.pop(); - } - socket.options = opts; - _doRequest(client, socket); - } - }; - - /** - * Destroys this client. - */ - client.destroy = function() { - // clear pending requests, close and destroy sockets - client.requests = []; - for(var i = 0; i < client.sockets.length; ++i) { - client.sockets[i].close(); - client.sockets[i].destroy(); - } - client.socketPool = null; - client.sockets = []; - client.idle = []; - }; - - /** - * Sets a cookie for use with all connections made by this client. Any - * cookie with the same name will be replaced. If the cookie's value - * is undefined, null, or the blank string, the cookie will be removed. - * - * If the cookie's domain doesn't match this client's url host or the - * cookie's secure flag doesn't match this client's url scheme, then - * setting the cookie will fail with an exception. - * - * @param cookie the cookie with parameters: - * name: the name of the cookie. - * value: the value of the cookie. - * comment: an optional comment string. - * maxAge: the age of the cookie in seconds relative to created time. - * secure: true if the cookie must be sent over a secure protocol. - * httpOnly: true to restrict access to the cookie from javascript - * (inaffective since the cookies are stored in javascript). - * path: the path for the cookie. - * domain: optional domain the cookie belongs to (must start with dot). - * version: optional version of the cookie. - * created: creation time, in UTC seconds, of the cookie. - */ - client.setCookie = function(cookie) { - var rval; - if(typeof(cookie.name) !== 'undefined') { - if(cookie.value === null || typeof(cookie.value) === 'undefined' || - cookie.value === '') { - // remove cookie - rval = client.removeCookie(cookie.name, cookie.path); - } else { - // set cookie defaults - cookie.comment = cookie.comment || ''; - cookie.maxAge = cookie.maxAge || 0; - cookie.secure = (typeof(cookie.secure) === 'undefined') ? - true : cookie.secure; - cookie.httpOnly = cookie.httpOnly || true; - cookie.path = cookie.path || '/'; - cookie.domain = cookie.domain || null; - cookie.version = cookie.version || null; - cookie.created = _getUtcTime(new Date()); - - // do secure check - if(cookie.secure !== client.secure) { - var error = new Error('Http client url scheme is incompatible ' + - 'with cookie secure flag.'); - error.url = client.url; - error.cookie = cookie; - throw error; - } - // make sure url host is within cookie.domain - if(!http.withinCookieDomain(client.url, cookie)) { - var error = new Error('Http client url scheme is incompatible ' + - 'with cookie secure flag.'); - error.url = client.url; - error.cookie = cookie; - throw error; - } - - // add new cookie - if(!(cookie.name in client.cookies)) { - client.cookies[cookie.name] = {}; - } - client.cookies[cookie.name][cookie.path] = cookie; - rval = true; - - // save cookies - _saveCookies(client); - } - } - - return rval; - }; - - /** - * Gets a cookie by its name. - * - * @param name the name of the cookie to retrieve. - * @param path an optional path for the cookie (if there are multiple - * cookies with the same name but different paths). - * - * @return the cookie or null if not found. - */ - client.getCookie = function(name, path) { - var rval = null; - if(name in client.cookies) { - var paths = client.cookies[name]; - - // get path-specific cookie - if(path) { - if(path in paths) { - rval = paths[path]; - } - } else { - // get first cookie - for(var p in paths) { - rval = paths[p]; - break; - } - } - } - return rval; - }; - - /** - * Removes a cookie. - * - * @param name the name of the cookie to remove. - * @param path an optional path for the cookie (if there are multiple - * cookies with the same name but different paths). - * - * @return true if a cookie was removed, false if not. - */ - client.removeCookie = function(name, path) { - var rval = false; - if(name in client.cookies) { - // delete the specific path - if(path) { - var paths = client.cookies[name]; - if(path in paths) { - rval = true; - delete client.cookies[name][path]; - // clean up entry if empty - var empty = true; - for(var i in client.cookies[name]) { - empty = false; - break; - } - if(empty) { - delete client.cookies[name]; - } - } - } else { - // delete all cookies with the given name - rval = true; - delete client.cookies[name]; - } - } - if(rval) { - // save cookies - _saveCookies(client); - } - return rval; - }; - - /** - * Clears all cookies stored in this client. - */ - client.clearCookies = function() { - client.cookies = {}; - _clearCookies(client); - }; - - if(forge.log) { - forge.log.debug('forge.http', 'created client', options); - } - - return client; -}; - -/** - * Trims the whitespace off of the beginning and end of a string. - * - * @param str the string to trim. - * - * @return the trimmed string. - */ -var _trimString = function(str) { - return str.replace(/^\s*/, '').replace(/\s*$/, ''); -}; - -/** - * Creates an http header object. - * - * @return the http header object. - */ -var _createHeader = function() { - var header = { - fields: {}, - setField: function(name, value) { - // normalize field name, trim value - header.fields[_normalize(name)] = [_trimString('' + value)]; - }, - appendField: function(name, value) { - name = _normalize(name); - if(!(name in header.fields)) { - header.fields[name] = []; - } - header.fields[name].push(_trimString('' + value)); - }, - getField: function(name, index) { - var rval = null; - name = _normalize(name); - if(name in header.fields) { - index = index || 0; - rval = header.fields[name][index]; - } - return rval; - } - }; - return header; -}; - -/** - * Gets the time in utc seconds given a date. - * - * @param d the date to use. - * - * @return the time in utc seconds. - */ -var _getUtcTime = function(d) { - var utc = +d + d.getTimezoneOffset() * 60000; - return Math.floor(+new Date() / 1000); -}; - -/** - * Creates an http request. - * - * @param options: - * version: the version. - * method: the method. - * path: the path. - * body: the body. - * headers: custom header fields to add, - * eg: [{'Content-Length': 0}]. - * - * @return the http request. - */ -http.createRequest = function(options) { - options = options || {}; - var request = _createHeader(); - request.version = options.version || 'HTTP/1.1'; - request.method = options.method || null; - request.path = options.path || null; - request.body = options.body || null; - request.bodyDeflated = false; - request.flashApi = null; - - // add custom headers - var headers = options.headers || []; - if(!forge.util.isArray(headers)) { - headers = [headers]; - } - for(var i = 0; i < headers.length; ++i) { - for(var name in headers[i]) { - request.appendField(name, headers[i][name]); - } - } - - /** - * Adds a cookie to the request 'Cookie' header. - * - * @param cookie a cookie to add. - */ - request.addCookie = function(cookie) { - var value = ''; - var field = request.getField('Cookie'); - if(field !== null) { - // separate cookies by semi-colons - value = field + '; '; - } - - // get current time in utc seconds - var now = _getUtcTime(new Date()); - - // output cookie name and value - value += cookie.name + '=' + cookie.value; - request.setField('Cookie', value); - }; - - /** - * Converts an http request into a string that can be sent as an - * HTTP request. Does not include any data. - * - * @return the string representation of the request. - */ - request.toString = function() { - /* Sample request header: - GET /some/path/?query HTTP/1.1 - Host: www.someurl.com - Connection: close - Accept-Encoding: deflate - Accept: image/gif, text/html - User-Agent: Mozilla 4.0 - */ - - // set default headers - if(request.getField('User-Agent') === null) { - request.setField('User-Agent', 'forge.http 1.0'); - } - if(request.getField('Accept') === null) { - request.setField('Accept', '*/*'); - } - if(request.getField('Connection') === null) { - request.setField('Connection', 'keep-alive'); - request.setField('Keep-Alive', '115'); - } - - // add Accept-Encoding if not specified - if(request.flashApi !== null && - request.getField('Accept-Encoding') === null) { - request.setField('Accept-Encoding', 'deflate'); - } - - // if the body isn't null, deflate it if its larger than 100 bytes - if(request.flashApi !== null && request.body !== null && - request.getField('Content-Encoding') === null && - !request.bodyDeflated && request.body.length > 100) { - // use flash to compress data - request.body = forge.util.deflate(request.flashApi, request.body); - request.bodyDeflated = true; - request.setField('Content-Encoding', 'deflate'); - request.setField('Content-Length', request.body.length); - } else if(request.body !== null) { - // set content length for body - request.setField('Content-Length', request.body.length); - } - - // build start line - var rval = - request.method.toUpperCase() + ' ' + request.path + ' ' + - request.version + '\r\n'; - - // add each header - for(var name in request.fields) { - var fields = request.fields[name]; - for(var i = 0; i < fields.length; ++i) { - rval += name + ': ' + fields[i] + '\r\n'; - } - } - // final terminating CRLF - rval += '\r\n'; - - return rval; - }; - - return request; -}; - -/** - * Creates an empty http response header. - * - * @return the empty http response header. - */ -http.createResponse = function() { - // private vars - var _first = true; - var _chunkSize = 0; - var _chunksFinished = false; - - // create response - var response = _createHeader(); - response.version = null; - response.code = 0; - response.message = null; - response.body = null; - response.headerReceived = false; - response.bodyReceived = false; - response.flashApi = null; - - /** - * Reads a line that ends in CRLF from a byte buffer. - * - * @param b the byte buffer. - * - * @return the line or null if none was found. - */ - var _readCrlf = function(b) { - var line = null; - var i = b.data.indexOf('\r\n', b.read); - if(i != -1) { - // read line, skip CRLF - line = b.getBytes(i - b.read); - b.getBytes(2); - } - return line; - }; - - /** - * Parses a header field and appends it to the response. - * - * @param line the header field line. - */ - var _parseHeader = function(line) { - var tmp = line.indexOf(':'); - var name = line.substring(0, tmp++); - response.appendField( - name, (tmp < line.length) ? line.substring(tmp) : ''); - }; - - /** - * Reads an http response header from a buffer of bytes. - * - * @param b the byte buffer to parse the header from. - * - * @return true if the whole header was read, false if not. - */ - response.readHeader = function(b) { - // read header lines (each ends in CRLF) - var line = ''; - while(!response.headerReceived && line !== null) { - line = _readCrlf(b); - if(line !== null) { - // parse first line - if(_first) { - _first = false; - var tmp = line.split(' '); - if(tmp.length >= 3) { - response.version = tmp[0]; - response.code = parseInt(tmp[1], 10); - response.message = tmp.slice(2).join(' '); - } else { - // invalid header - var error = new Error('Invalid http response header.'); - error.details = {'line': line}; - throw error; - } - } else if(line.length === 0) { - // handle final line, end of header - response.headerReceived = true; - } else { - _parseHeader(line); - } - } - } - - return response.headerReceived; - }; - - /** - * Reads some chunked http response entity-body from the given buffer of - * bytes. - * - * @param b the byte buffer to read from. - * - * @return true if the whole body was read, false if not. - */ - var _readChunkedBody = function(b) { - /* Chunked transfer-encoding sends data in a series of chunks, - followed by a set of 0-N http trailers. - The format is as follows: - - chunk-size (in hex) CRLF - chunk data (with "chunk-size" many bytes) CRLF - ... (N many chunks) - chunk-size (of 0 indicating the last chunk) CRLF - N many http trailers followed by CRLF - blank line + CRLF (terminates the trailers) - - If there are no http trailers, then after the chunk-size of 0, - there is still a single CRLF (indicating the blank line + CRLF - that terminates the trailers). In other words, you always terminate - the trailers with blank line + CRLF, regardless of 0-N trailers. */ - - /* From RFC-2616, section 3.6.1, here is the pseudo-code for - implementing chunked transfer-encoding: - - length := 0 - read chunk-size, chunk-extension (if any) and CRLF - while (chunk-size > 0) { - read chunk-data and CRLF - append chunk-data to entity-body - length := length + chunk-size - read chunk-size and CRLF - } - read entity-header - while (entity-header not empty) { - append entity-header to existing header fields - read entity-header - } - Content-Length := length - Remove "chunked" from Transfer-Encoding - */ - - var line = ''; - while(line !== null && b.length() > 0) { - // if in the process of reading a chunk - if(_chunkSize > 0) { - // if there are not enough bytes to read chunk and its - // trailing CRLF, we must wait for more data to be received - if(_chunkSize + 2 > b.length()) { - break; - } - - // read chunk data, skip CRLF - response.body += b.getBytes(_chunkSize); - b.getBytes(2); - _chunkSize = 0; - } else if(!_chunksFinished) { - // more chunks, read next chunk-size line - line = _readCrlf(b); - if(line !== null) { - // parse chunk-size (ignore any chunk extension) - _chunkSize = parseInt(line.split(';', 1)[0], 16); - _chunksFinished = (_chunkSize === 0); - } - } else { - // chunks finished, read next trailer - line = _readCrlf(b); - while(line !== null) { - if(line.length > 0) { - // parse trailer - _parseHeader(line); - // read next trailer - line = _readCrlf(b); - } else { - // body received - response.bodyReceived = true; - line = null; - } - } - } - } - - return response.bodyReceived; - }; - - /** - * Reads an http response body from a buffer of bytes. - * - * @param b the byte buffer to read from. - * - * @return true if the whole body was read, false if not. - */ - response.readBody = function(b) { - var contentLength = response.getField('Content-Length'); - var transferEncoding = response.getField('Transfer-Encoding'); - if(contentLength !== null) { - contentLength = parseInt(contentLength); - } - - // read specified length - if(contentLength !== null && contentLength >= 0) { - response.body = response.body || ''; - response.body += b.getBytes(contentLength); - response.bodyReceived = (response.body.length === contentLength); - } else if(transferEncoding !== null) { - // read chunked encoding - if(transferEncoding.indexOf('chunked') != -1) { - response.body = response.body || ''; - _readChunkedBody(b); - } else { - var error = new Error('Unknown Transfer-Encoding.'); - error.details = {'transferEncoding': transferEncoding}; - throw error; - } - } else if((contentLength !== null && contentLength < 0) || - (contentLength === null && - response.getField('Content-Type') !== null)) { - // read all data in the buffer - response.body = response.body || ''; - response.body += b.getBytes(); - response.readBodyUntilClose = true; - } else { - // no body - response.body = null; - response.bodyReceived = true; - } - - if(response.bodyReceived) { - response.time = +new Date() - response.time; - } - - if(response.flashApi !== null && - response.bodyReceived && response.body !== null && - response.getField('Content-Encoding') === 'deflate') { - // inflate using flash api - response.body = forge.util.inflate( - response.flashApi, response.body); - } - - return response.bodyReceived; - }; - - /** - * Parses an array of cookies from the 'Set-Cookie' field, if present. - * - * @return the array of cookies. - */ - response.getCookies = function() { - var rval = []; - - // get Set-Cookie field - if('Set-Cookie' in response.fields) { - var field = response.fields['Set-Cookie']; - - // get current local time in seconds - var now = +new Date() / 1000; - - // regex for parsing 'name1=value1; name2=value2; name3' - var regex = /\s*([^=]*)=?([^;]*)(;|$)/g; - - // examples: - // Set-Cookie: cookie1_name=cookie1_value; max-age=0; path=/ - // Set-Cookie: c2=v2; expires=Thu, 21-Aug-2008 23:47:25 GMT; path=/ - for(var i = 0; i < field.length; ++i) { - var fv = field[i]; - var m; - regex.lastIndex = 0; - var first = true; - var cookie = {}; - do { - m = regex.exec(fv); - if(m !== null) { - var name = _trimString(m[1]); - var value = _trimString(m[2]); - - // cookie_name=value - if(first) { - cookie.name = name; - cookie.value = value; - first = false; - } else { - // property_name=value - name = name.toLowerCase(); - switch(name) { - case 'expires': - // replace hyphens w/spaces so date will parse - value = value.replace(/-/g, ' '); - var secs = Date.parse(value) / 1000; - cookie.maxAge = Math.max(0, secs - now); - break; - case 'max-age': - cookie.maxAge = parseInt(value, 10); - break; - case 'secure': - cookie.secure = true; - break; - case 'httponly': - cookie.httpOnly = true; - break; - default: - if(name !== '') { - cookie[name] = value; - } - } - } - } - } while(m !== null && m[0] !== ''); - rval.push(cookie); - } - } - - return rval; - }; - - /** - * Converts an http response into a string that can be sent as an - * HTTP response. Does not include any data. - * - * @return the string representation of the response. - */ - response.toString = function() { - /* Sample response header: - HTTP/1.0 200 OK - Host: www.someurl.com - Connection: close - */ - - // build start line - var rval = - response.version + ' ' + response.code + ' ' + response.message + '\r\n'; - - // add each header - for(var name in response.fields) { - var fields = response.fields[name]; - for(var i = 0; i < fields.length; ++i) { - rval += name + ': ' + fields[i] + '\r\n'; - } - } - // final terminating CRLF - rval += '\r\n'; - - return rval; - }; - - return response; -}; - -/** - * Parses the scheme, host, and port from an http(s) url. - * - * @param str the url string. - * - * @return the parsed url object or null if the url is invalid. - */ -http.parseUrl = forge.util.parseUrl; - -/** - * Returns true if the given url is within the given cookie's domain. - * - * @param url the url to check. - * @param cookie the cookie or cookie domain to check. - */ -http.withinCookieDomain = function(url, cookie) { - var rval = false; - - // cookie may be null, a cookie object, or a domain string - var domain = (cookie === null || typeof cookie === 'string') ? - cookie : cookie.domain; - - // any domain will do - if(domain === null) { - rval = true; - } else if(domain.charAt(0) === '.') { - // ensure domain starts with a '.' - // parse URL as necessary - if(typeof url === 'string') { - url = http.parseUrl(url); - } - - // add '.' to front of URL host to match against domain - var host = '.' + url.host; - - // if the host ends with domain then it falls within it - var idx = host.lastIndexOf(domain); - if(idx !== -1 && (idx + domain.length === host.length)) { - rval = true; - } - } - - return rval; -}; - -// public access to http namespace -if(typeof forge === 'undefined') { - forge = {}; -} -forge.http = http; - -})(); diff --git a/alarm/node_modules/node-forge/js/jsbn.js b/alarm/node_modules/node-forge/js/jsbn.js deleted file mode 100644 index 6510139..0000000 --- a/alarm/node_modules/node-forge/js/jsbn.js +++ /dev/null @@ -1,1321 +0,0 @@ -// Copyright (c) 2005 Tom Wu -// All Rights Reserved. -// See "LICENSE" for details. - -// Basic JavaScript BN library - subset useful for RSA encryption. - -/* -Licensing (LICENSE) -------------------- - -This software is covered under the following copyright: -*/ -/* - * Copyright (c) 2003-2005 Tom Wu - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * 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. - * - * In addition, the following condition applies: - * - * All redistributions must retain an intact copy of this copyright notice - * and disclaimer. - */ -/* -Address all questions regarding this license to: - - Tom Wu - tjw@cs.Stanford.EDU -*/ - -(function() { -/* ########## Begin module implementation ########## */ -function initModule(forge) { - -// Bits per digit -var dbits; - -// JavaScript engine analysis -var canary = 0xdeadbeefcafe; -var j_lm = ((canary&0xffffff)==0xefcafe); - -// (public) Constructor -function BigInteger(a,b,c) { - this.data = []; - if(a != null) - if("number" == typeof a) this.fromNumber(a,b,c); - else if(b == null && "string" != typeof a) this.fromString(a,256); - else this.fromString(a,b); -} - -// return new, unset BigInteger -function nbi() { return new BigInteger(null); } - -// am: Compute w_j += (x*this_i), propagate carries, -// c is initial carry, returns final carry. -// c < 3*dvalue, x < 2*dvalue, this_i < dvalue -// We need to select the fastest one that works in this environment. - -// am1: use a single mult and divide to get the high bits, -// max digit bits should be 26 because -// max internal value = 2*dvalue^2-2*dvalue (< 2^53) -function am1(i,x,w,j,c,n) { - while(--n >= 0) { - var v = x*this.data[i++]+w.data[j]+c; - c = Math.floor(v/0x4000000); - w.data[j++] = v&0x3ffffff; - } - return c; -} -// am2 avoids a big mult-and-extract completely. -// Max digit bits should be <= 30 because we do bitwise ops -// on values up to 2*hdvalue^2-hdvalue-1 (< 2^31) -function am2(i,x,w,j,c,n) { - var xl = x&0x7fff, xh = x>>15; - while(--n >= 0) { - var l = this.data[i]&0x7fff; - var h = this.data[i++]>>15; - var m = xh*l+h*xl; - l = xl*l+((m&0x7fff)<<15)+w.data[j]+(c&0x3fffffff); - c = (l>>>30)+(m>>>15)+xh*h+(c>>>30); - w.data[j++] = l&0x3fffffff; - } - return c; -} -// Alternately, set max digit bits to 28 since some -// browsers slow down when dealing with 32-bit numbers. -function am3(i,x,w,j,c,n) { - var xl = x&0x3fff, xh = x>>14; - while(--n >= 0) { - var l = this.data[i]&0x3fff; - var h = this.data[i++]>>14; - var m = xh*l+h*xl; - l = xl*l+((m&0x3fff)<<14)+w.data[j]+c; - c = (l>>28)+(m>>14)+xh*h; - w.data[j++] = l&0xfffffff; - } - return c; -} - -// node.js (no browser) -if(typeof(navigator) === 'undefined') -{ - BigInteger.prototype.am = am3; - dbits = 28; -} else if(j_lm && (navigator.appName == "Microsoft Internet Explorer")) { - BigInteger.prototype.am = am2; - dbits = 30; -} else if(j_lm && (navigator.appName != "Netscape")) { - BigInteger.prototype.am = am1; - dbits = 26; -} else { // Mozilla/Netscape seems to prefer am3 - BigInteger.prototype.am = am3; - dbits = 28; -} - -BigInteger.prototype.DB = dbits; -BigInteger.prototype.DM = ((1<<dbits)-1); -BigInteger.prototype.DV = (1<<dbits); - -var BI_FP = 52; -BigInteger.prototype.FV = Math.pow(2,BI_FP); -BigInteger.prototype.F1 = BI_FP-dbits; -BigInteger.prototype.F2 = 2*dbits-BI_FP; - -// Digit conversions -var BI_RM = "0123456789abcdefghijklmnopqrstuvwxyz"; -var BI_RC = new Array(); -var rr,vv; -rr = "0".charCodeAt(0); -for(vv = 0; vv <= 9; ++vv) BI_RC[rr++] = vv; -rr = "a".charCodeAt(0); -for(vv = 10; vv < 36; ++vv) BI_RC[rr++] = vv; -rr = "A".charCodeAt(0); -for(vv = 10; vv < 36; ++vv) BI_RC[rr++] = vv; - -function int2char(n) { return BI_RM.charAt(n); } -function intAt(s,i) { - var c = BI_RC[s.charCodeAt(i)]; - return (c==null)?-1:c; -} - -// (protected) copy this to r -function bnpCopyTo(r) { - for(var i = this.t-1; i >= 0; --i) r.data[i] = this.data[i]; - r.t = this.t; - r.s = this.s; -} - -// (protected) set from integer value x, -DV <= x < DV -function bnpFromInt(x) { - this.t = 1; - this.s = (x<0)?-1:0; - if(x > 0) this.data[0] = x; - else if(x < -1) this.data[0] = x+this.DV; - else this.t = 0; -} - -// return bigint initialized to value -function nbv(i) { var r = nbi(); r.fromInt(i); return r; } - -// (protected) set from string and radix -function bnpFromString(s,b) { - var k; - if(b == 16) k = 4; - else if(b == 8) k = 3; - else if(b == 256) k = 8; // byte array - else if(b == 2) k = 1; - else if(b == 32) k = 5; - else if(b == 4) k = 2; - else { this.fromRadix(s,b); return; } - this.t = 0; - this.s = 0; - var i = s.length, mi = false, sh = 0; - while(--i >= 0) { - var x = (k==8)?s[i]&0xff:intAt(s,i); - if(x < 0) { - if(s.charAt(i) == "-") mi = true; - continue; - } - mi = false; - if(sh == 0) - this.data[this.t++] = x; - else if(sh+k > this.DB) { - this.data[this.t-1] |= (x&((1<<(this.DB-sh))-1))<<sh; - this.data[this.t++] = (x>>(this.DB-sh)); - } else - this.data[this.t-1] |= x<<sh; - sh += k; - if(sh >= this.DB) sh -= this.DB; - } - if(k == 8 && (s[0]&0x80) != 0) { - this.s = -1; - if(sh > 0) this.data[this.t-1] |= ((1<<(this.DB-sh))-1)<<sh; - } - this.clamp(); - if(mi) BigInteger.ZERO.subTo(this,this); -} - -// (protected) clamp off excess high words -function bnpClamp() { - var c = this.s&this.DM; - while(this.t > 0 && this.data[this.t-1] == c) --this.t; -} - -// (public) return string representation in given radix -function bnToString(b) { - if(this.s < 0) return "-"+this.negate().toString(b); - var k; - if(b == 16) k = 4; - else if(b == 8) k = 3; - else if(b == 2) k = 1; - else if(b == 32) k = 5; - else if(b == 4) k = 2; - else return this.toRadix(b); - var km = (1<<k)-1, d, m = false, r = "", i = this.t; - var p = this.DB-(i*this.DB)%k; - if(i-- > 0) { - if(p < this.DB && (d = this.data[i]>>p) > 0) { m = true; r = int2char(d); } - while(i >= 0) { - if(p < k) { - d = (this.data[i]&((1<<p)-1))<<(k-p); - d |= this.data[--i]>>(p+=this.DB-k); - } else { - d = (this.data[i]>>(p-=k))&km; - if(p <= 0) { p += this.DB; --i; } - } - if(d > 0) m = true; - if(m) r += int2char(d); - } - } - return m?r:"0"; -} - -// (public) -this -function bnNegate() { var r = nbi(); BigInteger.ZERO.subTo(this,r); return r; } - -// (public) |this| -function bnAbs() { return (this.s<0)?this.negate():this; } - -// (public) return + if this > a, - if this < a, 0 if equal -function bnCompareTo(a) { - var r = this.s-a.s; - if(r != 0) return r; - var i = this.t; - r = i-a.t; - if(r != 0) return (this.s<0)?-r:r; - while(--i >= 0) if((r=this.data[i]-a.data[i]) != 0) return r; - return 0; -} - -// returns bit length of the integer x -function nbits(x) { - var r = 1, t; - if((t=x>>>16) != 0) { x = t; r += 16; } - if((t=x>>8) != 0) { x = t; r += 8; } - if((t=x>>4) != 0) { x = t; r += 4; } - if((t=x>>2) != 0) { x = t; r += 2; } - if((t=x>>1) != 0) { x = t; r += 1; } - return r; -} - -// (public) return the number of bits in "this" -function bnBitLength() { - if(this.t <= 0) return 0; - return this.DB*(this.t-1)+nbits(this.data[this.t-1]^(this.s&this.DM)); -} - -// (protected) r = this << n*DB -function bnpDLShiftTo(n,r) { - var i; - for(i = this.t-1; i >= 0; --i) r.data[i+n] = this.data[i]; - for(i = n-1; i >= 0; --i) r.data[i] = 0; - r.t = this.t+n; - r.s = this.s; -} - -// (protected) r = this >> n*DB -function bnpDRShiftTo(n,r) { - for(var i = n; i < this.t; ++i) r.data[i-n] = this.data[i]; - r.t = Math.max(this.t-n,0); - r.s = this.s; -} - -// (protected) r = this << n -function bnpLShiftTo(n,r) { - var bs = n%this.DB; - var cbs = this.DB-bs; - var bm = (1<<cbs)-1; - var ds = Math.floor(n/this.DB), c = (this.s<<bs)&this.DM, i; - for(i = this.t-1; i >= 0; --i) { - r.data[i+ds+1] = (this.data[i]>>cbs)|c; - c = (this.data[i]&bm)<<bs; - } - for(i = ds-1; i >= 0; --i) r.data[i] = 0; - r.data[ds] = c; - r.t = this.t+ds+1; - r.s = this.s; - r.clamp(); -} - -// (protected) r = this >> n -function bnpRShiftTo(n,r) { - r.s = this.s; - var ds = Math.floor(n/this.DB); - if(ds >= this.t) { r.t = 0; return; } - var bs = n%this.DB; - var cbs = this.DB-bs; - var bm = (1<<bs)-1; - r.data[0] = this.data[ds]>>bs; - for(var i = ds+1; i < this.t; ++i) { - r.data[i-ds-1] |= (this.data[i]&bm)<<cbs; - r.data[i-ds] = this.data[i]>>bs; - } - if(bs > 0) r.data[this.t-ds-1] |= (this.s&bm)<<cbs; - r.t = this.t-ds; - r.clamp(); -} - -// (protected) r = this - a -function bnpSubTo(a,r) { - var i = 0, c = 0, m = Math.min(a.t,this.t); - while(i < m) { - c += this.data[i]-a.data[i]; - r.data[i++] = c&this.DM; - c >>= this.DB; - } - if(a.t < this.t) { - c -= a.s; - while(i < this.t) { - c += this.data[i]; - r.data[i++] = c&this.DM; - c >>= this.DB; - } - c += this.s; - } else { - c += this.s; - while(i < a.t) { - c -= a.data[i]; - r.data[i++] = c&this.DM; - c >>= this.DB; - } - c -= a.s; - } - r.s = (c<0)?-1:0; - if(c < -1) r.data[i++] = this.DV+c; - else if(c > 0) r.data[i++] = c; - r.t = i; - r.clamp(); -} - -// (protected) r = this * a, r != this,a (HAC 14.12) -// "this" should be the larger one if appropriate. -function bnpMultiplyTo(a,r) { - var x = this.abs(), y = a.abs(); - var i = x.t; - r.t = i+y.t; - while(--i >= 0) r.data[i] = 0; - for(i = 0; i < y.t; ++i) r.data[i+x.t] = x.am(0,y.data[i],r,i,0,x.t); - r.s = 0; - r.clamp(); - if(this.s != a.s) BigInteger.ZERO.subTo(r,r); -} - -// (protected) r = this^2, r != this (HAC 14.16) -function bnpSquareTo(r) { - var x = this.abs(); - var i = r.t = 2*x.t; - while(--i >= 0) r.data[i] = 0; - for(i = 0; i < x.t-1; ++i) { - var c = x.am(i,x.data[i],r,2*i,0,1); - if((r.data[i+x.t]+=x.am(i+1,2*x.data[i],r,2*i+1,c,x.t-i-1)) >= x.DV) { - r.data[i+x.t] -= x.DV; - r.data[i+x.t+1] = 1; - } - } - if(r.t > 0) r.data[r.t-1] += x.am(i,x.data[i],r,2*i,0,1); - r.s = 0; - r.clamp(); -} - -// (protected) divide this by m, quotient and remainder to q, r (HAC 14.20) -// r != q, this != m. q or r may be null. -function bnpDivRemTo(m,q,r) { - var pm = m.abs(); - if(pm.t <= 0) return; - var pt = this.abs(); - if(pt.t < pm.t) { - if(q != null) q.fromInt(0); - if(r != null) this.copyTo(r); - return; - } - if(r == null) r = nbi(); - var y = nbi(), ts = this.s, ms = m.s; - var nsh = this.DB-nbits(pm.data[pm.t-1]); // normalize modulus - if(nsh > 0) { pm.lShiftTo(nsh,y); pt.lShiftTo(nsh,r); } else { pm.copyTo(y); pt.copyTo(r); } - var ys = y.t; - var y0 = y.data[ys-1]; - if(y0 == 0) return; - var yt = y0*(1<<this.F1)+((ys>1)?y.data[ys-2]>>this.F2:0); - var d1 = this.FV/yt, d2 = (1<<this.F1)/yt, e = 1<<this.F2; - var i = r.t, j = i-ys, t = (q==null)?nbi():q; - y.dlShiftTo(j,t); - if(r.compareTo(t) >= 0) { - r.data[r.t++] = 1; - r.subTo(t,r); - } - BigInteger.ONE.dlShiftTo(ys,t); - t.subTo(y,y); // "negative" y so we can replace sub with am later - while(y.t < ys) y.data[y.t++] = 0; - while(--j >= 0) { - // Estimate quotient digit - var qd = (r.data[--i]==y0)?this.DM:Math.floor(r.data[i]*d1+(r.data[i-1]+e)*d2); - if((r.data[i]+=y.am(0,qd,r,j,0,ys)) < qd) { // Try it out - y.dlShiftTo(j,t); - r.subTo(t,r); - while(r.data[i] < --qd) r.subTo(t,r); - } - } - if(q != null) { - r.drShiftTo(ys,q); - if(ts != ms) BigInteger.ZERO.subTo(q,q); - } - r.t = ys; - r.clamp(); - if(nsh > 0) r.rShiftTo(nsh,r); // Denormalize remainder - if(ts < 0) BigInteger.ZERO.subTo(r,r); -} - -// (public) this mod a -function bnMod(a) { - var r = nbi(); - this.abs().divRemTo(a,null,r); - if(this.s < 0 && r.compareTo(BigInteger.ZERO) > 0) a.subTo(r,r); - return r; -} - -// Modular reduction using "classic" algorithm -function Classic(m) { this.m = m; } -function cConvert(x) { - if(x.s < 0 || x.compareTo(this.m) >= 0) return x.mod(this.m); - else return x; -} -function cRevert(x) { return x; } -function cReduce(x) { x.divRemTo(this.m,null,x); } -function cMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); } -function cSqrTo(x,r) { x.squareTo(r); this.reduce(r); } - -Classic.prototype.convert = cConvert; -Classic.prototype.revert = cRevert; -Classic.prototype.reduce = cReduce; -Classic.prototype.mulTo = cMulTo; -Classic.prototype.sqrTo = cSqrTo; - -// (protected) return "-1/this % 2^DB"; useful for Mont. reduction -// justification: -// xy == 1 (mod m) -// xy = 1+km -// xy(2-xy) = (1+km)(1-km) -// x[y(2-xy)] = 1-k^2m^2 -// x[y(2-xy)] == 1 (mod m^2) -// if y is 1/x mod m, then y(2-xy) is 1/x mod m^2 -// should reduce x and y(2-xy) by m^2 at each step to keep size bounded. -// JS multiply "overflows" differently from C/C++, so care is needed here. -function bnpInvDigit() { - if(this.t < 1) return 0; - var x = this.data[0]; - if((x&1) == 0) return 0; - var y = x&3; // y == 1/x mod 2^2 - y = (y*(2-(x&0xf)*y))&0xf; // y == 1/x mod 2^4 - y = (y*(2-(x&0xff)*y))&0xff; // y == 1/x mod 2^8 - y = (y*(2-(((x&0xffff)*y)&0xffff)))&0xffff; // y == 1/x mod 2^16 - // last step - calculate inverse mod DV directly; - // assumes 16 < DB <= 32 and assumes ability to handle 48-bit ints - y = (y*(2-x*y%this.DV))%this.DV; // y == 1/x mod 2^dbits - // we really want the negative inverse, and -DV < y < DV - return (y>0)?this.DV-y:-y; -} - -// Montgomery reduction -function Montgomery(m) { - this.m = m; - this.mp = m.invDigit(); - this.mpl = this.mp&0x7fff; - this.mph = this.mp>>15; - this.um = (1<<(m.DB-15))-1; - this.mt2 = 2*m.t; -} - -// xR mod m -function montConvert(x) { - var r = nbi(); - x.abs().dlShiftTo(this.m.t,r); - r.divRemTo(this.m,null,r); - if(x.s < 0 && r.compareTo(BigInteger.ZERO) > 0) this.m.subTo(r,r); - return r; -} - -// x/R mod m -function montRevert(x) { - var r = nbi(); - x.copyTo(r); - this.reduce(r); - return r; -} - -// x = x/R mod m (HAC 14.32) -function montReduce(x) { - while(x.t <= this.mt2) // pad x so am has enough room later - x.data[x.t++] = 0; - for(var i = 0; i < this.m.t; ++i) { - // faster way of calculating u0 = x.data[i]*mp mod DV - var j = x.data[i]&0x7fff; - var u0 = (j*this.mpl+(((j*this.mph+(x.data[i]>>15)*this.mpl)&this.um)<<15))&x.DM; - // use am to combine the multiply-shift-add into one call - j = i+this.m.t; - x.data[j] += this.m.am(0,u0,x,i,0,this.m.t); - // propagate carry - while(x.data[j] >= x.DV) { x.data[j] -= x.DV; x.data[++j]++; } - } - x.clamp(); - x.drShiftTo(this.m.t,x); - if(x.compareTo(this.m) >= 0) x.subTo(this.m,x); -} - -// r = "x^2/R mod m"; x != r -function montSqrTo(x,r) { x.squareTo(r); this.reduce(r); } - -// r = "xy/R mod m"; x,y != r -function montMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); } - -Montgomery.prototype.convert = montConvert; -Montgomery.prototype.revert = montRevert; -Montgomery.prototype.reduce = montReduce; -Montgomery.prototype.mulTo = montMulTo; -Montgomery.prototype.sqrTo = montSqrTo; - -// (protected) true iff this is even -function bnpIsEven() { return ((this.t>0)?(this.data[0]&1):this.s) == 0; } - -// (protected) this^e, e < 2^32, doing sqr and mul with "r" (HAC 14.79) -function bnpExp(e,z) { - if(e > 0xffffffff || e < 1) return BigInteger.ONE; - var r = nbi(), r2 = nbi(), g = z.convert(this), i = nbits(e)-1; - g.copyTo(r); - while(--i >= 0) { - z.sqrTo(r,r2); - if((e&(1<<i)) > 0) z.mulTo(r2,g,r); - else { var t = r; r = r2; r2 = t; } - } - return z.revert(r); -} - -// (public) this^e % m, 0 <= e < 2^32 -function bnModPowInt(e,m) { - var z; - if(e < 256 || m.isEven()) z = new Classic(m); else z = new Montgomery(m); - return this.exp(e,z); -} - -// protected -BigInteger.prototype.copyTo = bnpCopyTo; -BigInteger.prototype.fromInt = bnpFromInt; -BigInteger.prototype.fromString = bnpFromString; -BigInteger.prototype.clamp = bnpClamp; -BigInteger.prototype.dlShiftTo = bnpDLShiftTo; -BigInteger.prototype.drShiftTo = bnpDRShiftTo; -BigInteger.prototype.lShiftTo = bnpLShiftTo; -BigInteger.prototype.rShiftTo = bnpRShiftTo; -BigInteger.prototype.subTo = bnpSubTo; -BigInteger.prototype.multiplyTo = bnpMultiplyTo; -BigInteger.prototype.squareTo = bnpSquareTo; -BigInteger.prototype.divRemTo = bnpDivRemTo; -BigInteger.prototype.invDigit = bnpInvDigit; -BigInteger.prototype.isEven = bnpIsEven; -BigInteger.prototype.exp = bnpExp; - -// public -BigInteger.prototype.toString = bnToString; -BigInteger.prototype.negate = bnNegate; -BigInteger.prototype.abs = bnAbs; -BigInteger.prototype.compareTo = bnCompareTo; -BigInteger.prototype.bitLength = bnBitLength; -BigInteger.prototype.mod = bnMod; -BigInteger.prototype.modPowInt = bnModPowInt; - -// "constants" -BigInteger.ZERO = nbv(0); -BigInteger.ONE = nbv(1); - -// jsbn2 lib - -//Copyright (c) 2005-2009 Tom Wu -//All Rights Reserved. -//See "LICENSE" for details (See jsbn.js for LICENSE). - -//Extended JavaScript BN functions, required for RSA private ops. - -//Version 1.1: new BigInteger("0", 10) returns "proper" zero - -//(public) -function bnClone() { var r = nbi(); this.copyTo(r); return r; } - -//(public) return value as integer -function bnIntValue() { -if(this.s < 0) { - if(this.t == 1) return this.data[0]-this.DV; - else if(this.t == 0) return -1; -} else if(this.t == 1) return this.data[0]; -else if(this.t == 0) return 0; -// assumes 16 < DB < 32 -return ((this.data[1]&((1<<(32-this.DB))-1))<<this.DB)|this.data[0]; -} - -//(public) return value as byte -function bnByteValue() { return (this.t==0)?this.s:(this.data[0]<<24)>>24; } - -//(public) return value as short (assumes DB>=16) -function bnShortValue() { return (this.t==0)?this.s:(this.data[0]<<16)>>16; } - -//(protected) return x s.t. r^x < DV -function bnpChunkSize(r) { return Math.floor(Math.LN2*this.DB/Math.log(r)); } - -//(public) 0 if this == 0, 1 if this > 0 -function bnSigNum() { -if(this.s < 0) return -1; -else if(this.t <= 0 || (this.t == 1 && this.data[0] <= 0)) return 0; -else return 1; -} - -//(protected) convert to radix string -function bnpToRadix(b) { -if(b == null) b = 10; -if(this.signum() == 0 || b < 2 || b > 36) return "0"; -var cs = this.chunkSize(b); -var a = Math.pow(b,cs); -var d = nbv(a), y = nbi(), z = nbi(), r = ""; -this.divRemTo(d,y,z); -while(y.signum() > 0) { - r = (a+z.intValue()).toString(b).substr(1) + r; - y.divRemTo(d,y,z); -} -return z.intValue().toString(b) + r; -} - -//(protected) convert from radix string -function bnpFromRadix(s,b) { -this.fromInt(0); -if(b == null) b = 10; -var cs = this.chunkSize(b); -var d = Math.pow(b,cs), mi = false, j = 0, w = 0; -for(var i = 0; i < s.length; ++i) { - var x = intAt(s,i); - if(x < 0) { - if(s.charAt(i) == "-" && this.signum() == 0) mi = true; - continue; - } - w = b*w+x; - if(++j >= cs) { - this.dMultiply(d); - this.dAddOffset(w,0); - j = 0; - w = 0; - } -} -if(j > 0) { - this.dMultiply(Math.pow(b,j)); - this.dAddOffset(w,0); -} -if(mi) BigInteger.ZERO.subTo(this,this); -} - -//(protected) alternate constructor -function bnpFromNumber(a,b,c) { -if("number" == typeof b) { - // new BigInteger(int,int,RNG) - if(a < 2) this.fromInt(1); - else { - this.fromNumber(a,c); - if(!this.testBit(a-1)) // force MSB set - this.bitwiseTo(BigInteger.ONE.shiftLeft(a-1),op_or,this); - if(this.isEven()) this.dAddOffset(1,0); // force odd - while(!this.isProbablePrime(b)) { - this.dAddOffset(2,0); - if(this.bitLength() > a) this.subTo(BigInteger.ONE.shiftLeft(a-1),this); - } - } -} else { - // new BigInteger(int,RNG) - var x = new Array(), t = a&7; - x.length = (a>>3)+1; - b.nextBytes(x); - if(t > 0) x[0] &= ((1<<t)-1); else x[0] = 0; - this.fromString(x,256); -} -} - -//(public) convert to bigendian byte array -function bnToByteArray() { -var i = this.t, r = new Array(); -r[0] = this.s; -var p = this.DB-(i*this.DB)%8, d, k = 0; -if(i-- > 0) { - if(p < this.DB && (d = this.data[i]>>p) != (this.s&this.DM)>>p) - r[k++] = d|(this.s<<(this.DB-p)); - while(i >= 0) { - if(p < 8) { - d = (this.data[i]&((1<<p)-1))<<(8-p); - d |= this.data[--i]>>(p+=this.DB-8); - } else { - d = (this.data[i]>>(p-=8))&0xff; - if(p <= 0) { p += this.DB; --i; } - } - if((d&0x80) != 0) d |= -256; - if(k == 0 && (this.s&0x80) != (d&0x80)) ++k; - if(k > 0 || d != this.s) r[k++] = d; - } -} -return r; -} - -function bnEquals(a) { return(this.compareTo(a)==0); } -function bnMin(a) { return(this.compareTo(a)<0)?this:a; } -function bnMax(a) { return(this.compareTo(a)>0)?this:a; } - -//(protected) r = this op a (bitwise) -function bnpBitwiseTo(a,op,r) { -var i, f, m = Math.min(a.t,this.t); -for(i = 0; i < m; ++i) r.data[i] = op(this.data[i],a.data[i]); -if(a.t < this.t) { - f = a.s&this.DM; - for(i = m; i < this.t; ++i) r.data[i] = op(this.data[i],f); - r.t = this.t; -} else { - f = this.s&this.DM; - for(i = m; i < a.t; ++i) r.data[i] = op(f,a.data[i]); - r.t = a.t; -} -r.s = op(this.s,a.s); -r.clamp(); -} - -//(public) this & a -function op_and(x,y) { return x&y; } -function bnAnd(a) { var r = nbi(); this.bitwiseTo(a,op_and,r); return r; } - -//(public) this | a -function op_or(x,y) { return x|y; } -function bnOr(a) { var r = nbi(); this.bitwiseTo(a,op_or,r); return r; } - -//(public) this ^ a -function op_xor(x,y) { return x^y; } -function bnXor(a) { var r = nbi(); this.bitwiseTo(a,op_xor,r); return r; } - -//(public) this & ~a -function op_andnot(x,y) { return x&~y; } -function bnAndNot(a) { var r = nbi(); this.bitwiseTo(a,op_andnot,r); return r; } - -//(public) ~this -function bnNot() { -var r = nbi(); -for(var i = 0; i < this.t; ++i) r.data[i] = this.DM&~this.data[i]; -r.t = this.t; -r.s = ~this.s; -return r; -} - -//(public) this << n -function bnShiftLeft(n) { -var r = nbi(); -if(n < 0) this.rShiftTo(-n,r); else this.lShiftTo(n,r); -return r; -} - -//(public) this >> n -function bnShiftRight(n) { -var r = nbi(); -if(n < 0) this.lShiftTo(-n,r); else this.rShiftTo(n,r); -return r; -} - -//return index of lowest 1-bit in x, x < 2^31 -function lbit(x) { -if(x == 0) return -1; -var r = 0; -if((x&0xffff) == 0) { x >>= 16; r += 16; } -if((x&0xff) == 0) { x >>= 8; r += 8; } -if((x&0xf) == 0) { x >>= 4; r += 4; } -if((x&3) == 0) { x >>= 2; r += 2; } -if((x&1) == 0) ++r; -return r; -} - -//(public) returns index of lowest 1-bit (or -1 if none) -function bnGetLowestSetBit() { -for(var i = 0; i < this.t; ++i) - if(this.data[i] != 0) return i*this.DB+lbit(this.data[i]); -if(this.s < 0) return this.t*this.DB; -return -1; -} - -//return number of 1 bits in x -function cbit(x) { -var r = 0; -while(x != 0) { x &= x-1; ++r; } -return r; -} - -//(public) return number of set bits -function bnBitCount() { -var r = 0, x = this.s&this.DM; -for(var i = 0; i < this.t; ++i) r += cbit(this.data[i]^x); -return r; -} - -//(public) true iff nth bit is set -function bnTestBit(n) { -var j = Math.floor(n/this.DB); -if(j >= this.t) return(this.s!=0); -return((this.data[j]&(1<<(n%this.DB)))!=0); -} - -//(protected) this op (1<<n) -function bnpChangeBit(n,op) { -var r = BigInteger.ONE.shiftLeft(n); -this.bitwiseTo(r,op,r); -return r; -} - -//(public) this | (1<<n) -function bnSetBit(n) { return this.changeBit(n,op_or); } - -//(public) this & ~(1<<n) -function bnClearBit(n) { return this.changeBit(n,op_andnot); } - -//(public) this ^ (1<<n) -function bnFlipBit(n) { return this.changeBit(n,op_xor); } - -//(protected) r = this + a -function bnpAddTo(a,r) { -var i = 0, c = 0, m = Math.min(a.t,this.t); -while(i < m) { - c += this.data[i]+a.data[i]; - r.data[i++] = c&this.DM; - c >>= this.DB; -} -if(a.t < this.t) { - c += a.s; - while(i < this.t) { - c += this.data[i]; - r.data[i++] = c&this.DM; - c >>= this.DB; - } - c += this.s; -} else { - c += this.s; - while(i < a.t) { - c += a.data[i]; - r.data[i++] = c&this.DM; - c >>= this.DB; - } - c += a.s; -} -r.s = (c<0)?-1:0; -if(c > 0) r.data[i++] = c; -else if(c < -1) r.data[i++] = this.DV+c; -r.t = i; -r.clamp(); -} - -//(public) this + a -function bnAdd(a) { var r = nbi(); this.addTo(a,r); return r; } - -//(public) this - a -function bnSubtract(a) { var r = nbi(); this.subTo(a,r); return r; } - -//(public) this * a -function bnMultiply(a) { var r = nbi(); this.multiplyTo(a,r); return r; } - -//(public) this / a -function bnDivide(a) { var r = nbi(); this.divRemTo(a,r,null); return r; } - -//(public) this % a -function bnRemainder(a) { var r = nbi(); this.divRemTo(a,null,r); return r; } - -//(public) [this/a,this%a] -function bnDivideAndRemainder(a) { -var q = nbi(), r = nbi(); -this.divRemTo(a,q,r); -return new Array(q,r); -} - -//(protected) this *= n, this >= 0, 1 < n < DV -function bnpDMultiply(n) { -this.data[this.t] = this.am(0,n-1,this,0,0,this.t); -++this.t; -this.clamp(); -} - -//(protected) this += n << w words, this >= 0 -function bnpDAddOffset(n,w) { -if(n == 0) return; -while(this.t <= w) this.data[this.t++] = 0; -this.data[w] += n; -while(this.data[w] >= this.DV) { - this.data[w] -= this.DV; - if(++w >= this.t) this.data[this.t++] = 0; - ++this.data[w]; -} -} - -//A "null" reducer -function NullExp() {} -function nNop(x) { return x; } -function nMulTo(x,y,r) { x.multiplyTo(y,r); } -function nSqrTo(x,r) { x.squareTo(r); } - -NullExp.prototype.convert = nNop; -NullExp.prototype.revert = nNop; -NullExp.prototype.mulTo = nMulTo; -NullExp.prototype.sqrTo = nSqrTo; - -//(public) this^e -function bnPow(e) { return this.exp(e,new NullExp()); } - -//(protected) r = lower n words of "this * a", a.t <= n -//"this" should be the larger one if appropriate. -function bnpMultiplyLowerTo(a,n,r) { -var i = Math.min(this.t+a.t,n); -r.s = 0; // assumes a,this >= 0 -r.t = i; -while(i > 0) r.data[--i] = 0; -var j; -for(j = r.t-this.t; i < j; ++i) r.data[i+this.t] = this.am(0,a.data[i],r,i,0,this.t); -for(j = Math.min(a.t,n); i < j; ++i) this.am(0,a.data[i],r,i,0,n-i); -r.clamp(); -} - -//(protected) r = "this * a" without lower n words, n > 0 -//"this" should be the larger one if appropriate. -function bnpMultiplyUpperTo(a,n,r) { ---n; -var i = r.t = this.t+a.t-n; -r.s = 0; // assumes a,this >= 0 -while(--i >= 0) r.data[i] = 0; -for(i = Math.max(n-this.t,0); i < a.t; ++i) - r.data[this.t+i-n] = this.am(n-i,a.data[i],r,0,0,this.t+i-n); -r.clamp(); -r.drShiftTo(1,r); -} - -//Barrett modular reduction -function Barrett(m) { -// setup Barrett -this.r2 = nbi(); -this.q3 = nbi(); -BigInteger.ONE.dlShiftTo(2*m.t,this.r2); -this.mu = this.r2.divide(m); -this.m = m; -} - -function barrettConvert(x) { -if(x.s < 0 || x.t > 2*this.m.t) return x.mod(this.m); -else if(x.compareTo(this.m) < 0) return x; -else { var r = nbi(); x.copyTo(r); this.reduce(r); return r; } -} - -function barrettRevert(x) { return x; } - -//x = x mod m (HAC 14.42) -function barrettReduce(x) { -x.drShiftTo(this.m.t-1,this.r2); -if(x.t > this.m.t+1) { x.t = this.m.t+1; x.clamp(); } -this.mu.multiplyUpperTo(this.r2,this.m.t+1,this.q3); -this.m.multiplyLowerTo(this.q3,this.m.t+1,this.r2); -while(x.compareTo(this.r2) < 0) x.dAddOffset(1,this.m.t+1); -x.subTo(this.r2,x); -while(x.compareTo(this.m) >= 0) x.subTo(this.m,x); -} - -//r = x^2 mod m; x != r -function barrettSqrTo(x,r) { x.squareTo(r); this.reduce(r); } - -//r = x*y mod m; x,y != r -function barrettMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); } - -Barrett.prototype.convert = barrettConvert; -Barrett.prototype.revert = barrettRevert; -Barrett.prototype.reduce = barrettReduce; -Barrett.prototype.mulTo = barrettMulTo; -Barrett.prototype.sqrTo = barrettSqrTo; - -//(public) this^e % m (HAC 14.85) -function bnModPow(e,m) { -var i = e.bitLength(), k, r = nbv(1), z; -if(i <= 0) return r; -else if(i < 18) k = 1; -else if(i < 48) k = 3; -else if(i < 144) k = 4; -else if(i < 768) k = 5; -else k = 6; -if(i < 8) - z = new Classic(m); -else if(m.isEven()) - z = new Barrett(m); -else - z = new Montgomery(m); - -// precomputation -var g = new Array(), n = 3, k1 = k-1, km = (1<<k)-1; -g[1] = z.convert(this); -if(k > 1) { - var g2 = nbi(); - z.sqrTo(g[1],g2); - while(n <= km) { - g[n] = nbi(); - z.mulTo(g2,g[n-2],g[n]); - n += 2; - } -} - -var j = e.t-1, w, is1 = true, r2 = nbi(), t; -i = nbits(e.data[j])-1; -while(j >= 0) { - if(i >= k1) w = (e.data[j]>>(i-k1))&km; - else { - w = (e.data[j]&((1<<(i+1))-1))<<(k1-i); - if(j > 0) w |= e.data[j-1]>>(this.DB+i-k1); - } - - n = k; - while((w&1) == 0) { w >>= 1; --n; } - if((i -= n) < 0) { i += this.DB; --j; } - if(is1) { // ret == 1, don't bother squaring or multiplying it - g[w].copyTo(r); - is1 = false; - } else { - while(n > 1) { z.sqrTo(r,r2); z.sqrTo(r2,r); n -= 2; } - if(n > 0) z.sqrTo(r,r2); else { t = r; r = r2; r2 = t; } - z.mulTo(r2,g[w],r); - } - - while(j >= 0 && (e.data[j]&(1<<i)) == 0) { - z.sqrTo(r,r2); t = r; r = r2; r2 = t; - if(--i < 0) { i = this.DB-1; --j; } - } -} -return z.revert(r); -} - -//(public) gcd(this,a) (HAC 14.54) -function bnGCD(a) { -var x = (this.s<0)?this.negate():this.clone(); -var y = (a.s<0)?a.negate():a.clone(); -if(x.compareTo(y) < 0) { var t = x; x = y; y = t; } -var i = x.getLowestSetBit(), g = y.getLowestSetBit(); -if(g < 0) return x; -if(i < g) g = i; -if(g > 0) { - x.rShiftTo(g,x); - y.rShiftTo(g,y); -} -while(x.signum() > 0) { - if((i = x.getLowestSetBit()) > 0) x.rShiftTo(i,x); - if((i = y.getLowestSetBit()) > 0) y.rShiftTo(i,y); - if(x.compareTo(y) >= 0) { - x.subTo(y,x); - x.rShiftTo(1,x); - } else { - y.subTo(x,y); - y.rShiftTo(1,y); - } -} -if(g > 0) y.lShiftTo(g,y); -return y; -} - -//(protected) this % n, n < 2^26 -function bnpModInt(n) { -if(n <= 0) return 0; -var d = this.DV%n, r = (this.s<0)?n-1:0; -if(this.t > 0) - if(d == 0) r = this.data[0]%n; - else for(var i = this.t-1; i >= 0; --i) r = (d*r+this.data[i])%n; -return r; -} - -//(public) 1/this % m (HAC 14.61) -function bnModInverse(m) { -var ac = m.isEven(); -if((this.isEven() && ac) || m.signum() == 0) return BigInteger.ZERO; -var u = m.clone(), v = this.clone(); -var a = nbv(1), b = nbv(0), c = nbv(0), d = nbv(1); -while(u.signum() != 0) { - while(u.isEven()) { - u.rShiftTo(1,u); - if(ac) { - if(!a.isEven() || !b.isEven()) { a.addTo(this,a); b.subTo(m,b); } - a.rShiftTo(1,a); - } else if(!b.isEven()) b.subTo(m,b); - b.rShiftTo(1,b); - } - while(v.isEven()) { - v.rShiftTo(1,v); - if(ac) { - if(!c.isEven() || !d.isEven()) { c.addTo(this,c); d.subTo(m,d); } - c.rShiftTo(1,c); - } else if(!d.isEven()) d.subTo(m,d); - d.rShiftTo(1,d); - } - if(u.compareTo(v) >= 0) { - u.subTo(v,u); - if(ac) a.subTo(c,a); - b.subTo(d,b); - } else { - v.subTo(u,v); - if(ac) c.subTo(a,c); - d.subTo(b,d); - } -} -if(v.compareTo(BigInteger.ONE) != 0) return BigInteger.ZERO; -if(d.compareTo(m) >= 0) return d.subtract(m); -if(d.signum() < 0) d.addTo(m,d); else return d; -if(d.signum() < 0) return d.add(m); else return d; -} - -var lowprimes = [2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293,307,311,313,317,331,337,347,349,353,359,367,373,379,383,389,397,401,409,419,421,431,433,439,443,449,457,461,463,467,479,487,491,499,503,509]; -var lplim = (1<<26)/lowprimes[lowprimes.length-1]; - -//(public) test primality with certainty >= 1-.5^t -function bnIsProbablePrime(t) { -var i, x = this.abs(); -if(x.t == 1 && x.data[0] <= lowprimes[lowprimes.length-1]) { - for(i = 0; i < lowprimes.length; ++i) - if(x.data[0] == lowprimes[i]) return true; - return false; -} -if(x.isEven()) return false; -i = 1; -while(i < lowprimes.length) { - var m = lowprimes[i], j = i+1; - while(j < lowprimes.length && m < lplim) m *= lowprimes[j++]; - m = x.modInt(m); - while(i < j) if(m%lowprimes[i++] == 0) return false; -} -return x.millerRabin(t); -} - -//(protected) true if probably prime (HAC 4.24, Miller-Rabin) -function bnpMillerRabin(t) { -var n1 = this.subtract(BigInteger.ONE); -var k = n1.getLowestSetBit(); -if(k <= 0) return false; -var r = n1.shiftRight(k); -var prng = bnGetPrng(); -var a; -for(var i = 0; i < t; ++i) { - // select witness 'a' at random from between 1 and n1 - do { - a = new BigInteger(this.bitLength(), prng); - } - while(a.compareTo(BigInteger.ONE) <= 0 || a.compareTo(n1) >= 0); - var y = a.modPow(r,this); - if(y.compareTo(BigInteger.ONE) != 0 && y.compareTo(n1) != 0) { - var j = 1; - while(j++ < k && y.compareTo(n1) != 0) { - y = y.modPowInt(2,this); - if(y.compareTo(BigInteger.ONE) == 0) return false; - } - if(y.compareTo(n1) != 0) return false; - } -} -return true; -} - -// get pseudo random number generator -function bnGetPrng() { - // create prng with api that matches BigInteger secure random - return { - // x is an array to fill with bytes - nextBytes: function(x) { - for(var i = 0; i < x.length; ++i) { - x[i] = Math.floor(Math.random() * 0x0100); - } - } - }; -} - -//protected -BigInteger.prototype.chunkSize = bnpChunkSize; -BigInteger.prototype.toRadix = bnpToRadix; -BigInteger.prototype.fromRadix = bnpFromRadix; -BigInteger.prototype.fromNumber = bnpFromNumber; -BigInteger.prototype.bitwiseTo = bnpBitwiseTo; -BigInteger.prototype.changeBit = bnpChangeBit; -BigInteger.prototype.addTo = bnpAddTo; -BigInteger.prototype.dMultiply = bnpDMultiply; -BigInteger.prototype.dAddOffset = bnpDAddOffset; -BigInteger.prototype.multiplyLowerTo = bnpMultiplyLowerTo; -BigInteger.prototype.multiplyUpperTo = bnpMultiplyUpperTo; -BigInteger.prototype.modInt = bnpModInt; -BigInteger.prototype.millerRabin = bnpMillerRabin; - -//public -BigInteger.prototype.clone = bnClone; -BigInteger.prototype.intValue = bnIntValue; -BigInteger.prototype.byteValue = bnByteValue; -BigInteger.prototype.shortValue = bnShortValue; -BigInteger.prototype.signum = bnSigNum; -BigInteger.prototype.toByteArray = bnToByteArray; -BigInteger.prototype.equals = bnEquals; -BigInteger.prototype.min = bnMin; -BigInteger.prototype.max = bnMax; -BigInteger.prototype.and = bnAnd; -BigInteger.prototype.or = bnOr; -BigInteger.prototype.xor = bnXor; -BigInteger.prototype.andNot = bnAndNot; -BigInteger.prototype.not = bnNot; -BigInteger.prototype.shiftLeft = bnShiftLeft; -BigInteger.prototype.shiftRight = bnShiftRight; -BigInteger.prototype.getLowestSetBit = bnGetLowestSetBit; -BigInteger.prototype.bitCount = bnBitCount; -BigInteger.prototype.testBit = bnTestBit; -BigInteger.prototype.setBit = bnSetBit; -BigInteger.prototype.clearBit = bnClearBit; -BigInteger.prototype.flipBit = bnFlipBit; -BigInteger.prototype.add = bnAdd; -BigInteger.prototype.subtract = bnSubtract; -BigInteger.prototype.multiply = bnMultiply; -BigInteger.prototype.divide = bnDivide; -BigInteger.prototype.remainder = bnRemainder; -BigInteger.prototype.divideAndRemainder = bnDivideAndRemainder; -BigInteger.prototype.modPow = bnModPow; -BigInteger.prototype.modInverse = bnModInverse; -BigInteger.prototype.pow = bnPow; -BigInteger.prototype.gcd = bnGCD; -BigInteger.prototype.isProbablePrime = bnIsProbablePrime; - -//BigInteger interfaces not implemented in jsbn: - -//BigInteger(int signum, byte[] magnitude) -//double doubleValue() -//float floatValue() -//int hashCode() -//long longValue() -//static BigInteger valueOf(long val) - -forge.jsbn = forge.jsbn || {}; -forge.jsbn.BigInteger = BigInteger; - -} // end module implementation - -/* ########## Begin module wrapper ########## */ -var name = 'jsbn'; -if(typeof define !== 'function') { - // NodeJS -> AMD - if(typeof module === 'object' && module.exports) { - var nodeJS = true; - define = function(ids, factory) { - factory(require, module); - }; - } else { - // <script> - if(typeof forge === 'undefined') { - forge = {}; - } - return initModule(forge); - } -} -// AMD -var deps; -var defineFunc = function(require, module) { - module.exports = function(forge) { - var mods = deps.map(function(dep) { - return require(dep); - }).concat(initModule); - // handle circular dependencies - forge = forge || {}; - forge.defined = forge.defined || {}; - if(forge.defined[name]) { - return forge[name]; - } - forge.defined[name] = true; - for(var i = 0; i < mods.length; ++i) { - mods[i](forge); - } - return forge[name]; - }; -}; -var tmpDefine = define; -define = function(ids, factory) { - deps = (typeof ids === 'string') ? factory.slice(2) : ids.slice(2); - if(nodeJS) { - delete define; - return tmpDefine.apply(null, Array.prototype.slice.call(arguments, 0)); - } - define = tmpDefine; - return define.apply(null, Array.prototype.slice.call(arguments, 0)); -}; -define(['require', 'module'], function() { - defineFunc.apply(null, Array.prototype.slice.call(arguments, 0)); -}); -})(); diff --git a/alarm/node_modules/node-forge/js/kem.js b/alarm/node_modules/node-forge/js/kem.js deleted file mode 100644 index 7ac7851..0000000 --- a/alarm/node_modules/node-forge/js/kem.js +++ /dev/null @@ -1,221 +0,0 @@ -/** - * Javascript implementation of RSA-KEM. - * - * @author Lautaro Cozzani Rodriguez - * @author Dave Longley - * - * Copyright (c) 2014 Lautaro Cozzani <lautaro.cozzani@scytl.com> - * Copyright (c) 2014 Digital Bazaar, Inc. - */ -(function() { -/* ########## Begin module implementation ########## */ -function initModule(forge) { - -forge.kem = forge.kem || {}; - -var BigInteger = forge.jsbn.BigInteger; - -/** - * The API for the RSA Key Encapsulation Mechanism (RSA-KEM) from ISO 18033-2. - */ -forge.kem.rsa = {}; - -/** - * Creates an RSA KEM API object for generating a secret asymmetric key. - * - * The symmetric key may be generated via a call to 'encrypt', which will - * produce a ciphertext to be transmitted to the recipient and a key to be - * kept secret. The ciphertext is a parameter to be passed to 'decrypt' which - * will produce the same secret key for the recipient to use to decrypt a - * message that was encrypted with the secret key. - * - * @param kdf the KDF API to use (eg: new forge.kem.kdf1()). - * @param options the options to use. - * [prng] a custom crypto-secure pseudo-random number generator to use, - * that must define "getBytesSync". - */ -forge.kem.rsa.create = function(kdf, options) { - options = options || {}; - var prng = options.prng || forge.random; - - var kem = {}; - - /** - * Generates a secret key and its encapsulation. - * - * @param publicKey the RSA public key to encrypt with. - * @param keyLength the length, in bytes, of the secret key to generate. - * - * @return an object with: - * encapsulation: the ciphertext for generating the secret key, as a - * binary-encoded string of bytes. - * key: the secret key to use for encrypting a message. - */ - kem.encrypt = function(publicKey, keyLength) { - // generate a random r where 1 > r > n - var byteLength = Math.ceil(publicKey.n.bitLength() / 8); - var r; - do { - r = new BigInteger( - forge.util.bytesToHex(prng.getBytesSync(byteLength)), - 16).mod(publicKey.n); - } while(r.equals(BigInteger.ZERO)); - - // prepend r with zeros - r = forge.util.hexToBytes(r.toString(16)); - var zeros = byteLength - r.length; - if(zeros > 0) { - r = forge.util.fillString(String.fromCharCode(0), zeros) + r; - } - - // encrypt the random - var encapsulation = publicKey.encrypt(r, 'NONE'); - - // generate the secret key - var key = kdf.generate(r, keyLength); - - return {encapsulation: encapsulation, key: key}; - }; - - /** - * Decrypts an encapsulated secret key. - * - * @param privateKey the RSA private key to decrypt with. - * @param encapsulation the ciphertext for generating the secret key, as - * a binary-encoded string of bytes. - * @param keyLength the length, in bytes, of the secret key to generate. - * - * @return the secret key as a binary-encoded string of bytes. - */ - kem.decrypt = function(privateKey, encapsulation, keyLength) { - // decrypt the encapsulation and generate the secret key - var r = privateKey.decrypt(encapsulation, 'NONE'); - return kdf.generate(r, keyLength); - }; - - return kem; -}; - -// TODO: add forge.kem.kdf.create('KDF1', {md: ..., ...}) API? - -/** - * Creates a key derivation API object that implements KDF1 per ISO 18033-2. - * - * @param md the hash API to use. - * @param [digestLength] an optional digest length that must be positive and - * less than or equal to md.digestLength. - * - * @return a KDF1 API object. - */ -forge.kem.kdf1 = function(md, digestLength) { - _createKDF(this, md, 0, digestLength || md.digestLength); -}; - -/** - * Creates a key derivation API object that implements KDF2 per ISO 18033-2. - * - * @param md the hash API to use. - * @param [digestLength] an optional digest length that must be positive and - * less than or equal to md.digestLength. - * - * @return a KDF2 API object. - */ -forge.kem.kdf2 = function(md, digestLength) { - _createKDF(this, md, 1, digestLength || md.digestLength); -}; - -/** - * Creates a KDF1 or KDF2 API object. - * - * @param md the hash API to use. - * @param counterStart the starting index for the counter. - * @param digestLength the digest length to use. - * - * @return the KDF API object. - */ -function _createKDF(kdf, md, counterStart, digestLength) { - /** - * Generate a key of the specified length. - * - * @param x the binary-encoded byte string to generate a key from. - * @param length the number of bytes to generate (the size of the key). - * - * @return the key as a binary-encoded string. - */ - kdf.generate = function(x, length) { - var key = new forge.util.ByteBuffer(); - - // run counter from counterStart to ceil(length / Hash.len) - var k = Math.ceil(length / digestLength) + counterStart; - - var c = new forge.util.ByteBuffer(); - for(var i = counterStart; i < k; ++i) { - // I2OSP(i, 4): convert counter to an octet string of 4 octets - c.putInt32(i); - - // digest 'x' and the counter and add the result to the key - md.start(); - md.update(x + c.getBytes()); - var hash = md.digest(); - key.putBytes(hash.getBytes(digestLength)); - } - - // truncate to the correct key length - key.truncate(key.length() - length); - return key.getBytes(); - }; -} - -} // end module implementation - -/* ########## Begin module wrapper ########## */ -var name = 'kem'; -if(typeof define !== 'function') { - // NodeJS -> AMD - if(typeof module === 'object' && module.exports) { - var nodeJS = true; - define = function(ids, factory) { - factory(require, module); - }; - } else { - // <script> - if(typeof forge === 'undefined') { - forge = {}; - } - return initModule(forge); - } -} -// AMD -var deps; -var defineFunc = function(require, module) { - module.exports = function(forge) { - var mods = deps.map(function(dep) { - return require(dep); - }).concat(initModule); - // handle circular dependencies - forge = forge || {}; - forge.defined = forge.defined || {}; - if(forge.defined[name]) { - return forge[name]; - } - forge.defined[name] = true; - for(var i = 0; i < mods.length; ++i) { - mods[i](forge); - } - return forge[name]; - }; -}; -var tmpDefine = define; -define = function(ids, factory) { - deps = (typeof ids === 'string') ? factory.slice(2) : ids.slice(2); - if(nodeJS) { - delete define; - return tmpDefine.apply(null, Array.prototype.slice.call(arguments, 0)); - } - define = tmpDefine; - return define.apply(null, Array.prototype.slice.call(arguments, 0)); -}; -define(['require', 'module', './util','./random','./jsbn'], function() { - defineFunc.apply(null, Array.prototype.slice.call(arguments, 0)); -}); -})(); diff --git a/alarm/node_modules/node-forge/js/log.js b/alarm/node_modules/node-forge/js/log.js deleted file mode 100644 index c7931f5..0000000 --- a/alarm/node_modules/node-forge/js/log.js +++ /dev/null @@ -1,372 +0,0 @@ -/** - * Cross-browser support for logging in a web application. - * - * @author David I. Lehn <dlehn@digitalbazaar.com> - * - * Copyright (c) 2008-2013 Digital Bazaar, Inc. - */ -(function() { -/* ########## Begin module implementation ########## */ -function initModule(forge) { - -/* LOG API */ -forge.log = forge.log || {}; - -/** - * Application logging system. - * - * Each logger level available as it's own function of the form: - * forge.log.level(category, args...) - * The category is an arbitrary string, and the args are the same as - * Firebug's console.log API. By default the call will be output as: - * 'LEVEL [category] <args[0]>, args[1], ...' - * This enables proper % formatting via the first argument. - * Each category is enabled by default but can be enabled or disabled with - * the setCategoryEnabled() function. - */ -// list of known levels -forge.log.levels = [ - 'none', 'error', 'warning', 'info', 'debug', 'verbose', 'max']; -// info on the levels indexed by name: -// index: level index -// name: uppercased display name -var sLevelInfo = {}; -// list of loggers -var sLoggers = []; -/** - * Standard console logger. If no console support is enabled this will - * remain null. Check before using. - */ -var sConsoleLogger = null; - -// logger flags -/** - * Lock the level at the current value. Used in cases where user config may - * set the level such that only critical messages are seen but more verbose - * messages are needed for debugging or other purposes. - */ -forge.log.LEVEL_LOCKED = (1 << 1); -/** - * Always call log function. By default, the logging system will check the - * message level against logger.level before calling the log function. This - * flag allows the function to do its own check. - */ -forge.log.NO_LEVEL_CHECK = (1 << 2); -/** - * Perform message interpolation with the passed arguments. "%" style - * fields in log messages will be replaced by arguments as needed. Some - * loggers, such as Firebug, may do this automatically. The original log - * message will be available as 'message' and the interpolated version will - * be available as 'fullMessage'. - */ -forge.log.INTERPOLATE = (1 << 3); - -// setup each log level -for(var i = 0; i < forge.log.levels.length; ++i) { - var level = forge.log.levels[i]; - sLevelInfo[level] = { - index: i, - name: level.toUpperCase() - }; -} - -/** - * Message logger. Will dispatch a message to registered loggers as needed. - * - * @param message message object - */ -forge.log.logMessage = function(message) { - var messageLevelIndex = sLevelInfo[message.level].index; - for(var i = 0; i < sLoggers.length; ++i) { - var logger = sLoggers[i]; - if(logger.flags & forge.log.NO_LEVEL_CHECK) { - logger.f(message); - } else { - // get logger level - var loggerLevelIndex = sLevelInfo[logger.level].index; - // check level - if(messageLevelIndex <= loggerLevelIndex) { - // message critical enough, call logger - logger.f(logger, message); - } - } - } -}; - -/** - * Sets the 'standard' key on a message object to: - * "LEVEL [category] " + message - * - * @param message a message log object - */ -forge.log.prepareStandard = function(message) { - if(!('standard' in message)) { - message.standard = - sLevelInfo[message.level].name + - //' ' + +message.timestamp + - ' [' + message.category + '] ' + - message.message; - } -}; - -/** - * Sets the 'full' key on a message object to the original message - * interpolated via % formatting with the message arguments. - * - * @param message a message log object. - */ -forge.log.prepareFull = function(message) { - if(!('full' in message)) { - // copy args and insert message at the front - var args = [message.message]; - args = args.concat([] || message['arguments']); - // format the message - message.full = forge.util.format.apply(this, args); - } -}; - -/** - * Applies both preparseStandard() and prepareFull() to a message object and - * store result in 'standardFull'. - * - * @param message a message log object. - */ -forge.log.prepareStandardFull = function(message) { - if(!('standardFull' in message)) { - // FIXME implement 'standardFull' logging - forge.log.prepareStandard(message); - message.standardFull = message.standard; - } -}; - -// create log level functions -if(true) { - // levels for which we want functions - var levels = ['error', 'warning', 'info', 'debug', 'verbose']; - for(var i = 0; i < levels.length; ++i) { - // wrap in a function to ensure proper level var is passed - (function(level) { - // create function for this level - forge.log[level] = function(category, message/*, args...*/) { - // convert arguments to real array, remove category and message - var args = Array.prototype.slice.call(arguments).slice(2); - // create message object - // Note: interpolation and standard formatting is done lazily - var msg = { - timestamp: new Date(), - level: level, - category: category, - message: message, - 'arguments': args - /*standard*/ - /*full*/ - /*fullMessage*/ - }; - // process this message - forge.log.logMessage(msg); - }; - })(levels[i]); - } -} - -/** - * Creates a new logger with specified custom logging function. - * - * The logging function has a signature of: - * function(logger, message) - * logger: current logger - * message: object: - * level: level id - * category: category - * message: string message - * arguments: Array of extra arguments - * fullMessage: interpolated message and arguments if INTERPOLATE flag set - * - * @param logFunction a logging function which takes a log message object - * as a parameter. - * - * @return a logger object. - */ -forge.log.makeLogger = function(logFunction) { - var logger = { - flags: 0, - f: logFunction - }; - forge.log.setLevel(logger, 'none'); - return logger; -}; - -/** - * Sets the current log level on a logger. - * - * @param logger the target logger. - * @param level the new maximum log level as a string. - * - * @return true if set, false if not. - */ -forge.log.setLevel = function(logger, level) { - var rval = false; - if(logger && !(logger.flags & forge.log.LEVEL_LOCKED)) { - for(var i = 0; i < forge.log.levels.length; ++i) { - var aValidLevel = forge.log.levels[i]; - if(level == aValidLevel) { - // set level - logger.level = level; - rval = true; - break; - } - } - } - - return rval; -}; - -/** - * Locks the log level at its current value. - * - * @param logger the target logger. - * @param lock boolean lock value, default to true. - */ -forge.log.lock = function(logger, lock) { - if(typeof lock === 'undefined' || lock) { - logger.flags |= forge.log.LEVEL_LOCKED; - } else { - logger.flags &= ~forge.log.LEVEL_LOCKED; - } -}; - -/** - * Adds a logger. - * - * @param logger the logger object. - */ -forge.log.addLogger = function(logger) { - sLoggers.push(logger); -}; - -// setup the console logger if possible, else create fake console.log -if(typeof(console) !== 'undefined' && 'log' in console) { - var logger; - if(console.error && console.warn && console.info && console.debug) { - // looks like Firebug-style logging is available - // level handlers map - var levelHandlers = { - error: console.error, - warning: console.warn, - info: console.info, - debug: console.debug, - verbose: console.debug - }; - var f = function(logger, message) { - forge.log.prepareStandard(message); - var handler = levelHandlers[message.level]; - // prepend standard message and concat args - var args = [message.standard]; - args = args.concat(message['arguments'].slice()); - // apply to low-level console function - handler.apply(console, args); - }; - logger = forge.log.makeLogger(f); - } else { - // only appear to have basic console.log - var f = function(logger, message) { - forge.log.prepareStandardFull(message); - console.log(message.standardFull); - }; - logger = forge.log.makeLogger(f); - } - forge.log.setLevel(logger, 'debug'); - forge.log.addLogger(logger); - sConsoleLogger = logger; -} else { - // define fake console.log to avoid potential script errors on - // browsers that do not have console logging - console = { - log: function() {} - }; -} - -/* - * Check for logging control query vars. - * - * console.level=<level-name> - * Set's the console log level by name. Useful to override defaults and - * allow more verbose logging before a user config is loaded. - * - * console.lock=<true|false> - * Lock the console log level at whatever level it is set at. This is run - * after console.level is processed. Useful to force a level of verbosity - * that could otherwise be limited by a user config. - */ -if(sConsoleLogger !== null) { - var query = forge.util.getQueryVariables(); - if('console.level' in query) { - // set with last value - forge.log.setLevel( - sConsoleLogger, query['console.level'].slice(-1)[0]); - } - if('console.lock' in query) { - // set with last value - var lock = query['console.lock'].slice(-1)[0]; - if(lock == 'true') { - forge.log.lock(sConsoleLogger); - } - } -} - -// provide public access to console logger -forge.log.consoleLogger = sConsoleLogger; - -} // end module implementation - -/* ########## Begin module wrapper ########## */ -var name = 'log'; -if(typeof define !== 'function') { - // NodeJS -> AMD - if(typeof module === 'object' && module.exports) { - var nodeJS = true; - define = function(ids, factory) { - factory(require, module); - }; - } else { - // <script> - if(typeof forge === 'undefined') { - forge = {}; - } - return initModule(forge); - } -} -// AMD -var deps; -var defineFunc = function(require, module) { - module.exports = function(forge) { - var mods = deps.map(function(dep) { - return require(dep); - }).concat(initModule); - // handle circular dependencies - forge = forge || {}; - forge.defined = forge.defined || {}; - if(forge.defined[name]) { - return forge[name]; - } - forge.defined[name] = true; - for(var i = 0; i < mods.length; ++i) { - mods[i](forge); - } - return forge[name]; - }; -}; -var tmpDefine = define; -define = function(ids, factory) { - deps = (typeof ids === 'string') ? factory.slice(2) : ids.slice(2); - if(nodeJS) { - delete define; - return tmpDefine.apply(null, Array.prototype.slice.call(arguments, 0)); - } - define = tmpDefine; - return define.apply(null, Array.prototype.slice.call(arguments, 0)); -}; -define(['require', 'module', './util'], function() { - defineFunc.apply(null, Array.prototype.slice.call(arguments, 0)); -}); -})(); diff --git a/alarm/node_modules/node-forge/js/md.js b/alarm/node_modules/node-forge/js/md.js deleted file mode 100644 index e980cfd..0000000 --- a/alarm/node_modules/node-forge/js/md.js +++ /dev/null @@ -1,75 +0,0 @@ -/** - * Node.js module for Forge message digests. - * - * @author Dave Longley - * - * Copyright 2011-2014 Digital Bazaar, Inc. - */ -(function() { -/* ########## Begin module implementation ########## */ -function initModule(forge) { - -forge.md = forge.md || {}; -forge.md.algorithms = { - md5: forge.md5, - sha1: forge.sha1, - sha256: forge.sha256 -}; -forge.md.md5 = forge.md5; -forge.md.sha1 = forge.sha1; -forge.md.sha256 = forge.sha256; - -} // end module implementation - -/* ########## Begin module wrapper ########## */ -var name = 'md'; -if(typeof define !== 'function') { - // NodeJS -> AMD - if(typeof module === 'object' && module.exports) { - var nodeJS = true; - define = function(ids, factory) { - factory(require, module); - }; - } else { - // <script> - if(typeof forge === 'undefined') { - forge = {}; - } - return initModule(forge); - } -} -// AMD -var deps; -var defineFunc = function(require, module) { - module.exports = function(forge) { - var mods = deps.map(function(dep) { - return require(dep); - }).concat(initModule); - // handle circular dependencies - forge = forge || {}; - forge.defined = forge.defined || {}; - if(forge.defined[name]) { - return forge[name]; - } - forge.defined[name] = true; - for(var i = 0; i < mods.length; ++i) { - mods[i](forge); - } - return forge[name]; - }; -}; -var tmpDefine = define; -define = function(ids, factory) { - deps = (typeof ids === 'string') ? factory.slice(2) : ids.slice(2); - if(nodeJS) { - delete define; - return tmpDefine.apply(null, Array.prototype.slice.call(arguments, 0)); - } - define = tmpDefine; - return define.apply(null, Array.prototype.slice.call(arguments, 0)); -}; -define( - ['require', 'module', './md5', './sha1', './sha256', './sha512'], function() { - defineFunc.apply(null, Array.prototype.slice.call(arguments, 0)); -}); -})(); diff --git a/alarm/node_modules/node-forge/js/md5.js b/alarm/node_modules/node-forge/js/md5.js deleted file mode 100644 index acf7d11..0000000 --- a/alarm/node_modules/node-forge/js/md5.js +++ /dev/null @@ -1,322 +0,0 @@ -/** - * Message Digest Algorithm 5 with 128-bit digest (MD5) implementation. - * - * @author Dave Longley - * - * Copyright (c) 2010-2014 Digital Bazaar, Inc. - */ -(function() { -/* ########## Begin module implementation ########## */ -function initModule(forge) { - -var md5 = forge.md5 = forge.md5 || {}; -forge.md = forge.md || {}; -forge.md.algorithms = forge.md.algorithms || {}; -forge.md.md5 = forge.md.algorithms.md5 = md5; - -/** - * Creates an MD5 message digest object. - * - * @return a message digest object. - */ -md5.create = function() { - // do initialization as necessary - if(!_initialized) { - _init(); - } - - // MD5 state contains four 32-bit integers - var _state = null; - - // input buffer - var _input = forge.util.createBuffer(); - - // used for word storage - var _w = new Array(16); - - // message digest object - var md = { - algorithm: 'md5', - blockLength: 64, - digestLength: 16, - // 56-bit length of message so far (does not including padding) - messageLength: 0, - // true 64-bit message length as two 32-bit ints - messageLength64: [0, 0] - }; - - /** - * Starts the digest. - * - * @return this digest object. - */ - md.start = function() { - md.messageLength = 0; - md.messageLength64 = [0, 0]; - _input = forge.util.createBuffer(); - _state = { - h0: 0x67452301, - h1: 0xEFCDAB89, - h2: 0x98BADCFE, - h3: 0x10325476 - }; - return md; - }; - // start digest automatically for first time - md.start(); - - /** - * Updates the digest with the given message input. The given input can - * treated as raw input (no encoding will be applied) or an encoding of - * 'utf8' maybe given to encode the input using UTF-8. - * - * @param msg the message input to update with. - * @param encoding the encoding to use (default: 'raw', other: 'utf8'). - * - * @return this digest object. - */ - md.update = function(msg, encoding) { - if(encoding === 'utf8') { - msg = forge.util.encodeUtf8(msg); - } - - // update message length - md.messageLength += msg.length; - md.messageLength64[0] += (msg.length / 0x100000000) >>> 0; - md.messageLength64[1] += msg.length >>> 0; - - // add bytes to input buffer - _input.putBytes(msg); - - // process bytes - _update(_state, _w, _input); - - // compact input buffer every 2K or if empty - if(_input.read > 2048 || _input.length() === 0) { - _input.compact(); - } - - return md; - }; - - /** - * Produces the digest. - * - * @return a byte buffer containing the digest value. - */ - md.digest = function() { - /* Note: Here we copy the remaining bytes in the input buffer and - add the appropriate MD5 padding. Then we do the final update - on a copy of the state so that if the user wants to get - intermediate digests they can do so. */ - - /* Determine the number of bytes that must be added to the message - to ensure its length is congruent to 448 mod 512. In other words, - the data to be digested must be a multiple of 512 bits (or 128 bytes). - This data includes the message, some padding, and the length of the - message. Since the length of the message will be encoded as 8 bytes (64 - bits), that means that the last segment of the data must have 56 bytes - (448 bits) of message and padding. Therefore, the length of the message - plus the padding must be congruent to 448 mod 512 because - 512 - 128 = 448. - - In order to fill up the message length it must be filled with - padding that begins with 1 bit followed by all 0 bits. Padding - must *always* be present, so if the message length is already - congruent to 448 mod 512, then 512 padding bits must be added. */ - - // 512 bits == 64 bytes, 448 bits == 56 bytes, 64 bits = 8 bytes - // _padding starts with 1 byte with first bit is set in it which - // is byte value 128, then there may be up to 63 other pad bytes - var padBytes = forge.util.createBuffer(); - padBytes.putBytes(_input.bytes()); - // 64 - (remaining msg + 8 bytes msg length) mod 64 - padBytes.putBytes( - _padding.substr(0, 64 - ((md.messageLength64[1] + 8) & 0x3F))); - - /* Now append length of the message. The length is appended in bits - as a 64-bit number in little-endian order. Since we store the length in - bytes, we must multiply the 64-bit length by 8 (or left shift by 3). */ - padBytes.putInt32Le(md.messageLength64[1] << 3); - padBytes.putInt32Le( - (md.messageLength64[0] << 3) | (md.messageLength64[0] >>> 28)); - var s2 = { - h0: _state.h0, - h1: _state.h1, - h2: _state.h2, - h3: _state.h3 - }; - _update(s2, _w, padBytes); - var rval = forge.util.createBuffer(); - rval.putInt32Le(s2.h0); - rval.putInt32Le(s2.h1); - rval.putInt32Le(s2.h2); - rval.putInt32Le(s2.h3); - return rval; - }; - - return md; -}; - -// padding, constant tables for calculating md5 -var _padding = null; -var _g = null; -var _r = null; -var _k = null; -var _initialized = false; - -/** - * Initializes the constant tables. - */ -function _init() { - // create padding - _padding = String.fromCharCode(128); - _padding += forge.util.fillString(String.fromCharCode(0x00), 64); - - // g values - _g = [ - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, - 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2, - 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9]; - - // rounds table - _r = [ - 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, - 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, - 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, - 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21]; - - // get the result of abs(sin(i + 1)) as a 32-bit integer - _k = new Array(64); - for(var i = 0; i < 64; ++i) { - _k[i] = Math.floor(Math.abs(Math.sin(i + 1)) * 0x100000000); - } - - // now initialized - _initialized = true; -} - -/** - * Updates an MD5 state with the given byte buffer. - * - * @param s the MD5 state to update. - * @param w the array to use to store words. - * @param bytes the byte buffer to update with. - */ -function _update(s, w, bytes) { - // consume 512 bit (64 byte) chunks - var t, a, b, c, d, f, r, i; - var len = bytes.length(); - while(len >= 64) { - // initialize hash value for this chunk - a = s.h0; - b = s.h1; - c = s.h2; - d = s.h3; - - // round 1 - for(i = 0; i < 16; ++i) { - w[i] = bytes.getInt32Le(); - f = d ^ (b & (c ^ d)); - t = (a + f + _k[i] + w[i]); - r = _r[i]; - a = d; - d = c; - c = b; - b += (t << r) | (t >>> (32 - r)); - } - // round 2 - for(; i < 32; ++i) { - f = c ^ (d & (b ^ c)); - t = (a + f + _k[i] + w[_g[i]]); - r = _r[i]; - a = d; - d = c; - c = b; - b += (t << r) | (t >>> (32 - r)); - } - // round 3 - for(; i < 48; ++i) { - f = b ^ c ^ d; - t = (a + f + _k[i] + w[_g[i]]); - r = _r[i]; - a = d; - d = c; - c = b; - b += (t << r) | (t >>> (32 - r)); - } - // round 4 - for(; i < 64; ++i) { - f = c ^ (b | ~d); - t = (a + f + _k[i] + w[_g[i]]); - r = _r[i]; - a = d; - d = c; - c = b; - b += (t << r) | (t >>> (32 - r)); - } - - // update hash state - s.h0 = (s.h0 + a) | 0; - s.h1 = (s.h1 + b) | 0; - s.h2 = (s.h2 + c) | 0; - s.h3 = (s.h3 + d) | 0; - - len -= 64; - } -} - -} // end module implementation - -/* ########## Begin module wrapper ########## */ -var name = 'md5'; -if(typeof define !== 'function') { - // NodeJS -> AMD - if(typeof module === 'object' && module.exports) { - var nodeJS = true; - define = function(ids, factory) { - factory(require, module); - }; - } else { - // <script> - if(typeof forge === 'undefined') { - forge = {}; - } - return initModule(forge); - } -} -// AMD -var deps; -var defineFunc = function(require, module) { - module.exports = function(forge) { - var mods = deps.map(function(dep) { - return require(dep); - }).concat(initModule); - // handle circular dependencies - forge = forge || {}; - forge.defined = forge.defined || {}; - if(forge.defined[name]) { - return forge[name]; - } - forge.defined[name] = true; - for(var i = 0; i < mods.length; ++i) { - mods[i](forge); - } - return forge[name]; - }; -}; -var tmpDefine = define; -define = function(ids, factory) { - deps = (typeof ids === 'string') ? factory.slice(2) : ids.slice(2); - if(nodeJS) { - delete define; - return tmpDefine.apply(null, Array.prototype.slice.call(arguments, 0)); - } - define = tmpDefine; - return define.apply(null, Array.prototype.slice.call(arguments, 0)); -}; -define(['require', 'module', './util'], function() { - defineFunc.apply(null, Array.prototype.slice.call(arguments, 0)); -}); -})(); diff --git a/alarm/node_modules/node-forge/js/mgf.js b/alarm/node_modules/node-forge/js/mgf.js deleted file mode 100644 index 927082a..0000000 --- a/alarm/node_modules/node-forge/js/mgf.js +++ /dev/null @@ -1,67 +0,0 @@ -/** - * Node.js module for Forge mask generation functions. - * - * @author Stefan Siegl - * - * Copyright 2012 Stefan Siegl <stesie@brokenpipe.de> - */ -(function() { -/* ########## Begin module implementation ########## */ -function initModule(forge) { - -forge.mgf = forge.mgf || {}; -forge.mgf.mgf1 = forge.mgf1; - -} // end module implementation - -/* ########## Begin module wrapper ########## */ -var name = 'mgf'; -if(typeof define !== 'function') { - // NodeJS -> AMD - if(typeof module === 'object' && module.exports) { - var nodeJS = true; - define = function(ids, factory) { - factory(require, module); - }; - } else { - // <script> - if(typeof forge === 'undefined') { - forge = {}; - } - return initModule(forge); - } -} -// AMD -var deps; -var defineFunc = function(require, module) { - module.exports = function(forge) { - var mods = deps.map(function(dep) { - return require(dep); - }).concat(initModule); - // handle circular dependencies - forge = forge || {}; - forge.defined = forge.defined || {}; - if(forge.defined[name]) { - return forge[name]; - } - forge.defined[name] = true; - for(var i = 0; i < mods.length; ++i) { - mods[i](forge); - } - return forge[name]; - }; -}; -var tmpDefine = define; -define = function(ids, factory) { - deps = (typeof ids === 'string') ? factory.slice(2) : ids.slice(2); - if(nodeJS) { - delete define; - return tmpDefine.apply(null, Array.prototype.slice.call(arguments, 0)); - } - define = tmpDefine; - return define.apply(null, Array.prototype.slice.call(arguments, 0)); -}; -define(['require', 'module', './mgf1'], function() { - defineFunc.apply(null, Array.prototype.slice.call(arguments, 0)); -}); -})(); diff --git a/alarm/node_modules/node-forge/js/mgf1.js b/alarm/node_modules/node-forge/js/mgf1.js deleted file mode 100644 index 82d62cd..0000000 --- a/alarm/node_modules/node-forge/js/mgf1.js +++ /dev/null @@ -1,112 +0,0 @@ -/** - * Javascript implementation of mask generation function MGF1. - * - * @author Stefan Siegl - * @author Dave Longley - * - * Copyright (c) 2012 Stefan Siegl <stesie@brokenpipe.de> - * Copyright (c) 2014 Digital Bazaar, Inc. - */ -(function() { -/* ########## Begin module implementation ########## */ -function initModule(forge) { - -forge.mgf = forge.mgf || {}; -var mgf1 = forge.mgf.mgf1 = forge.mgf1 = forge.mgf1 || {}; - -/** - * Creates a MGF1 mask generation function object. - * - * @param md the message digest API to use (eg: forge.md.sha1.create()). - * - * @return a mask generation function object. - */ -mgf1.create = function(md) { - var mgf = { - /** - * Generate mask of specified length. - * - * @param {String} seed The seed for mask generation. - * @param maskLen Number of bytes to generate. - * @return {String} The generated mask. - */ - generate: function(seed, maskLen) { - /* 2. Let T be the empty octet string. */ - var t = new forge.util.ByteBuffer(); - - /* 3. For counter from 0 to ceil(maskLen / hLen), do the following: */ - var len = Math.ceil(maskLen / md.digestLength); - for(var i = 0; i < len; i++) { - /* a. Convert counter to an octet string C of length 4 octets */ - var c = new forge.util.ByteBuffer(); - c.putInt32(i); - - /* b. Concatenate the hash of the seed mgfSeed and C to the octet - * string T: */ - md.start(); - md.update(seed + c.getBytes()); - t.putBuffer(md.digest()); - } - - /* Output the leading maskLen octets of T as the octet string mask. */ - t.truncate(t.length() - maskLen); - return t.getBytes(); - } - }; - - return mgf; -}; - -} // end module implementation - -/* ########## Begin module wrapper ########## */ -var name = 'mgf1'; -if(typeof define !== 'function') { - // NodeJS -> AMD - if(typeof module === 'object' && module.exports) { - var nodeJS = true; - define = function(ids, factory) { - factory(require, module); - }; - } else { - // <script> - if(typeof forge === 'undefined') { - forge = {}; - } - return initModule(forge); - } -} -// AMD -var deps; -var defineFunc = function(require, module) { - module.exports = function(forge) { - var mods = deps.map(function(dep) { - return require(dep); - }).concat(initModule); - // handle circular dependencies - forge = forge || {}; - forge.defined = forge.defined || {}; - if(forge.defined[name]) { - return forge[name]; - } - forge.defined[name] = true; - for(var i = 0; i < mods.length; ++i) { - mods[i](forge); - } - return forge[name]; - }; -}; -var tmpDefine = define; -define = function(ids, factory) { - deps = (typeof ids === 'string') ? factory.slice(2) : ids.slice(2); - if(nodeJS) { - delete define; - return tmpDefine.apply(null, Array.prototype.slice.call(arguments, 0)); - } - define = tmpDefine; - return define.apply(null, Array.prototype.slice.call(arguments, 0)); -}; -define(['require', 'module', './util'], function() { - defineFunc.apply(null, Array.prototype.slice.call(arguments, 0)); -}); -})(); diff --git a/alarm/node_modules/node-forge/js/oids.js b/alarm/node_modules/node-forge/js/oids.js deleted file mode 100644 index ef3e67d..0000000 --- a/alarm/node_modules/node-forge/js/oids.js +++ /dev/null @@ -1,269 +0,0 @@ -/** - * Object IDs for ASN.1. - * - * @author Dave Longley - * - * Copyright (c) 2010-2013 Digital Bazaar, Inc. - */ -(function() { -/* ########## Begin module implementation ########## */ -function initModule(forge) { - -forge.pki = forge.pki || {}; -var oids = forge.pki.oids = forge.oids = forge.oids || {}; - -// algorithm OIDs -oids['1.2.840.113549.1.1.1'] = 'rsaEncryption'; -oids['rsaEncryption'] = '1.2.840.113549.1.1.1'; -// Note: md2 & md4 not implemented -//oids['1.2.840.113549.1.1.2'] = 'md2WithRSAEncryption'; -//oids['md2WithRSAEncryption'] = '1.2.840.113549.1.1.2'; -//oids['1.2.840.113549.1.1.3'] = 'md4WithRSAEncryption'; -//oids['md4WithRSAEncryption'] = '1.2.840.113549.1.1.3'; -oids['1.2.840.113549.1.1.4'] = 'md5WithRSAEncryption'; -oids['md5WithRSAEncryption'] = '1.2.840.113549.1.1.4'; -oids['1.2.840.113549.1.1.5'] = 'sha1WithRSAEncryption'; -oids['sha1WithRSAEncryption'] = '1.2.840.113549.1.1.5'; -oids['1.2.840.113549.1.1.7'] = 'RSAES-OAEP'; -oids['RSAES-OAEP'] = '1.2.840.113549.1.1.7'; -oids['1.2.840.113549.1.1.8'] = 'mgf1'; -oids['mgf1'] = '1.2.840.113549.1.1.8'; -oids['1.2.840.113549.1.1.9'] = 'pSpecified'; -oids['pSpecified'] = '1.2.840.113549.1.1.9'; -oids['1.2.840.113549.1.1.10'] = 'RSASSA-PSS'; -oids['RSASSA-PSS'] = '1.2.840.113549.1.1.10'; -oids['1.2.840.113549.1.1.11'] = 'sha256WithRSAEncryption'; -oids['sha256WithRSAEncryption'] = '1.2.840.113549.1.1.11'; -oids['1.2.840.113549.1.1.12'] = 'sha384WithRSAEncryption'; -oids['sha384WithRSAEncryption'] = '1.2.840.113549.1.1.12'; -oids['1.2.840.113549.1.1.13'] = 'sha512WithRSAEncryption'; -oids['sha512WithRSAEncryption'] = '1.2.840.113549.1.1.13'; - -oids['1.3.14.3.2.7'] = 'desCBC'; -oids['desCBC'] = '1.3.14.3.2.7'; - -oids['1.3.14.3.2.26'] = 'sha1'; -oids['sha1'] = '1.3.14.3.2.26'; -oids['2.16.840.1.101.3.4.2.1'] = 'sha256'; -oids['sha256'] = '2.16.840.1.101.3.4.2.1'; -oids['2.16.840.1.101.3.4.2.2'] = 'sha384'; -oids['sha384'] = '2.16.840.1.101.3.4.2.2'; -oids['2.16.840.1.101.3.4.2.3'] = 'sha512'; -oids['sha512'] = '2.16.840.1.101.3.4.2.3'; -oids['1.2.840.113549.2.5'] = 'md5'; -oids['md5'] = '1.2.840.113549.2.5'; - -// pkcs#7 content types -oids['1.2.840.113549.1.7.1'] = 'data'; -oids['data'] = '1.2.840.113549.1.7.1'; -oids['1.2.840.113549.1.7.2'] = 'signedData'; -oids['signedData'] = '1.2.840.113549.1.7.2'; -oids['1.2.840.113549.1.7.3'] = 'envelopedData'; -oids['envelopedData'] = '1.2.840.113549.1.7.3'; -oids['1.2.840.113549.1.7.4'] = 'signedAndEnvelopedData'; -oids['signedAndEnvelopedData'] = '1.2.840.113549.1.7.4'; -oids['1.2.840.113549.1.7.5'] = 'digestedData'; -oids['digestedData'] = '1.2.840.113549.1.7.5'; -oids['1.2.840.113549.1.7.6'] = 'encryptedData'; -oids['encryptedData'] = '1.2.840.113549.1.7.6'; - -// pkcs#9 oids -oids['1.2.840.113549.1.9.1'] = 'emailAddress'; -oids['emailAddress'] = '1.2.840.113549.1.9.1'; -oids['1.2.840.113549.1.9.2'] = 'unstructuredName'; -oids['unstructuredName'] = '1.2.840.113549.1.9.2'; -oids['1.2.840.113549.1.9.3'] = 'contentType'; -oids['contentType'] = '1.2.840.113549.1.9.3'; -oids['1.2.840.113549.1.9.4'] = 'messageDigest'; -oids['messageDigest'] = '1.2.840.113549.1.9.4'; -oids['1.2.840.113549.1.9.5'] = 'signingTime'; -oids['signingTime'] = '1.2.840.113549.1.9.5'; -oids['1.2.840.113549.1.9.6'] = 'counterSignature'; -oids['counterSignature'] = '1.2.840.113549.1.9.6'; -oids['1.2.840.113549.1.9.7'] = 'challengePassword'; -oids['challengePassword'] = '1.2.840.113549.1.9.7'; -oids['1.2.840.113549.1.9.8'] = 'unstructuredAddress'; -oids['unstructuredAddress'] = '1.2.840.113549.1.9.8'; -oids['1.2.840.113549.1.9.14'] = 'extensionRequest'; -oids['extensionRequest'] = '1.2.840.113549.1.9.14'; - -oids['1.2.840.113549.1.9.20'] = 'friendlyName'; -oids['friendlyName'] = '1.2.840.113549.1.9.20'; -oids['1.2.840.113549.1.9.21'] = 'localKeyId'; -oids['localKeyId'] = '1.2.840.113549.1.9.21'; -oids['1.2.840.113549.1.9.22.1'] = 'x509Certificate'; -oids['x509Certificate'] = '1.2.840.113549.1.9.22.1'; - -// pkcs#12 safe bags -oids['1.2.840.113549.1.12.10.1.1'] = 'keyBag'; -oids['keyBag'] = '1.2.840.113549.1.12.10.1.1'; -oids['1.2.840.113549.1.12.10.1.2'] = 'pkcs8ShroudedKeyBag'; -oids['pkcs8ShroudedKeyBag'] = '1.2.840.113549.1.12.10.1.2'; -oids['1.2.840.113549.1.12.10.1.3'] = 'certBag'; -oids['certBag'] = '1.2.840.113549.1.12.10.1.3'; -oids['1.2.840.113549.1.12.10.1.4'] = 'crlBag'; -oids['crlBag'] = '1.2.840.113549.1.12.10.1.4'; -oids['1.2.840.113549.1.12.10.1.5'] = 'secretBag'; -oids['secretBag'] = '1.2.840.113549.1.12.10.1.5'; -oids['1.2.840.113549.1.12.10.1.6'] = 'safeContentsBag'; -oids['safeContentsBag'] = '1.2.840.113549.1.12.10.1.6'; - -// password-based-encryption for pkcs#12 -oids['1.2.840.113549.1.5.13'] = 'pkcs5PBES2'; -oids['pkcs5PBES2'] = '1.2.840.113549.1.5.13'; -oids['1.2.840.113549.1.5.12'] = 'pkcs5PBKDF2'; -oids['pkcs5PBKDF2'] = '1.2.840.113549.1.5.12'; - -oids['1.2.840.113549.1.12.1.1'] = 'pbeWithSHAAnd128BitRC4'; -oids['pbeWithSHAAnd128BitRC4'] = '1.2.840.113549.1.12.1.1'; -oids['1.2.840.113549.1.12.1.2'] = 'pbeWithSHAAnd40BitRC4'; -oids['pbeWithSHAAnd40BitRC4'] = '1.2.840.113549.1.12.1.2'; -oids['1.2.840.113549.1.12.1.3'] = 'pbeWithSHAAnd3-KeyTripleDES-CBC'; -oids['pbeWithSHAAnd3-KeyTripleDES-CBC'] = '1.2.840.113549.1.12.1.3'; -oids['1.2.840.113549.1.12.1.4'] = 'pbeWithSHAAnd2-KeyTripleDES-CBC'; -oids['pbeWithSHAAnd2-KeyTripleDES-CBC'] = '1.2.840.113549.1.12.1.4'; -oids['1.2.840.113549.1.12.1.5'] = 'pbeWithSHAAnd128BitRC2-CBC'; -oids['pbeWithSHAAnd128BitRC2-CBC'] = '1.2.840.113549.1.12.1.5'; -oids['1.2.840.113549.1.12.1.6'] = 'pbewithSHAAnd40BitRC2-CBC'; -oids['pbewithSHAAnd40BitRC2-CBC'] = '1.2.840.113549.1.12.1.6'; - -// symmetric key algorithm oids -oids['1.2.840.113549.3.7'] = 'des-EDE3-CBC'; -oids['des-EDE3-CBC'] = '1.2.840.113549.3.7'; -oids['2.16.840.1.101.3.4.1.2'] = 'aes128-CBC'; -oids['aes128-CBC'] = '2.16.840.1.101.3.4.1.2'; -oids['2.16.840.1.101.3.4.1.22'] = 'aes192-CBC'; -oids['aes192-CBC'] = '2.16.840.1.101.3.4.1.22'; -oids['2.16.840.1.101.3.4.1.42'] = 'aes256-CBC'; -oids['aes256-CBC'] = '2.16.840.1.101.3.4.1.42'; - -// certificate issuer/subject OIDs -oids['2.5.4.3'] = 'commonName'; -oids['commonName'] = '2.5.4.3'; -oids['2.5.4.5'] = 'serialName'; -oids['serialName'] = '2.5.4.5'; -oids['2.5.4.6'] = 'countryName'; -oids['countryName'] = '2.5.4.6'; -oids['2.5.4.7'] = 'localityName'; -oids['localityName'] = '2.5.4.7'; -oids['2.5.4.8'] = 'stateOrProvinceName'; -oids['stateOrProvinceName'] = '2.5.4.8'; -oids['2.5.4.10'] = 'organizationName'; -oids['organizationName'] = '2.5.4.10'; -oids['2.5.4.11'] = 'organizationalUnitName'; -oids['organizationalUnitName'] = '2.5.4.11'; - -// X.509 extension OIDs -oids['2.16.840.1.113730.1.1'] = 'nsCertType'; -oids['nsCertType'] = '2.16.840.1.113730.1.1'; -oids['2.5.29.1'] = 'authorityKeyIdentifier'; // deprecated, use .35 -oids['2.5.29.2'] = 'keyAttributes'; // obsolete use .37 or .15 -oids['2.5.29.3'] = 'certificatePolicies'; // deprecated, use .32 -oids['2.5.29.4'] = 'keyUsageRestriction'; // obsolete use .37 or .15 -oids['2.5.29.5'] = 'policyMapping'; // deprecated use .33 -oids['2.5.29.6'] = 'subtreesConstraint'; // obsolete use .30 -oids['2.5.29.7'] = 'subjectAltName'; // deprecated use .17 -oids['2.5.29.8'] = 'issuerAltName'; // deprecated use .18 -oids['2.5.29.9'] = 'subjectDirectoryAttributes'; -oids['2.5.29.10'] = 'basicConstraints'; // deprecated use .19 -oids['2.5.29.11'] = 'nameConstraints'; // deprecated use .30 -oids['2.5.29.12'] = 'policyConstraints'; // deprecated use .36 -oids['2.5.29.13'] = 'basicConstraints'; // deprecated use .19 -oids['2.5.29.14'] = 'subjectKeyIdentifier'; -oids['subjectKeyIdentifier'] = '2.5.29.14'; -oids['2.5.29.15'] = 'keyUsage'; -oids['keyUsage'] = '2.5.29.15'; -oids['2.5.29.16'] = 'privateKeyUsagePeriod'; -oids['2.5.29.17'] = 'subjectAltName'; -oids['subjectAltName'] = '2.5.29.17'; -oids['2.5.29.18'] = 'issuerAltName'; -oids['issuerAltName'] = '2.5.29.18'; -oids['2.5.29.19'] = 'basicConstraints'; -oids['basicConstraints'] = '2.5.29.19'; -oids['2.5.29.20'] = 'cRLNumber'; -oids['2.5.29.21'] = 'cRLReason'; -oids['2.5.29.22'] = 'expirationDate'; -oids['2.5.29.23'] = 'instructionCode'; -oids['2.5.29.24'] = 'invalidityDate'; -oids['2.5.29.25'] = 'cRLDistributionPoints'; // deprecated use .31 -oids['2.5.29.26'] = 'issuingDistributionPoint'; // deprecated use .28 -oids['2.5.29.27'] = 'deltaCRLIndicator'; -oids['2.5.29.28'] = 'issuingDistributionPoint'; -oids['2.5.29.29'] = 'certificateIssuer'; -oids['2.5.29.30'] = 'nameConstraints'; -oids['2.5.29.31'] = 'cRLDistributionPoints'; -oids['2.5.29.32'] = 'certificatePolicies'; -oids['2.5.29.33'] = 'policyMappings'; -oids['2.5.29.34'] = 'policyConstraints'; // deprecated use .36 -oids['2.5.29.35'] = 'authorityKeyIdentifier'; -oids['2.5.29.36'] = 'policyConstraints'; -oids['2.5.29.37'] = 'extKeyUsage'; -oids['extKeyUsage'] = '2.5.29.37'; -oids['2.5.29.46'] = 'freshestCRL'; -oids['2.5.29.54'] = 'inhibitAnyPolicy'; - -// extKeyUsage purposes -oids['1.3.6.1.5.5.7.3.1'] = 'serverAuth'; -oids['serverAuth'] = '1.3.6.1.5.5.7.3.1'; -oids['1.3.6.1.5.5.7.3.2'] = 'clientAuth'; -oids['clientAuth'] = '1.3.6.1.5.5.7.3.2'; -oids['1.3.6.1.5.5.7.3.3'] = 'codeSigning'; -oids['codeSigning'] = '1.3.6.1.5.5.7.3.3'; -oids['1.3.6.1.5.5.7.3.4'] = 'emailProtection'; -oids['emailProtection'] = '1.3.6.1.5.5.7.3.4'; -oids['1.3.6.1.5.5.7.3.8'] = 'timeStamping'; -oids['timeStamping'] = '1.3.6.1.5.5.7.3.8'; - -} // end module implementation - -/* ########## Begin module wrapper ########## */ -var name = 'oids'; -if(typeof define !== 'function') { - // NodeJS -> AMD - if(typeof module === 'object' && module.exports) { - var nodeJS = true; - define = function(ids, factory) { - factory(require, module); - }; - } else { - // <script> - if(typeof forge === 'undefined') { - forge = {}; - } - return initModule(forge); - } -} -// AMD -var deps; -var defineFunc = function(require, module) { - module.exports = function(forge) { - var mods = deps.map(function(dep) { - return require(dep); - }).concat(initModule); - // handle circular dependencies - forge = forge || {}; - forge.defined = forge.defined || {}; - if(forge.defined[name]) { - return forge[name]; - } - forge.defined[name] = true; - for(var i = 0; i < mods.length; ++i) { - mods[i](forge); - } - return forge[name]; - }; -}; -var tmpDefine = define; -define = function(ids, factory) { - deps = (typeof ids === 'string') ? factory.slice(2) : ids.slice(2); - if(nodeJS) { - delete define; - return tmpDefine.apply(null, Array.prototype.slice.call(arguments, 0)); - } - define = tmpDefine; - return define.apply(null, Array.prototype.slice.call(arguments, 0)); -}; -define(['require', 'module'], function() { - defineFunc.apply(null, Array.prototype.slice.call(arguments, 0)); -}); -})(); diff --git a/alarm/node_modules/node-forge/js/pbe.js b/alarm/node_modules/node-forge/js/pbe.js deleted file mode 100644 index 0b25758..0000000 --- a/alarm/node_modules/node-forge/js/pbe.js +++ /dev/null @@ -1,975 +0,0 @@ -/** - * Password-based encryption functions. - * - * @author Dave Longley - * @author Stefan Siegl <stesie@brokenpipe.de> - * - * Copyright (c) 2010-2013 Digital Bazaar, Inc. - * Copyright (c) 2012 Stefan Siegl <stesie@brokenpipe.de> - * - * An EncryptedPrivateKeyInfo: - * - * EncryptedPrivateKeyInfo ::= SEQUENCE { - * encryptionAlgorithm EncryptionAlgorithmIdentifier, - * encryptedData EncryptedData } - * - * EncryptionAlgorithmIdentifier ::= AlgorithmIdentifier - * - * EncryptedData ::= OCTET STRING - */ -(function() { -/* ########## Begin module implementation ########## */ -function initModule(forge) { - -if(typeof BigInteger === 'undefined') { - var BigInteger = forge.jsbn.BigInteger; -} - -// shortcut for asn.1 API -var asn1 = forge.asn1; - -/* Password-based encryption implementation. */ -var pki = forge.pki = forge.pki || {}; -pki.pbe = forge.pbe = forge.pbe || {}; -var oids = pki.oids; - -// validator for an EncryptedPrivateKeyInfo structure -// Note: Currently only works w/algorithm params -var encryptedPrivateKeyValidator = { - name: 'EncryptedPrivateKeyInfo', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.SEQUENCE, - constructed: true, - value: [{ - name: 'EncryptedPrivateKeyInfo.encryptionAlgorithm', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.SEQUENCE, - constructed: true, - value: [{ - name: 'AlgorithmIdentifier.algorithm', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.OID, - constructed: false, - capture: 'encryptionOid' - }, { - name: 'AlgorithmIdentifier.parameters', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.SEQUENCE, - constructed: true, - captureAsn1: 'encryptionParams' - }] - }, { - // encryptedData - name: 'EncryptedPrivateKeyInfo.encryptedData', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.OCTETSTRING, - constructed: false, - capture: 'encryptedData' - }] -}; - -// validator for a PBES2Algorithms structure -// Note: Currently only works w/PBKDF2 + AES encryption schemes -var PBES2AlgorithmsValidator = { - name: 'PBES2Algorithms', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.SEQUENCE, - constructed: true, - value: [{ - name: 'PBES2Algorithms.keyDerivationFunc', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.SEQUENCE, - constructed: true, - value: [{ - name: 'PBES2Algorithms.keyDerivationFunc.oid', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.OID, - constructed: false, - capture: 'kdfOid' - }, { - name: 'PBES2Algorithms.params', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.SEQUENCE, - constructed: true, - value: [{ - name: 'PBES2Algorithms.params.salt', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.OCTETSTRING, - constructed: false, - capture: 'kdfSalt' - }, { - name: 'PBES2Algorithms.params.iterationCount', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.INTEGER, - onstructed: true, - capture: 'kdfIterationCount' - }] - }] - }, { - name: 'PBES2Algorithms.encryptionScheme', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.SEQUENCE, - constructed: true, - value: [{ - name: 'PBES2Algorithms.encryptionScheme.oid', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.OID, - constructed: false, - capture: 'encOid' - }, { - name: 'PBES2Algorithms.encryptionScheme.iv', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.OCTETSTRING, - constructed: false, - capture: 'encIv' - }] - }] -}; - -var pkcs12PbeParamsValidator = { - name: 'pkcs-12PbeParams', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.SEQUENCE, - constructed: true, - value: [{ - name: 'pkcs-12PbeParams.salt', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.OCTETSTRING, - constructed: false, - capture: 'salt' - }, { - name: 'pkcs-12PbeParams.iterations', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.INTEGER, - constructed: false, - capture: 'iterations' - }] -}; - -/** - * Encrypts a ASN.1 PrivateKeyInfo object, producing an EncryptedPrivateKeyInfo. - * - * PBES2Algorithms ALGORITHM-IDENTIFIER ::= - * { {PBES2-params IDENTIFIED BY id-PBES2}, ...} - * - * id-PBES2 OBJECT IDENTIFIER ::= {pkcs-5 13} - * - * PBES2-params ::= SEQUENCE { - * keyDerivationFunc AlgorithmIdentifier {{PBES2-KDFs}}, - * encryptionScheme AlgorithmIdentifier {{PBES2-Encs}} - * } - * - * PBES2-KDFs ALGORITHM-IDENTIFIER ::= - * { {PBKDF2-params IDENTIFIED BY id-PBKDF2}, ... } - * - * PBES2-Encs ALGORITHM-IDENTIFIER ::= { ... } - * - * PBKDF2-params ::= SEQUENCE { - * salt CHOICE { - * specified OCTET STRING, - * otherSource AlgorithmIdentifier {{PBKDF2-SaltSources}} - * }, - * iterationCount INTEGER (1..MAX), - * keyLength INTEGER (1..MAX) OPTIONAL, - * prf AlgorithmIdentifier {{PBKDF2-PRFs}} DEFAULT algid-hmacWithSHA1 - * } - * - * @param obj the ASN.1 PrivateKeyInfo object. - * @param password the password to encrypt with. - * @param options: - * algorithm the encryption algorithm to use - * ('aes128', 'aes192', 'aes256', '3des'), defaults to 'aes128'. - * count the iteration count to use. - * saltSize the salt size to use. - * - * @return the ASN.1 EncryptedPrivateKeyInfo. - */ -pki.encryptPrivateKeyInfo = function(obj, password, options) { - // set default options - options = options || {}; - options.saltSize = options.saltSize || 8; - options.count = options.count || 2048; - options.algorithm = options.algorithm || 'aes128'; - - // generate PBE params - var salt = forge.random.getBytesSync(options.saltSize); - var count = options.count; - var countBytes = asn1.integerToDer(count); - var dkLen; - var encryptionAlgorithm; - var encryptedData; - if(options.algorithm.indexOf('aes') === 0 || options.algorithm === 'des') { - // Do PBES2 - var ivLen, encOid, cipherFn; - switch(options.algorithm) { - case 'aes128': - dkLen = 16; - ivLen = 16; - encOid = oids['aes128-CBC']; - cipherFn = forge.aes.createEncryptionCipher; - break; - case 'aes192': - dkLen = 24; - ivLen = 16; - encOid = oids['aes192-CBC']; - cipherFn = forge.aes.createEncryptionCipher; - break; - case 'aes256': - dkLen = 32; - ivLen = 16; - encOid = oids['aes256-CBC']; - cipherFn = forge.aes.createEncryptionCipher; - break; - case 'des': - dkLen = 8; - ivLen = 8; - encOid = oids['desCBC']; - cipherFn = forge.des.createEncryptionCipher; - break; - default: - var error = new Error('Cannot encrypt private key. Unknown encryption algorithm.'); - error.algorithm = options.algorithm; - throw error; - } - - // encrypt private key using pbe SHA-1 and AES/DES - var dk = forge.pkcs5.pbkdf2(password, salt, count, dkLen); - var iv = forge.random.getBytesSync(ivLen); - var cipher = cipherFn(dk); - cipher.start(iv); - cipher.update(asn1.toDer(obj)); - cipher.finish(); - encryptedData = cipher.output.getBytes(); - - encryptionAlgorithm = asn1.create( - asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [ - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, - asn1.oidToDer(oids['pkcs5PBES2']).getBytes()), - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [ - // keyDerivationFunc - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [ - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, - asn1.oidToDer(oids['pkcs5PBKDF2']).getBytes()), - // PBKDF2-params - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [ - // salt - asn1.create( - asn1.Class.UNIVERSAL, asn1.Type.OCTETSTRING, false, salt), - // iteration count - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false, - countBytes.getBytes()) - ]) - ]), - // encryptionScheme - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [ - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, - asn1.oidToDer(encOid).getBytes()), - // iv - asn1.create( - asn1.Class.UNIVERSAL, asn1.Type.OCTETSTRING, false, iv) - ]) - ]) - ]); - } else if(options.algorithm === '3des') { - // Do PKCS12 PBE - dkLen = 24; - - var saltBytes = new forge.util.ByteBuffer(salt); - var dk = pki.pbe.generatePkcs12Key(password, saltBytes, 1, count, dkLen); - var iv = pki.pbe.generatePkcs12Key(password, saltBytes, 2, count, dkLen); - var cipher = forge.des.createEncryptionCipher(dk); - cipher.start(iv); - cipher.update(asn1.toDer(obj)); - cipher.finish(); - encryptedData = cipher.output.getBytes(); - - encryptionAlgorithm = asn1.create( - asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [ - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, - asn1.oidToDer(oids['pbeWithSHAAnd3-KeyTripleDES-CBC']).getBytes()), - // pkcs-12PbeParams - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [ - // salt - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OCTETSTRING, false, salt), - // iteration count - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false, - countBytes.getBytes()) - ]) - ]); - } else { - var error = new Error('Cannot encrypt private key. Unknown encryption algorithm.'); - error.algorithm = options.algorithm; - throw error; - } - - // EncryptedPrivateKeyInfo - var rval = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [ - // encryptionAlgorithm - encryptionAlgorithm, - // encryptedData - asn1.create( - asn1.Class.UNIVERSAL, asn1.Type.OCTETSTRING, false, encryptedData) - ]); - return rval; -}; - -/** - * Decrypts a ASN.1 PrivateKeyInfo object. - * - * @param obj the ASN.1 EncryptedPrivateKeyInfo object. - * @param password the password to decrypt with. - * - * @return the ASN.1 PrivateKeyInfo on success, null on failure. - */ -pki.decryptPrivateKeyInfo = function(obj, password) { - var rval = null; - - // get PBE params - var capture = {}; - var errors = []; - if(!asn1.validate(obj, encryptedPrivateKeyValidator, capture, errors)) { - var error = new Error('Cannot read encrypted private key. ' + - 'ASN.1 object is not a supported EncryptedPrivateKeyInfo.'); - error.errors = errors; - throw error; - } - - // get cipher - var oid = asn1.derToOid(capture.encryptionOid); - var cipher = pki.pbe.getCipher(oid, capture.encryptionParams, password); - - // get encrypted data - var encrypted = forge.util.createBuffer(capture.encryptedData); - - cipher.update(encrypted); - if(cipher.finish()) { - rval = asn1.fromDer(cipher.output); - } - - return rval; -}; - -/** - * Converts a EncryptedPrivateKeyInfo to PEM format. - * - * @param epki the EncryptedPrivateKeyInfo. - * @param maxline the maximum characters per line, defaults to 64. - * - * @return the PEM-formatted encrypted private key. - */ -pki.encryptedPrivateKeyToPem = function(epki, maxline) { - // convert to DER, then PEM-encode - var msg = { - type: 'ENCRYPTED PRIVATE KEY', - body: asn1.toDer(epki).getBytes() - }; - return forge.pem.encode(msg, {maxline: maxline}); -}; - -/** - * Converts a PEM-encoded EncryptedPrivateKeyInfo to ASN.1 format. Decryption - * is not performed. - * - * @param pem the EncryptedPrivateKeyInfo in PEM-format. - * - * @return the ASN.1 EncryptedPrivateKeyInfo. - */ -pki.encryptedPrivateKeyFromPem = function(pem) { - var msg = forge.pem.decode(pem)[0]; - - if(msg.type !== 'ENCRYPTED PRIVATE KEY') { - var error = new Error('Could not convert encrypted private key from PEM; ' + - 'PEM header type is "ENCRYPTED PRIVATE KEY".'); - error.headerType = msg.type; - throw error; - } - if(msg.procType && msg.procType.type === 'ENCRYPTED') { - throw new Error('Could not convert encrypted private key from PEM; ' + - 'PEM is encrypted.'); - } - - // convert DER to ASN.1 object - return asn1.fromDer(msg.body); -}; - -/** - * Encrypts an RSA private key. By default, the key will be wrapped in - * a PrivateKeyInfo and encrypted to produce a PKCS#8 EncryptedPrivateKeyInfo. - * This is the standard, preferred way to encrypt a private key. - * - * To produce a non-standard PEM-encrypted private key that uses encapsulated - * headers to indicate the encryption algorithm (old-style non-PKCS#8 OpenSSL - * private key encryption), set the 'legacy' option to true. Note: Using this - * option will cause the iteration count to be forced to 1. - * - * Note: The 'des' algorithm is supported, but it is not considered to be - * secure because it only uses a single 56-bit key. If possible, it is highly - * recommended that a different algorithm be used. - * - * @param rsaKey the RSA key to encrypt. - * @param password the password to use. - * @param options: - * algorithm: the encryption algorithm to use - * ('aes128', 'aes192', 'aes256', '3des', 'des'). - * count: the iteration count to use. - * saltSize: the salt size to use. - * legacy: output an old non-PKCS#8 PEM-encrypted+encapsulated - * headers (DEK-Info) private key. - * - * @return the PEM-encoded ASN.1 EncryptedPrivateKeyInfo. - */ -pki.encryptRsaPrivateKey = function(rsaKey, password, options) { - // standard PKCS#8 - options = options || {}; - if(!options.legacy) { - // encrypt PrivateKeyInfo - var rval = pki.wrapRsaPrivateKey(pki.privateKeyToAsn1(rsaKey)); - rval = pki.encryptPrivateKeyInfo(rval, password, options); - return pki.encryptedPrivateKeyToPem(rval); - } - - // legacy non-PKCS#8 - var algorithm; - var iv; - var dkLen; - var cipherFn; - switch(options.algorithm) { - case 'aes128': - algorithm = 'AES-128-CBC'; - dkLen = 16; - iv = forge.random.getBytesSync(16); - cipherFn = forge.aes.createEncryptionCipher; - break; - case 'aes192': - algorithm = 'AES-192-CBC'; - dkLen = 24; - iv = forge.random.getBytesSync(16); - cipherFn = forge.aes.createEncryptionCipher; - break; - case 'aes256': - algorithm = 'AES-256-CBC'; - dkLen = 32; - iv = forge.random.getBytesSync(16); - cipherFn = forge.aes.createEncryptionCipher; - break; - case '3des': - algorithm = 'DES-EDE3-CBC'; - dkLen = 24; - iv = forge.random.getBytesSync(8); - cipherFn = forge.des.createEncryptionCipher; - break; - case 'des': - algorithm = 'DES-CBC'; - dkLen = 8; - iv = forge.random.getBytesSync(8); - cipherFn = forge.des.createEncryptionCipher; - break; - default: - var error = new Error('Could not encrypt RSA private key; unsupported ' + - 'encryption algorithm "' + options.algorithm + '".'); - error.algorithm = options.algorithm; - throw error; - } - - // encrypt private key using OpenSSL legacy key derivation - var dk = forge.pbe.opensslDeriveBytes(password, iv.substr(0, 8), dkLen); - var cipher = cipherFn(dk); - cipher.start(iv); - cipher.update(asn1.toDer(pki.privateKeyToAsn1(rsaKey))); - cipher.finish(); - - var msg = { - type: 'RSA PRIVATE KEY', - procType: { - version: '4', - type: 'ENCRYPTED' - }, - dekInfo: { - algorithm: algorithm, - parameters: forge.util.bytesToHex(iv).toUpperCase() - }, - body: cipher.output.getBytes() - }; - return forge.pem.encode(msg); -}; - -/** - * Decrypts an RSA private key. - * - * @param pem the PEM-formatted EncryptedPrivateKeyInfo to decrypt. - * @param password the password to use. - * - * @return the RSA key on success, null on failure. - */ -pki.decryptRsaPrivateKey = function(pem, password) { - var rval = null; - - var msg = forge.pem.decode(pem)[0]; - - if(msg.type !== 'ENCRYPTED PRIVATE KEY' && - msg.type !== 'PRIVATE KEY' && - msg.type !== 'RSA PRIVATE KEY') { - var error = new Error('Could not convert private key from PEM; PEM header type ' + - 'is not "ENCRYPTED PRIVATE KEY", "PRIVATE KEY", or "RSA PRIVATE KEY".'); - error.headerType = error; - throw error; - } - - if(msg.procType && msg.procType.type === 'ENCRYPTED') { - var dkLen; - var cipherFn; - switch(msg.dekInfo.algorithm) { - case 'DES-CBC': - dkLen = 8; - cipherFn = forge.des.createDecryptionCipher; - break; - case 'DES-EDE3-CBC': - dkLen = 24; - cipherFn = forge.des.createDecryptionCipher; - break; - case 'AES-128-CBC': - dkLen = 16; - cipherFn = forge.aes.createDecryptionCipher; - break; - case 'AES-192-CBC': - dkLen = 24; - cipherFn = forge.aes.createDecryptionCipher; - break; - case 'AES-256-CBC': - dkLen = 32; - cipherFn = forge.aes.createDecryptionCipher; - break; - case 'RC2-40-CBC': - dkLen = 5; - cipherFn = function(key) { - return forge.rc2.createDecryptionCipher(key, 40); - }; - break; - case 'RC2-64-CBC': - dkLen = 8; - cipherFn = function(key) { - return forge.rc2.createDecryptionCipher(key, 64); - }; - break; - case 'RC2-128-CBC': - dkLen = 16; - cipherFn = function(key) { - return forge.rc2.createDecryptionCipher(key, 128); - }; - break; - default: - var error = new Error('Could not decrypt private key; unsupported ' + - 'encryption algorithm "' + msg.dekInfo.algorithm + '".'); - error.algorithm = msg.dekInfo.algorithm; - throw error; - } - - // use OpenSSL legacy key derivation - var iv = forge.util.hexToBytes(msg.dekInfo.parameters); - var dk = forge.pbe.opensslDeriveBytes(password, iv.substr(0, 8), dkLen); - var cipher = cipherFn(dk); - cipher.start(iv); - cipher.update(forge.util.createBuffer(msg.body)); - if(cipher.finish()) { - rval = cipher.output.getBytes(); - } else { - return rval; - } - } else { - rval = msg.body; - } - - if(msg.type === 'ENCRYPTED PRIVATE KEY') { - rval = pki.decryptPrivateKeyInfo(asn1.fromDer(rval), password); - } else { - // decryption already performed above - rval = asn1.fromDer(rval); - } - - if(rval !== null) { - rval = pki.privateKeyFromAsn1(rval); - } - - return rval; -}; - -/** - * Derives a PKCS#12 key. - * - * @param password the password to derive the key material from, null or - * undefined for none. - * @param salt the salt, as a ByteBuffer, to use. - * @param id the PKCS#12 ID byte (1 = key material, 2 = IV, 3 = MAC). - * @param iter the iteration count. - * @param n the number of bytes to derive from the password. - * @param md the message digest to use, defaults to SHA-1. - * - * @return a ByteBuffer with the bytes derived from the password. - */ -pki.pbe.generatePkcs12Key = function(password, salt, id, iter, n, md) { - var j, l; - - if(typeof md === 'undefined' || md === null) { - md = forge.md.sha1.create(); - } - - var u = md.digestLength; - var v = md.blockLength; - var result = new forge.util.ByteBuffer(); - - /* Convert password to Unicode byte buffer + trailing 0-byte. */ - var passBuf = new forge.util.ByteBuffer(); - if(password !== null && password !== undefined) { - for(l = 0; l < password.length; l++) { - passBuf.putInt16(password.charCodeAt(l)); - } - passBuf.putInt16(0); - } - - /* Length of salt and password in BYTES. */ - var p = passBuf.length(); - var s = salt.length(); - - /* 1. Construct a string, D (the "diversifier"), by concatenating - v copies of ID. */ - var D = new forge.util.ByteBuffer(); - D.fillWithByte(id, v); - - /* 2. Concatenate copies of the salt together to create a string S of length - v * ceil(s / v) bytes (the final copy of the salt may be trunacted - to create S). - Note that if the salt is the empty string, then so is S. */ - var Slen = v * Math.ceil(s / v); - var S = new forge.util.ByteBuffer(); - for(l = 0; l < Slen; l ++) { - S.putByte(salt.at(l % s)); - } - - /* 3. Concatenate copies of the password together to create a string P of - length v * ceil(p / v) bytes (the final copy of the password may be - truncated to create P). - Note that if the password is the empty string, then so is P. */ - var Plen = v * Math.ceil(p / v); - var P = new forge.util.ByteBuffer(); - for(l = 0; l < Plen; l ++) { - P.putByte(passBuf.at(l % p)); - } - - /* 4. Set I=S||P to be the concatenation of S and P. */ - var I = S; - I.putBuffer(P); - - /* 5. Set c=ceil(n / u). */ - var c = Math.ceil(n / u); - - /* 6. For i=1, 2, ..., c, do the following: */ - for(var i = 1; i <= c; i ++) { - /* a) Set Ai=H^r(D||I). (l.e. the rth hash of D||I, H(H(H(...H(D||I)))) */ - var buf = new forge.util.ByteBuffer(); - buf.putBytes(D.bytes()); - buf.putBytes(I.bytes()); - for(var round = 0; round < iter; round ++) { - md.start(); - md.update(buf.getBytes()); - buf = md.digest(); - } - - /* b) Concatenate copies of Ai to create a string B of length v bytes (the - final copy of Ai may be truncated to create B). */ - var B = new forge.util.ByteBuffer(); - for(l = 0; l < v; l ++) { - B.putByte(buf.at(l % u)); - } - - /* c) Treating I as a concatenation I0, I1, ..., Ik-1 of v-byte blocks, - where k=ceil(s / v) + ceil(p / v), modify I by setting - Ij=(Ij+B+1) mod 2v for each j. */ - var k = Math.ceil(s / v) + Math.ceil(p / v); - var Inew = new forge.util.ByteBuffer(); - for(j = 0; j < k; j ++) { - var chunk = new forge.util.ByteBuffer(I.getBytes(v)); - var x = 0x1ff; - for(l = B.length() - 1; l >= 0; l --) { - x = x >> 8; - x += B.at(l) + chunk.at(l); - chunk.setAt(l, x & 0xff); - } - Inew.putBuffer(chunk); - } - I = Inew; - - /* Add Ai to A. */ - result.putBuffer(buf); - } - - result.truncate(result.length() - n); - return result; -}; - -/** - * Get new Forge cipher object instance. - * - * @param oid the OID (in string notation). - * @param params the ASN.1 params object. - * @param password the password to decrypt with. - * - * @return new cipher object instance. - */ -pki.pbe.getCipher = function(oid, params, password) { - switch(oid) { - case pki.oids['pkcs5PBES2']: - return pki.pbe.getCipherForPBES2(oid, params, password); - - case pki.oids['pbeWithSHAAnd3-KeyTripleDES-CBC']: - case pki.oids['pbewithSHAAnd40BitRC2-CBC']: - return pki.pbe.getCipherForPKCS12PBE(oid, params, password); - - default: - var error = new Error('Cannot read encrypted PBE data block. Unsupported OID.'); - error.oid = oid; - error.supportedOids = [ - 'pkcs5PBES2', - 'pbeWithSHAAnd3-KeyTripleDES-CBC', - 'pbewithSHAAnd40BitRC2-CBC' - ]; - throw error; - } -}; - -/** - * Get new Forge cipher object instance according to PBES2 params block. - * - * The returned cipher instance is already started using the IV - * from PBES2 parameter block. - * - * @param oid the PKCS#5 PBKDF2 OID (in string notation). - * @param params the ASN.1 PBES2-params object. - * @param password the password to decrypt with. - * - * @return new cipher object instance. - */ -pki.pbe.getCipherForPBES2 = function(oid, params, password) { - // get PBE params - var capture = {}; - var errors = []; - if(!asn1.validate(params, PBES2AlgorithmsValidator, capture, errors)) { - var error = new Error('Cannot read password-based-encryption algorithm ' + - 'parameters. ASN.1 object is not a supported EncryptedPrivateKeyInfo.'); - error.errors = errors; - throw error; - } - - // check oids - oid = asn1.derToOid(capture.kdfOid); - if(oid !== pki.oids['pkcs5PBKDF2']) { - var error = new Error('Cannot read encrypted private key. ' + - 'Unsupported key derivation function OID.'); - error.oid = oid; - error.supportedOids = ['pkcs5PBKDF2']; - throw error; - } - oid = asn1.derToOid(capture.encOid); - if(oid !== pki.oids['aes128-CBC'] && - oid !== pki.oids['aes192-CBC'] && - oid !== pki.oids['aes256-CBC'] && - oid !== pki.oids['des-EDE3-CBC'] && - oid !== pki.oids['desCBC']) { - var error = new Error('Cannot read encrypted private key. ' + - 'Unsupported encryption scheme OID.'); - error.oid = oid; - error.supportedOids = [ - 'aes128-CBC', 'aes192-CBC', 'aes256-CBC', 'des-EDE3-CBC', 'desCBC']; - throw error; - } - - // set PBE params - var salt = capture.kdfSalt; - var count = forge.util.createBuffer(capture.kdfIterationCount); - count = count.getInt(count.length() << 3); - var dkLen; - var cipherFn; - switch(pki.oids[oid]) { - case 'aes128-CBC': - dkLen = 16; - cipherFn = forge.aes.createDecryptionCipher; - break; - case 'aes192-CBC': - dkLen = 24; - cipherFn = forge.aes.createDecryptionCipher; - break; - case 'aes256-CBC': - dkLen = 32; - cipherFn = forge.aes.createDecryptionCipher; - break; - case 'des-EDE3-CBC': - dkLen = 24; - cipherFn = forge.des.createDecryptionCipher; - break; - case 'desCBC': - dkLen = 8; - cipherFn = forge.des.createDecryptionCipher; - break; - } - - // decrypt private key using pbe SHA-1 and AES/DES - var dk = forge.pkcs5.pbkdf2(password, salt, count, dkLen); - var iv = capture.encIv; - var cipher = cipherFn(dk); - cipher.start(iv); - - return cipher; -}; - -/** - * Get new Forge cipher object instance for PKCS#12 PBE. - * - * The returned cipher instance is already started using the key & IV - * derived from the provided password and PKCS#12 PBE salt. - * - * @param oid The PKCS#12 PBE OID (in string notation). - * @param params The ASN.1 PKCS#12 PBE-params object. - * @param password The password to decrypt with. - * - * @return the new cipher object instance. - */ -pki.pbe.getCipherForPKCS12PBE = function(oid, params, password) { - // get PBE params - var capture = {}; - var errors = []; - if(!asn1.validate(params, pkcs12PbeParamsValidator, capture, errors)) { - var error = new Error('Cannot read password-based-encryption algorithm ' + - 'parameters. ASN.1 object is not a supported EncryptedPrivateKeyInfo.'); - error.errors = errors; - throw error; - } - - var salt = forge.util.createBuffer(capture.salt); - var count = forge.util.createBuffer(capture.iterations); - count = count.getInt(count.length() << 3); - - var dkLen, dIvLen, cipherFn; - switch(oid) { - case pki.oids['pbeWithSHAAnd3-KeyTripleDES-CBC']: - dkLen = 24; - dIvLen = 8; - cipherFn = forge.des.startDecrypting; - break; - - case pki.oids['pbewithSHAAnd40BitRC2-CBC']: - dkLen = 5; - dIvLen = 8; - cipherFn = function(key, iv) { - var cipher = forge.rc2.createDecryptionCipher(key, 40); - cipher.start(iv, null); - return cipher; - }; - break; - - default: - var error = new Error('Cannot read PKCS #12 PBE data block. Unsupported OID.'); - error.oid = oid; - throw error; - } - - var key = pki.pbe.generatePkcs12Key(password, salt, 1, count, dkLen); - var iv = pki.pbe.generatePkcs12Key(password, salt, 2, count, dIvLen); - - return cipherFn(key, iv); -}; - -/** - * OpenSSL's legacy key derivation function. - * - * See: http://www.openssl.org/docs/crypto/EVP_BytesToKey.html - * - * @param password the password to derive the key from. - * @param salt the salt to use, null for none. - * @param dkLen the number of bytes needed for the derived key. - * @param [options] the options to use: - * [md] an optional message digest object to use. - */ -pki.pbe.opensslDeriveBytes = function(password, salt, dkLen, md) { - if(typeof md === 'undefined' || md === null) { - md = forge.md.md5.create(); - } - if(salt === null) { - salt = ''; - } - var digests = [hash(md, password + salt)]; - for(var length = 16, i = 1; length < dkLen; ++i, length += 16) { - digests.push(hash(md, digests[i - 1] + password + salt)); - } - return digests.join('').substr(0, dkLen); -}; - -function hash(md, bytes) { - return md.start().update(bytes).digest().getBytes(); -} - -} // end module implementation - -/* ########## Begin module wrapper ########## */ -var name = 'pbe'; -if(typeof define !== 'function') { - // NodeJS -> AMD - if(typeof module === 'object' && module.exports) { - var nodeJS = true; - define = function(ids, factory) { - factory(require, module); - }; - } else { - // <script> - if(typeof forge === 'undefined') { - forge = {}; - } - return initModule(forge); - } -} -// AMD -var deps; -var defineFunc = function(require, module) { - module.exports = function(forge) { - var mods = deps.map(function(dep) { - return require(dep); - }).concat(initModule); - // handle circular dependencies - forge = forge || {}; - forge.defined = forge.defined || {}; - if(forge.defined[name]) { - return forge[name]; - } - forge.defined[name] = true; - for(var i = 0; i < mods.length; ++i) { - mods[i](forge); - } - return forge[name]; - }; -}; -var tmpDefine = define; -define = function(ids, factory) { - deps = (typeof ids === 'string') ? factory.slice(2) : ids.slice(2); - if(nodeJS) { - delete define; - return tmpDefine.apply(null, Array.prototype.slice.call(arguments, 0)); - } - define = tmpDefine; - return define.apply(null, Array.prototype.slice.call(arguments, 0)); -}; -define([ - 'require', - 'module', - './aes', - './asn1', - './des', - './md', - './oids', - './pem', - './pbkdf2', - './random', - './rc2', - './rsa', - './util' -], function() { - defineFunc.apply(null, Array.prototype.slice.call(arguments, 0)); -}); -})(); diff --git a/alarm/node_modules/node-forge/js/pbkdf2.js b/alarm/node_modules/node-forge/js/pbkdf2.js deleted file mode 100644 index 63612e7..0000000 --- a/alarm/node_modules/node-forge/js/pbkdf2.js +++ /dev/null @@ -1,264 +0,0 @@ -/** - * Password-Based Key-Derivation Function #2 implementation. - * - * See RFC 2898 for details. - * - * @author Dave Longley - * - * Copyright (c) 2010-2013 Digital Bazaar, Inc. - */ -(function() { -/* ########## Begin module implementation ########## */ -function initModule(forge) { - -var pkcs5 = forge.pkcs5 = forge.pkcs5 || {}; - -var _nodejs = ( - typeof process !== 'undefined' && process.versions && process.versions.node); -var crypto; -if(_nodejs && !forge.disableNativeCode) { - crypto = require('crypto'); -} - -/** - * Derives a key from a password. - * - * @param p the password as a binary-encoded string of bytes. - * @param s the salt as a binary-encoded string of bytes. - * @param c the iteration count, a positive integer. - * @param dkLen the intended length, in bytes, of the derived key, - * (max: 2^32 - 1) * hash length of the PRF. - * @param [md] the message digest (or algorithm identifier as a string) to use - * in the PRF, defaults to SHA-1. - * @param [callback(err, key)] presence triggers asynchronous version, called - * once the operation completes. - * - * @return the derived key, as a binary-encoded string of bytes, for the - * synchronous version (if no callback is specified). - */ -forge.pbkdf2 = pkcs5.pbkdf2 = function(p, s, c, dkLen, md, callback) { - if(typeof md === 'function') { - callback = md; - md = null; - } - - // use native implementation if possible and not disabled, note that - // some node versions only support SHA-1, others allow digest to be changed - if(_nodejs && !forge.disableNativeCode && crypto.pbkdf2 && - (md === null || typeof md !== 'object') && - (crypto.pbkdf2Sync.length > 4 || (!md || md === 'sha1'))) { - if(typeof md !== 'string') { - // default prf to SHA-1 - md = 'sha1'; - } - s = new Buffer(s, 'binary'); - if(!callback) { - if(crypto.pbkdf2Sync.length === 4) { - return crypto.pbkdf2Sync(p, s, c, dkLen).toString('binary'); - } - return crypto.pbkdf2Sync(p, s, c, dkLen, md).toString('binary'); - } - if(crypto.pbkdf2Sync.length === 4) { - return crypto.pbkdf2(p, s, c, dkLen, function(err, key) { - if(err) { - return callback(err); - } - callback(null, key.toString('binary')); - }); - } - return crypto.pbkdf2(p, s, c, dkLen, md, function(err, key) { - if(err) { - return callback(err); - } - callback(null, key.toString('binary')); - }); - } - - if(typeof md === 'undefined' || md === null) { - // default prf to SHA-1 - md = forge.md.sha1.create(); - } - if(typeof md === 'string') { - if(!(md in forge.md.algorithms)) { - throw new Error('Unknown hash algorithm: ' + md); - } - md = forge.md[md].create(); - } - - var hLen = md.digestLength; - - /* 1. If dkLen > (2^32 - 1) * hLen, output "derived key too long" and - stop. */ - if(dkLen > (0xFFFFFFFF * hLen)) { - var err = new Error('Derived key is too long.'); - if(callback) { - return callback(err); - } - throw err; - } - - /* 2. Let len be the number of hLen-octet blocks in the derived key, - rounding up, and let r be the number of octets in the last - block: - - len = CEIL(dkLen / hLen), - r = dkLen - (len - 1) * hLen. */ - var len = Math.ceil(dkLen / hLen); - var r = dkLen - (len - 1) * hLen; - - /* 3. For each block of the derived key apply the function F defined - below to the password P, the salt S, the iteration count c, and - the block index to compute the block: - - T_1 = F(P, S, c, 1), - T_2 = F(P, S, c, 2), - ... - T_len = F(P, S, c, len), - - where the function F is defined as the exclusive-or sum of the - first c iterates of the underlying pseudorandom function PRF - applied to the password P and the concatenation of the salt S - and the block index i: - - F(P, S, c, i) = u_1 XOR u_2 XOR ... XOR u_c - - where - - u_1 = PRF(P, S || INT(i)), - u_2 = PRF(P, u_1), - ... - u_c = PRF(P, u_{c-1}). - - Here, INT(i) is a four-octet encoding of the integer i, most - significant octet first. */ - var prf = forge.hmac.create(); - prf.start(md, p); - var dk = ''; - var xor, u_c, u_c1; - - // sync version - if(!callback) { - for(var i = 1; i <= len; ++i) { - // PRF(P, S || INT(i)) (first iteration) - prf.start(null, null); - prf.update(s); - prf.update(forge.util.int32ToBytes(i)); - xor = u_c1 = prf.digest().getBytes(); - - // PRF(P, u_{c-1}) (other iterations) - for(var j = 2; j <= c; ++j) { - prf.start(null, null); - prf.update(u_c1); - u_c = prf.digest().getBytes(); - // F(p, s, c, i) - xor = forge.util.xorBytes(xor, u_c, hLen); - u_c1 = u_c; - } - - /* 4. Concatenate the blocks and extract the first dkLen octets to - produce a derived key DK: - - DK = T_1 || T_2 || ... || T_len<0..r-1> */ - dk += (i < len) ? xor : xor.substr(0, r); - } - /* 5. Output the derived key DK. */ - return dk; - } - - // async version - var i = 1, j; - function outer() { - if(i > len) { - // done - return callback(null, dk); - } - - // PRF(P, S || INT(i)) (first iteration) - prf.start(null, null); - prf.update(s); - prf.update(forge.util.int32ToBytes(i)); - xor = u_c1 = prf.digest().getBytes(); - - // PRF(P, u_{c-1}) (other iterations) - j = 2; - inner(); - } - - function inner() { - if(j <= c) { - prf.start(null, null); - prf.update(u_c1); - u_c = prf.digest().getBytes(); - // F(p, s, c, i) - xor = forge.util.xorBytes(xor, u_c, hLen); - u_c1 = u_c; - ++j; - return forge.util.setImmediate(inner); - } - - /* 4. Concatenate the blocks and extract the first dkLen octets to - produce a derived key DK: - - DK = T_1 || T_2 || ... || T_len<0..r-1> */ - dk += (i < len) ? xor : xor.substr(0, r); - - ++i; - outer(); - } - - outer(); -}; - -} // end module implementation - -/* ########## Begin module wrapper ########## */ -var name = 'pbkdf2'; -if(typeof define !== 'function') { - // NodeJS -> AMD - if(typeof module === 'object' && module.exports) { - var nodeJS = true; - define = function(ids, factory) { - factory(require, module); - }; - } else { - // <script> - if(typeof forge === 'undefined') { - forge = {}; - } - return initModule(forge); - } -} -// AMD -var deps; -var defineFunc = function(require, module) { - module.exports = function(forge) { - var mods = deps.map(function(dep) { - return require(dep); - }).concat(initModule); - // handle circular dependencies - forge = forge || {}; - forge.defined = forge.defined || {}; - if(forge.defined[name]) { - return forge[name]; - } - forge.defined[name] = true; - for(var i = 0; i < mods.length; ++i) { - mods[i](forge); - } - return forge[name]; - }; -}; -var tmpDefine = define; -define = function(ids, factory) { - deps = (typeof ids === 'string') ? factory.slice(2) : ids.slice(2); - if(nodeJS) { - delete define; - return tmpDefine.apply(null, Array.prototype.slice.call(arguments, 0)); - } - define = tmpDefine; - return define.apply(null, Array.prototype.slice.call(arguments, 0)); -}; -define(['require', 'module', './hmac', './md', './util'], function() { - defineFunc.apply(null, Array.prototype.slice.call(arguments, 0)); -}); -})(); diff --git a/alarm/node_modules/node-forge/js/pem.js b/alarm/node_modules/node-forge/js/pem.js deleted file mode 100644 index e3085dc..0000000 --- a/alarm/node_modules/node-forge/js/pem.js +++ /dev/null @@ -1,285 +0,0 @@ -/** - * Javascript implementation of basic PEM (Privacy Enhanced Mail) algorithms. - * - * See: RFC 1421. - * - * @author Dave Longley - * - * Copyright (c) 2013-2014 Digital Bazaar, Inc. - * - * A Forge PEM object has the following fields: - * - * type: identifies the type of message (eg: "RSA PRIVATE KEY"). - * - * procType: identifies the type of processing performed on the message, - * it has two subfields: version and type, eg: 4,ENCRYPTED. - * - * contentDomain: identifies the type of content in the message, typically - * only uses the value: "RFC822". - * - * dekInfo: identifies the message encryption algorithm and mode and includes - * any parameters for the algorithm, it has two subfields: algorithm and - * parameters, eg: DES-CBC,F8143EDE5960C597. - * - * headers: contains all other PEM encapsulated headers -- where order is - * significant (for pairing data like recipient ID + key info). - * - * body: the binary-encoded body. - */ -(function() { -/* ########## Begin module implementation ########## */ -function initModule(forge) { - -// shortcut for pem API -var pem = forge.pem = forge.pem || {}; - -/** - * Encodes (serializes) the given PEM object. - * - * @param msg the PEM message object to encode. - * @param options the options to use: - * maxline the maximum characters per line for the body, (default: 64). - * - * @return the PEM-formatted string. - */ -pem.encode = function(msg, options) { - options = options || {}; - var rval = '-----BEGIN ' + msg.type + '-----\r\n'; - - // encode special headers - var header; - if(msg.procType) { - header = { - name: 'Proc-Type', - values: [String(msg.procType.version), msg.procType.type] - }; - rval += foldHeader(header); - } - if(msg.contentDomain) { - header = {name: 'Content-Domain', values: [msg.contentDomain]}; - rval += foldHeader(header); - } - if(msg.dekInfo) { - header = {name: 'DEK-Info', values: [msg.dekInfo.algorithm]}; - if(msg.dekInfo.parameters) { - header.values.push(msg.dekInfo.parameters); - } - rval += foldHeader(header); - } - - if(msg.headers) { - // encode all other headers - for(var i = 0; i < msg.headers.length; ++i) { - rval += foldHeader(msg.headers[i]); - } - } - - // terminate header - if(msg.procType) { - rval += '\r\n'; - } - - // add body - rval += forge.util.encode64(msg.body, options.maxline || 64) + '\r\n'; - - rval += '-----END ' + msg.type + '-----\r\n'; - return rval; -}; - -/** - * Decodes (deserializes) all PEM messages found in the given string. - * - * @param str the PEM-formatted string to decode. - * - * @return the PEM message objects in an array. - */ -pem.decode = function(str) { - var rval = []; - - // split string into PEM messages (be lenient w/EOF on BEGIN line) - var rMessage = /\s*-----BEGIN ([A-Z0-9- ]+)-----\r?\n?([\x21-\x7e\s]+?(?:\r?\n\r?\n))?([:A-Za-z0-9+\/=\s]+?)-----END \1-----/g; - var rHeader = /([\x21-\x7e]+):\s*([\x21-\x7e\s^:]+)/; - var rCRLF = /\r?\n/; - var match; - while(true) { - match = rMessage.exec(str); - if(!match) { - break; - } - - var msg = { - type: match[1], - procType: null, - contentDomain: null, - dekInfo: null, - headers: [], - body: forge.util.decode64(match[3]) - }; - rval.push(msg); - - // no headers - if(!match[2]) { - continue; - } - - // parse headers - var lines = match[2].split(rCRLF); - var li = 0; - while(match && li < lines.length) { - // get line, trim any rhs whitespace - var line = lines[li].replace(/\s+$/, ''); - - // RFC2822 unfold any following folded lines - for(var nl = li + 1; nl < lines.length; ++nl) { - var next = lines[nl]; - if(!/\s/.test(next[0])) { - break; - } - line += next; - li = nl; - } - - // parse header - match = line.match(rHeader); - if(match) { - var header = {name: match[1], values: []}; - var values = match[2].split(','); - for(var vi = 0; vi < values.length; ++vi) { - header.values.push(ltrim(values[vi])); - } - - // Proc-Type must be the first header - if(!msg.procType) { - if(header.name !== 'Proc-Type') { - throw new Error('Invalid PEM formatted message. The first ' + - 'encapsulated header must be "Proc-Type".'); - } else if(header.values.length !== 2) { - throw new Error('Invalid PEM formatted message. The "Proc-Type" ' + - 'header must have two subfields.'); - } - msg.procType = {version: values[0], type: values[1]}; - } else if(!msg.contentDomain && header.name === 'Content-Domain') { - // special-case Content-Domain - msg.contentDomain = values[0] || ''; - } else if(!msg.dekInfo && header.name === 'DEK-Info') { - // special-case DEK-Info - if(header.values.length === 0) { - throw new Error('Invalid PEM formatted message. The "DEK-Info" ' + - 'header must have at least one subfield.'); - } - msg.dekInfo = {algorithm: values[0], parameters: values[1] || null}; - } else { - msg.headers.push(header); - } - } - - ++li; - } - - if(msg.procType === 'ENCRYPTED' && !msg.dekInfo) { - throw new Error('Invalid PEM formatted message. The "DEK-Info" ' + - 'header must be present if "Proc-Type" is "ENCRYPTED".'); - } - } - - if(rval.length === 0) { - throw new Error('Invalid PEM formatted message.'); - } - - return rval; -}; - -function foldHeader(header) { - var rval = header.name + ': '; - - // ensure values with CRLF are folded - var values = []; - var insertSpace = function(match, $1) { - return ' ' + $1; - }; - for(var i = 0; i < header.values.length; ++i) { - values.push(header.values[i].replace(/^(\S+\r\n)/, insertSpace)); - } - rval += values.join(',') + '\r\n'; - - // do folding - var length = 0; - var candidate = -1; - for(var i = 0; i < rval.length; ++i, ++length) { - if(length > 65 && candidate !== -1) { - var insert = rval[candidate]; - if(insert === ',') { - ++candidate; - rval = rval.substr(0, candidate) + '\r\n ' + rval.substr(candidate); - } else { - rval = rval.substr(0, candidate) + - '\r\n' + insert + rval.substr(candidate + 1); - } - length = (i - candidate - 1); - candidate = -1; - ++i; - } else if(rval[i] === ' ' || rval[i] === '\t' || rval[i] === ',') { - candidate = i; - } - } - - return rval; -} - -function ltrim(str) { - return str.replace(/^\s+/, ''); -} - -} // end module implementation - -/* ########## Begin module wrapper ########## */ -var name = 'pem'; -if(typeof define !== 'function') { - // NodeJS -> AMD - if(typeof module === 'object' && module.exports) { - var nodeJS = true; - define = function(ids, factory) { - factory(require, module); - }; - } else { - // <script> - if(typeof forge === 'undefined') { - forge = {}; - } - return initModule(forge); - } -} -// AMD -var deps; -var defineFunc = function(require, module) { - module.exports = function(forge) { - var mods = deps.map(function(dep) { - return require(dep); - }).concat(initModule); - // handle circular dependencies - forge = forge || {}; - forge.defined = forge.defined || {}; - if(forge.defined[name]) { - return forge[name]; - } - forge.defined[name] = true; - for(var i = 0; i < mods.length; ++i) { - mods[i](forge); - } - return forge[name]; - }; -}; -var tmpDefine = define; -define = function(ids, factory) { - deps = (typeof ids === 'string') ? factory.slice(2) : ids.slice(2); - if(nodeJS) { - delete define; - return tmpDefine.apply(null, Array.prototype.slice.call(arguments, 0)); - } - define = tmpDefine; - return define.apply(null, Array.prototype.slice.call(arguments, 0)); -}; -define(['require', 'module', './util'], function() { - defineFunc.apply(null, Array.prototype.slice.call(arguments, 0)); -}); -})(); diff --git a/alarm/node_modules/node-forge/js/pkcs1.js b/alarm/node_modules/node-forge/js/pkcs1.js deleted file mode 100644 index 7bf734c..0000000 --- a/alarm/node_modules/node-forge/js/pkcs1.js +++ /dev/null @@ -1,329 +0,0 @@ -/** - * Partial implementation of PKCS#1 v2.2: RSA-OEAP - * - * Modified but based on the following MIT and BSD licensed code: - * - * https://github.com/kjur/jsjws/blob/master/rsa.js: - * - * The 'jsjws'(JSON Web Signature JavaScript Library) License - * - * Copyright (c) 2012 Kenji Urushima - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * http://webrsa.cvs.sourceforge.net/viewvc/webrsa/Client/RSAES-OAEP.js?content-type=text%2Fplain: - * - * RSAES-OAEP.js - * $Id: RSAES-OAEP.js,v 1.1.1.1 2003/03/19 15:37:20 ellispritchard Exp $ - * JavaScript Implementation of PKCS #1 v2.1 RSA CRYPTOGRAPHY STANDARD (RSA Laboratories, June 14, 2002) - * Copyright (C) Ellis Pritchard, Guardian Unlimited 2003. - * Contact: ellis@nukinetics.com - * Distributed under the BSD License. - * - * Official documentation: http://www.rsa.com/rsalabs/node.asp?id=2125 - * - * @author Evan Jones (http://evanjones.ca/) - * @author Dave Longley - * - * Copyright (c) 2013-2014 Digital Bazaar, Inc. - */ -(function() { -/* ########## Begin module implementation ########## */ -function initModule(forge) { - -// shortcut for PKCS#1 API -var pkcs1 = forge.pkcs1 = forge.pkcs1 || {}; - -/** - * Encode the given RSAES-OAEP message (M) using key, with optional label (L) - * and seed. - * - * This method does not perform RSA encryption, it only encodes the message - * using RSAES-OAEP. - * - * @param key the RSA key to use. - * @param message the message to encode. - * @param options the options to use: - * label an optional label to use. - * seed the seed to use. - * md the message digest object to use, undefined for SHA-1. - * mgf1 optional mgf1 parameters: - * md the message digest object to use for MGF1. - * - * @return the encoded message bytes. - */ -pkcs1.encode_rsa_oaep = function(key, message, options) { - // parse arguments - var label; - var seed; - var md; - var mgf1Md; - // legacy args (label, seed, md) - if(typeof options === 'string') { - label = options; - seed = arguments[3] || undefined; - md = arguments[4] || undefined; - } else if(options) { - label = options.label || undefined; - seed = options.seed || undefined; - md = options.md || undefined; - if(options.mgf1 && options.mgf1.md) { - mgf1Md = options.mgf1.md; - } - } - - // default OAEP to SHA-1 message digest - if(!md) { - md = forge.md.sha1.create(); - } else { - md.start(); - } - - // default MGF-1 to same as OAEP - if(!mgf1Md) { - mgf1Md = md; - } - - // compute length in bytes and check output - var keyLength = Math.ceil(key.n.bitLength() / 8); - var maxLength = keyLength - 2 * md.digestLength - 2; - if(message.length > maxLength) { - var error = new Error('RSAES-OAEP input message length is too long.'); - error.length = message.length; - error.maxLength = maxLength; - throw error; - } - - if(!label) { - label = ''; - } - md.update(label, 'raw'); - var lHash = md.digest(); - - var PS = ''; - var PS_length = maxLength - message.length; - for (var i = 0; i < PS_length; i++) { - PS += '\x00'; - } - - var DB = lHash.getBytes() + PS + '\x01' + message; - - if(!seed) { - seed = forge.random.getBytes(md.digestLength); - } else if(seed.length !== md.digestLength) { - var error = new Error('Invalid RSAES-OAEP seed. The seed length must ' + - 'match the digest length.') - error.seedLength = seed.length; - error.digestLength = md.digestLength; - throw error; - } - - var dbMask = rsa_mgf1(seed, keyLength - md.digestLength - 1, mgf1Md); - var maskedDB = forge.util.xorBytes(DB, dbMask, DB.length); - - var seedMask = rsa_mgf1(maskedDB, md.digestLength, mgf1Md); - var maskedSeed = forge.util.xorBytes(seed, seedMask, seed.length); - - // return encoded message - return '\x00' + maskedSeed + maskedDB; -}; - -/** - * Decode the given RSAES-OAEP encoded message (EM) using key, with optional - * label (L). - * - * This method does not perform RSA decryption, it only decodes the message - * using RSAES-OAEP. - * - * @param key the RSA key to use. - * @param em the encoded message to decode. - * @param options the options to use: - * label an optional label to use. - * md the message digest object to use for OAEP, undefined for SHA-1. - * mgf1 optional mgf1 parameters: - * md the message digest object to use for MGF1. - * - * @return the decoded message bytes. - */ -pkcs1.decode_rsa_oaep = function(key, em, options) { - // parse args - var label; - var md; - var mgf1Md; - // legacy args - if(typeof options === 'string') { - label = options; - md = arguments[3] || undefined; - } else if(options) { - label = options.label || undefined; - md = options.md || undefined; - if(options.mgf1 && options.mgf1.md) { - mgf1Md = options.mgf1.md; - } - } - - // compute length in bytes - var keyLength = Math.ceil(key.n.bitLength() / 8); - - if(em.length !== keyLength) { - var error = new Error('RSAES-OAEP encoded message length is invalid.'); - error.length = em.length; - error.expectedLength = keyLength; - throw error; - } - - // default OAEP to SHA-1 message digest - if(md === undefined) { - md = forge.md.sha1.create(); - } else { - md.start(); - } - - // default MGF-1 to same as OAEP - if(!mgf1Md) { - mgf1Md = md; - } - - if(keyLength < 2 * md.digestLength + 2) { - throw new Error('RSAES-OAEP key is too short for the hash function.'); - } - - if(!label) { - label = ''; - } - md.update(label, 'raw'); - var lHash = md.digest().getBytes(); - - // split the message into its parts - var y = em.charAt(0); - var maskedSeed = em.substring(1, md.digestLength + 1); - var maskedDB = em.substring(1 + md.digestLength); - - var seedMask = rsa_mgf1(maskedDB, md.digestLength, mgf1Md); - var seed = forge.util.xorBytes(maskedSeed, seedMask, maskedSeed.length); - - var dbMask = rsa_mgf1(seed, keyLength - md.digestLength - 1, mgf1Md); - var db = forge.util.xorBytes(maskedDB, dbMask, maskedDB.length); - - var lHashPrime = db.substring(0, md.digestLength); - - // constant time check that all values match what is expected - var error = (y !== '\x00'); - - // constant time check lHash vs lHashPrime - for(var i = 0; i < md.digestLength; ++i) { - error |= (lHash.charAt(i) !== lHashPrime.charAt(i)); - } - - // "constant time" find the 0x1 byte separating the padding (zeros) from the - // message - // TODO: It must be possible to do this in a better/smarter way? - var in_ps = 1; - var index = md.digestLength; - for(var j = md.digestLength; j < db.length; j++) { - var code = db.charCodeAt(j); - - var is_0 = (code & 0x1) ^ 0x1; - - // non-zero if not 0 or 1 in the ps section - var error_mask = in_ps ? 0xfffe : 0x0000; - error |= (code & error_mask); - - // latch in_ps to zero after we find 0x1 - in_ps = in_ps & is_0; - index += in_ps; - } - - if(error || db.charCodeAt(index) !== 0x1) { - throw new Error('Invalid RSAES-OAEP padding.'); - } - - return db.substring(index + 1); -}; - -function rsa_mgf1(seed, maskLength, hash) { - // default to SHA-1 message digest - if(!hash) { - hash = forge.md.sha1.create(); - } - var t = ''; - var count = Math.ceil(maskLength / hash.digestLength); - for(var i = 0; i < count; ++i) { - var c = String.fromCharCode( - (i >> 24) & 0xFF, (i >> 16) & 0xFF, (i >> 8) & 0xFF, i & 0xFF); - hash.start(); - hash.update(seed + c); - t += hash.digest().getBytes(); - } - return t.substring(0, maskLength); -} - -} // end module implementation - -/* ########## Begin module wrapper ########## */ -var name = 'pkcs1'; -if(typeof define !== 'function') { - // NodeJS -> AMD - if(typeof module === 'object' && module.exports) { - var nodeJS = true; - define = function(ids, factory) { - factory(require, module); - }; - } else { - // <script> - if(typeof forge === 'undefined') { - forge = {}; - } - return initModule(forge); - } -} -// AMD -var deps; -var defineFunc = function(require, module) { - module.exports = function(forge) { - var mods = deps.map(function(dep) { - return require(dep); - }).concat(initModule); - // handle circular dependencies - forge = forge || {}; - forge.defined = forge.defined || {}; - if(forge.defined[name]) { - return forge[name]; - } - forge.defined[name] = true; - for(var i = 0; i < mods.length; ++i) { - mods[i](forge); - } - return forge[name]; - }; -}; -var tmpDefine = define; -define = function(ids, factory) { - deps = (typeof ids === 'string') ? factory.slice(2) : ids.slice(2); - if(nodeJS) { - delete define; - return tmpDefine.apply(null, Array.prototype.slice.call(arguments, 0)); - } - define = tmpDefine; - return define.apply(null, Array.prototype.slice.call(arguments, 0)); -}; -define(['require', 'module', './util', './random', './sha1'], function() { - defineFunc.apply(null, Array.prototype.slice.call(arguments, 0)); -}); -})(); diff --git a/alarm/node_modules/node-forge/js/pkcs12.js b/alarm/node_modules/node-forge/js/pkcs12.js deleted file mode 100644 index 5d4d8af..0000000 --- a/alarm/node_modules/node-forge/js/pkcs12.js +++ /dev/null @@ -1,1133 +0,0 @@ -/** - * Javascript implementation of PKCS#12. - * - * @author Dave Longley - * @author Stefan Siegl <stesie@brokenpipe.de> - * - * Copyright (c) 2010-2014 Digital Bazaar, Inc. - * Copyright (c) 2012 Stefan Siegl <stesie@brokenpipe.de> - * - * The ASN.1 representation of PKCS#12 is as follows - * (see ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-12/pkcs-12-tc1.pdf for details) - * - * PFX ::= SEQUENCE { - * version INTEGER {v3(3)}(v3,...), - * authSafe ContentInfo, - * macData MacData OPTIONAL - * } - * - * MacData ::= SEQUENCE { - * mac DigestInfo, - * macSalt OCTET STRING, - * iterations INTEGER DEFAULT 1 - * } - * Note: The iterations default is for historical reasons and its use is - * deprecated. A higher value, like 1024, is recommended. - * - * DigestInfo is defined in PKCS#7 as follows: - * - * DigestInfo ::= SEQUENCE { - * digestAlgorithm DigestAlgorithmIdentifier, - * digest Digest - * } - * - * DigestAlgorithmIdentifier ::= AlgorithmIdentifier - * - * The AlgorithmIdentifier contains an Object Identifier (OID) and parameters - * for the algorithm, if any. In the case of SHA1 there is none. - * - * AlgorithmIdentifer ::= SEQUENCE { - * algorithm OBJECT IDENTIFIER, - * parameters ANY DEFINED BY algorithm OPTIONAL - * } - * - * Digest ::= OCTET STRING - * - * - * ContentInfo ::= SEQUENCE { - * contentType ContentType, - * content [0] EXPLICIT ANY DEFINED BY contentType OPTIONAL - * } - * - * ContentType ::= OBJECT IDENTIFIER - * - * AuthenticatedSafe ::= SEQUENCE OF ContentInfo - * -- Data if unencrypted - * -- EncryptedData if password-encrypted - * -- EnvelopedData if public key-encrypted - * - * - * SafeContents ::= SEQUENCE OF SafeBag - * - * SafeBag ::= SEQUENCE { - * bagId BAG-TYPE.&id ({PKCS12BagSet}) - * bagValue [0] EXPLICIT BAG-TYPE.&Type({PKCS12BagSet}{@bagId}), - * bagAttributes SET OF PKCS12Attribute OPTIONAL - * } - * - * PKCS12Attribute ::= SEQUENCE { - * attrId ATTRIBUTE.&id ({PKCS12AttrSet}), - * attrValues SET OF ATTRIBUTE.&Type ({PKCS12AttrSet}{@attrId}) - * } -- This type is compatible with the X.500 type ’Attribute’ - * - * PKCS12AttrSet ATTRIBUTE ::= { - * friendlyName | -- from PKCS #9 - * localKeyId, -- from PKCS #9 - * ... -- Other attributes are allowed - * } - * - * CertBag ::= SEQUENCE { - * certId BAG-TYPE.&id ({CertTypes}), - * certValue [0] EXPLICIT BAG-TYPE.&Type ({CertTypes}{@certId}) - * } - * - * x509Certificate BAG-TYPE ::= {OCTET STRING IDENTIFIED BY {certTypes 1}} - * -- DER-encoded X.509 certificate stored in OCTET STRING - * - * sdsiCertificate BAG-TYPE ::= {IA5String IDENTIFIED BY {certTypes 2}} - * -- Base64-encoded SDSI certificate stored in IA5String - * - * CertTypes BAG-TYPE ::= { - * x509Certificate | - * sdsiCertificate, - * ... -- For future extensions - * } - */ -(function() { -/* ########## Begin module implementation ########## */ -function initModule(forge) { - -// shortcut for asn.1 & PKI API -var asn1 = forge.asn1; -var pki = forge.pki; - -// shortcut for PKCS#12 API -var p12 = forge.pkcs12 = forge.pkcs12 || {}; - -var contentInfoValidator = { - name: 'ContentInfo', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.SEQUENCE, // a ContentInfo - constructed: true, - value: [{ - name: 'ContentInfo.contentType', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.OID, - constructed: false, - capture: 'contentType' - }, { - name: 'ContentInfo.content', - tagClass: asn1.Class.CONTEXT_SPECIFIC, - constructed: true, - captureAsn1: 'content' - }] -}; - -var pfxValidator = { - name: 'PFX', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.SEQUENCE, - constructed: true, - value: [{ - name: 'PFX.version', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.INTEGER, - constructed: false, - capture: 'version' - }, - contentInfoValidator, { - name: 'PFX.macData', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.SEQUENCE, - constructed: true, - optional: true, - captureAsn1: 'mac', - value: [{ - name: 'PFX.macData.mac', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.SEQUENCE, // DigestInfo - constructed: true, - value: [{ - name: 'PFX.macData.mac.digestAlgorithm', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.SEQUENCE, // DigestAlgorithmIdentifier - constructed: true, - value: [{ - name: 'PFX.macData.mac.digestAlgorithm.algorithm', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.OID, - constructed: false, - capture: 'macAlgorithm' - }, { - name: 'PFX.macData.mac.digestAlgorithm.parameters', - tagClass: asn1.Class.UNIVERSAL, - captureAsn1: 'macAlgorithmParameters' - }] - }, { - name: 'PFX.macData.mac.digest', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.OCTETSTRING, - constructed: false, - capture: 'macDigest' - }] - }, { - name: 'PFX.macData.macSalt', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.OCTETSTRING, - constructed: false, - capture: 'macSalt' - }, { - name: 'PFX.macData.iterations', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.INTEGER, - constructed: false, - optional: true, - capture: 'macIterations' - }] - }] -}; - -var safeBagValidator = { - name: 'SafeBag', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.SEQUENCE, - constructed: true, - value: [{ - name: 'SafeBag.bagId', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.OID, - constructed: false, - capture: 'bagId' - }, { - name: 'SafeBag.bagValue', - tagClass: asn1.Class.CONTEXT_SPECIFIC, - constructed: true, - captureAsn1: 'bagValue' - }, { - name: 'SafeBag.bagAttributes', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.SET, - constructed: true, - optional: true, - capture: 'bagAttributes' - }] -}; - -var attributeValidator = { - name: 'Attribute', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.SEQUENCE, - constructed: true, - value: [{ - name: 'Attribute.attrId', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.OID, - constructed: false, - capture: 'oid' - }, { - name: 'Attribute.attrValues', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.SET, - constructed: true, - capture: 'values' - }] -}; - -var certBagValidator = { - name: 'CertBag', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.SEQUENCE, - constructed: true, - value: [{ - name: 'CertBag.certId', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.OID, - constructed: false, - capture: 'certId' - }, { - name: 'CertBag.certValue', - tagClass: asn1.Class.CONTEXT_SPECIFIC, - constructed: true, - /* So far we only support X.509 certificates (which are wrapped in - an OCTET STRING, hence hard code that here). */ - value: [{ - name: 'CertBag.certValue[0]', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Class.OCTETSTRING, - constructed: false, - capture: 'cert' - }] - }] -}; - -/** - * Search SafeContents structure for bags with matching attributes. - * - * The search can optionally be narrowed by a certain bag type. - * - * @param safeContents the SafeContents structure to search in. - * @param attrName the name of the attribute to compare against. - * @param attrValue the attribute value to search for. - * @param [bagType] bag type to narrow search by. - * - * @return an array of matching bags. - */ -function _getBagsByAttribute(safeContents, attrName, attrValue, bagType) { - var result = []; - - for(var i = 0; i < safeContents.length; i ++) { - for(var j = 0; j < safeContents[i].safeBags.length; j ++) { - var bag = safeContents[i].safeBags[j]; - if(bagType !== undefined && bag.type !== bagType) { - continue; - } - // only filter by bag type, no attribute specified - if(attrName === null) { - result.push(bag); - continue; - } - if(bag.attributes[attrName] !== undefined && - bag.attributes[attrName].indexOf(attrValue) >= 0) { - result.push(bag); - } - } - } - - return result; -} - -/** - * Converts a PKCS#12 PFX in ASN.1 notation into a PFX object. - * - * @param obj The PKCS#12 PFX in ASN.1 notation. - * @param strict true to use strict DER decoding, false not to (default: true). - * @param {String} password Password to decrypt with (optional). - * - * @return PKCS#12 PFX object. - */ -p12.pkcs12FromAsn1 = function(obj, strict, password) { - // handle args - if(typeof strict === 'string') { - password = strict; - strict = true; - } else if(strict === undefined) { - strict = true; - } - - // validate PFX and capture data - var capture = {}; - var errors = []; - if(!asn1.validate(obj, pfxValidator, capture, errors)) { - var error = new Error('Cannot read PKCS#12 PFX. ' + - 'ASN.1 object is not an PKCS#12 PFX.'); - error.errors = error; - throw error; - } - - var pfx = { - version: capture.version.charCodeAt(0), - safeContents: [], - - /** - * Gets bags with matching attributes. - * - * @param filter the attributes to filter by: - * [localKeyId] the localKeyId to search for. - * [localKeyIdHex] the localKeyId in hex to search for. - * [friendlyName] the friendly name to search for. - * [bagType] bag type to narrow each attribute search by. - * - * @return a map of attribute type to an array of matching bags or, if no - * attribute was given but a bag type, the map key will be the - * bag type. - */ - getBags: function(filter) { - var rval = {}; - - var localKeyId; - if('localKeyId' in filter) { - localKeyId = filter.localKeyId; - } else if('localKeyIdHex' in filter) { - localKeyId = forge.util.hexToBytes(filter.localKeyIdHex); - } - - // filter on bagType only - if(localKeyId === undefined && !('friendlyName' in filter) && - 'bagType' in filter) { - rval[filter.bagType] = _getBagsByAttribute( - pfx.safeContents, null, null, filter.bagType); - } - - if(localKeyId !== undefined) { - rval.localKeyId = _getBagsByAttribute( - pfx.safeContents, 'localKeyId', - localKeyId, filter.bagType); - } - if('friendlyName' in filter) { - rval.friendlyName = _getBagsByAttribute( - pfx.safeContents, 'friendlyName', - filter.friendlyName, filter.bagType); - } - - return rval; - }, - - /** - * DEPRECATED: use getBags() instead. - * - * Get bags with matching friendlyName attribute. - * - * @param friendlyName the friendly name to search for. - * @param [bagType] bag type to narrow search by. - * - * @return an array of bags with matching friendlyName attribute. - */ - getBagsByFriendlyName: function(friendlyName, bagType) { - return _getBagsByAttribute( - pfx.safeContents, 'friendlyName', friendlyName, bagType); - }, - - /** - * DEPRECATED: use getBags() instead. - * - * Get bags with matching localKeyId attribute. - * - * @param localKeyId the localKeyId to search for. - * @param [bagType] bag type to narrow search by. - * - * @return an array of bags with matching localKeyId attribute. - */ - getBagsByLocalKeyId: function(localKeyId, bagType) { - return _getBagsByAttribute( - pfx.safeContents, 'localKeyId', localKeyId, bagType); - } - }; - - if(capture.version.charCodeAt(0) !== 3) { - var error = new Error('PKCS#12 PFX of version other than 3 not supported.'); - error.version = capture.version.charCodeAt(0); - throw error; - } - - if(asn1.derToOid(capture.contentType) !== pki.oids.data) { - var error = new Error('Only PKCS#12 PFX in password integrity mode supported.'); - error.oid = asn1.derToOid(capture.contentType); - throw error; - } - - var data = capture.content.value[0]; - if(data.tagClass !== asn1.Class.UNIVERSAL || - data.type !== asn1.Type.OCTETSTRING) { - throw new Error('PKCS#12 authSafe content data is not an OCTET STRING.'); - } - data = _decodePkcs7Data(data); - - // check for MAC - if(capture.mac) { - var md = null; - var macKeyBytes = 0; - var macAlgorithm = asn1.derToOid(capture.macAlgorithm); - switch(macAlgorithm) { - case pki.oids.sha1: - md = forge.md.sha1.create(); - macKeyBytes = 20; - break; - case pki.oids.sha256: - md = forge.md.sha256.create(); - macKeyBytes = 32; - break; - case pki.oids.sha384: - md = forge.md.sha384.create(); - macKeyBytes = 48; - break; - case pki.oids.sha512: - md = forge.md.sha512.create(); - macKeyBytes = 64; - break; - case pki.oids.md5: - md = forge.md.md5.create(); - macKeyBytes = 16; - break; - } - if(md === null) { - throw new Error('PKCS#12 uses unsupported MAC algorithm: ' + macAlgorithm); - } - - // verify MAC (iterations default to 1) - var macSalt = new forge.util.ByteBuffer(capture.macSalt); - var macIterations = (('macIterations' in capture) ? - parseInt(forge.util.bytesToHex(capture.macIterations), 16) : 1); - var macKey = p12.generateKey( - password, macSalt, 3, macIterations, macKeyBytes, md); - var mac = forge.hmac.create(); - mac.start(md, macKey); - mac.update(data.value); - var macValue = mac.getMac(); - if(macValue.getBytes() !== capture.macDigest) { - throw new Error('PKCS#12 MAC could not be verified. Invalid password?'); - } - } - - _decodeAuthenticatedSafe(pfx, data.value, strict, password); - return pfx; -}; - -/** - * Decodes PKCS#7 Data. PKCS#7 (RFC 2315) defines "Data" as an OCTET STRING, - * but it is sometimes an OCTET STRING that is composed/constructed of chunks, - * each its own OCTET STRING. This is BER-encoding vs. DER-encoding. This - * function transforms this corner-case into the usual simple, - * non-composed/constructed OCTET STRING. - * - * This function may be moved to ASN.1 at some point to better deal with - * more BER-encoding issues, should they arise. - * - * @param data the ASN.1 Data object to transform. - */ -function _decodePkcs7Data(data) { - // handle special case of "chunked" data content: an octet string composed - // of other octet strings - if(data.composed || data.constructed) { - var value = forge.util.createBuffer(); - for(var i = 0; i < data.value.length; ++i) { - value.putBytes(data.value[i].value); - } - data.composed = data.constructed = false; - data.value = value.getBytes(); - } - return data; -} - -/** - * Decode PKCS#12 AuthenticatedSafe (BER encoded) into PFX object. - * - * The AuthenticatedSafe is a BER-encoded SEQUENCE OF ContentInfo. - * - * @param pfx The PKCS#12 PFX object to fill. - * @param {String} authSafe BER-encoded AuthenticatedSafe. - * @param strict true to use strict DER decoding, false not to. - * @param {String} password Password to decrypt with (optional). - */ -function _decodeAuthenticatedSafe(pfx, authSafe, strict, password) { - authSafe = asn1.fromDer(authSafe, strict); /* actually it's BER encoded */ - - if(authSafe.tagClass !== asn1.Class.UNIVERSAL || - authSafe.type !== asn1.Type.SEQUENCE || - authSafe.constructed !== true) { - throw new Error('PKCS#12 AuthenticatedSafe expected to be a ' + - 'SEQUENCE OF ContentInfo'); - } - - for(var i = 0; i < authSafe.value.length; i ++) { - var contentInfo = authSafe.value[i]; - - // validate contentInfo and capture data - var capture = {}; - var errors = []; - if(!asn1.validate(contentInfo, contentInfoValidator, capture, errors)) { - var error = new Error('Cannot read ContentInfo.'); - error.errors = errors; - throw error; - } - - var obj = { - encrypted: false - }; - var safeContents = null; - var data = capture.content.value[0]; - switch(asn1.derToOid(capture.contentType)) { - case pki.oids.data: - if(data.tagClass !== asn1.Class.UNIVERSAL || - data.type !== asn1.Type.OCTETSTRING) { - throw new Error('PKCS#12 SafeContents Data is not an OCTET STRING.'); - } - safeContents = _decodePkcs7Data(data).value; - break; - case pki.oids.encryptedData: - safeContents = _decryptSafeContents(data, password); - obj.encrypted = true; - break; - default: - var error = new Error('Unsupported PKCS#12 contentType.'); - error.contentType = asn1.derToOid(capture.contentType); - throw error; - } - - obj.safeBags = _decodeSafeContents(safeContents, strict, password); - pfx.safeContents.push(obj); - } -} - -/** - * Decrypt PKCS#7 EncryptedData structure. - * - * @param data ASN.1 encoded EncryptedContentInfo object. - * @param password The user-provided password. - * - * @return The decrypted SafeContents (ASN.1 object). - */ -function _decryptSafeContents(data, password) { - var capture = {}; - var errors = []; - if(!asn1.validate( - data, forge.pkcs7.asn1.encryptedDataValidator, capture, errors)) { - var error = new Error('Cannot read EncryptedContentInfo.'); - error.errors = errors; - throw error; - } - - var oid = asn1.derToOid(capture.contentType); - if(oid !== pki.oids.data) { - var error = new Error( - 'PKCS#12 EncryptedContentInfo ContentType is not Data.'); - error.oid = oid; - throw error; - } - - // get cipher - oid = asn1.derToOid(capture.encAlgorithm); - var cipher = pki.pbe.getCipher(oid, capture.encParameter, password); - - // get encrypted data - var encryptedContentAsn1 = _decodePkcs7Data(capture.encryptedContentAsn1); - var encrypted = forge.util.createBuffer(encryptedContentAsn1.value); - - cipher.update(encrypted); - if(!cipher.finish()) { - throw new Error('Failed to decrypt PKCS#12 SafeContents.'); - } - - return cipher.output.getBytes(); -} - -/** - * Decode PKCS#12 SafeContents (BER-encoded) into array of Bag objects. - * - * The safeContents is a BER-encoded SEQUENCE OF SafeBag. - * - * @param {String} safeContents BER-encoded safeContents. - * @param strict true to use strict DER decoding, false not to. - * @param {String} password Password to decrypt with (optional). - * - * @return {Array} Array of Bag objects. - */ -function _decodeSafeContents(safeContents, strict, password) { - // if strict and no safe contents, return empty safes - if(!strict && safeContents.length === 0) { - return []; - } - - // actually it's BER-encoded - safeContents = asn1.fromDer(safeContents, strict); - - if(safeContents.tagClass !== asn1.Class.UNIVERSAL || - safeContents.type !== asn1.Type.SEQUENCE || - safeContents.constructed !== true) { - throw new Error( - 'PKCS#12 SafeContents expected to be a SEQUENCE OF SafeBag.'); - } - - var res = []; - for(var i = 0; i < safeContents.value.length; i++) { - var safeBag = safeContents.value[i]; - - // validate SafeBag and capture data - var capture = {}; - var errors = []; - if(!asn1.validate(safeBag, safeBagValidator, capture, errors)) { - var error = new Error('Cannot read SafeBag.'); - error.errors = errors; - throw error; - } - - /* Create bag object and push to result array. */ - var bag = { - type: asn1.derToOid(capture.bagId), - attributes: _decodeBagAttributes(capture.bagAttributes) - }; - res.push(bag); - - var validator, decoder; - var bagAsn1 = capture.bagValue.value[0]; - switch(bag.type) { - case pki.oids.pkcs8ShroudedKeyBag: - /* bagAsn1 has a EncryptedPrivateKeyInfo, which we need to decrypt. - Afterwards we can handle it like a keyBag, - which is a PrivateKeyInfo. */ - bagAsn1 = pki.decryptPrivateKeyInfo(bagAsn1, password); - if(bagAsn1 === null) { - throw new Error( - 'Unable to decrypt PKCS#8 ShroudedKeyBag, wrong password?'); - } - - /* fall through */ - case pki.oids.keyBag: - /* A PKCS#12 keyBag is a simple PrivateKeyInfo as understood by our - PKI module, hence we don't have to do validation/capturing here, - just pass what we already got. */ - try { - bag.key = pki.privateKeyFromAsn1(bagAsn1); - } catch(e) { - // ignore unknown key type, pass asn1 value - bag.key = null; - bag.asn1 = bagAsn1; - } - continue; /* Nothing more to do. */ - - case pki.oids.certBag: - /* A PKCS#12 certBag can wrap both X.509 and sdsi certificates. - Therefore put the SafeBag content through another validator to - capture the fields. Afterwards check & store the results. */ - validator = certBagValidator; - decoder = function() { - if(asn1.derToOid(capture.certId) !== pki.oids.x509Certificate) { - var error = new Error( - 'Unsupported certificate type, only X.509 supported.'); - error.oid = asn1.derToOid(capture.certId); - throw error; - } - - // true=produce cert hash - var certAsn1 = asn1.fromDer(capture.cert, strict); - try { - bag.cert = pki.certificateFromAsn1(certAsn1, true); - } catch(e) { - // ignore unknown cert type, pass asn1 value - bag.cert = null; - bag.asn1 = certAsn1; - } - }; - break; - - default: - var error = new Error('Unsupported PKCS#12 SafeBag type.'); - error.oid = bag.type; - throw error; - } - - /* Validate SafeBag value (i.e. CertBag, etc.) and capture data if needed. */ - if(validator !== undefined && - !asn1.validate(bagAsn1, validator, capture, errors)) { - var error = new Error('Cannot read PKCS#12 ' + validator.name); - error.errors = errors; - throw error; - } - - /* Call decoder function from above to store the results. */ - decoder(); - } - - return res; -} - -/** - * Decode PKCS#12 SET OF PKCS12Attribute into JavaScript object. - * - * @param attributes SET OF PKCS12Attribute (ASN.1 object). - * - * @return the decoded attributes. - */ -function _decodeBagAttributes(attributes) { - var decodedAttrs = {}; - - if(attributes !== undefined) { - for(var i = 0; i < attributes.length; ++i) { - var capture = {}; - var errors = []; - if(!asn1.validate(attributes[i], attributeValidator, capture, errors)) { - var error = new Error('Cannot read PKCS#12 BagAttribute.'); - error.errors = errors; - throw error; - } - - var oid = asn1.derToOid(capture.oid); - if(pki.oids[oid] === undefined) { - // unsupported attribute type, ignore. - continue; - } - - decodedAttrs[pki.oids[oid]] = []; - for(var j = 0; j < capture.values.length; ++j) { - decodedAttrs[pki.oids[oid]].push(capture.values[j].value); - } - } - } - - return decodedAttrs; -} - -/** - * Wraps a private key and certificate in a PKCS#12 PFX wrapper. If a - * password is provided then the private key will be encrypted. - * - * An entire certificate chain may also be included. To do this, pass - * an array for the "cert" parameter where the first certificate is - * the one that is paired with the private key and each subsequent one - * verifies the previous one. The certificates may be in PEM format or - * have been already parsed by Forge. - * - * @todo implement password-based-encryption for the whole package - * - * @param key the private key. - * @param cert the certificate (may be an array of certificates in order - * to specify a certificate chain). - * @param password the password to use, null for none. - * @param options: - * algorithm the encryption algorithm to use - * ('aes128', 'aes192', 'aes256', '3des'), defaults to 'aes128'. - * count the iteration count to use. - * saltSize the salt size to use. - * useMac true to include a MAC, false not to, defaults to true. - * localKeyId the local key ID to use, in hex. - * friendlyName the friendly name to use. - * generateLocalKeyId true to generate a random local key ID, - * false not to, defaults to true. - * - * @return the PKCS#12 PFX ASN.1 object. - */ -p12.toPkcs12Asn1 = function(key, cert, password, options) { - // set default options - options = options || {}; - options.saltSize = options.saltSize || 8; - options.count = options.count || 2048; - options.algorithm = options.algorithm || options.encAlgorithm || 'aes128'; - if(!('useMac' in options)) { - options.useMac = true; - } - if(!('localKeyId' in options)) { - options.localKeyId = null; - } - if(!('generateLocalKeyId' in options)) { - options.generateLocalKeyId = true; - } - - var localKeyId = options.localKeyId; - var bagAttrs; - if(localKeyId !== null) { - localKeyId = forge.util.hexToBytes(localKeyId); - } else if(options.generateLocalKeyId) { - // use SHA-1 of paired cert, if available - if(cert) { - var pairedCert = forge.util.isArray(cert) ? cert[0] : cert; - if(typeof pairedCert === 'string') { - pairedCert = pki.certificateFromPem(pairedCert); - } - var sha1 = forge.md.sha1.create(); - sha1.update(asn1.toDer(pki.certificateToAsn1(pairedCert)).getBytes()); - localKeyId = sha1.digest().getBytes(); - } else { - // FIXME: consider using SHA-1 of public key (which can be generated - // from private key components), see: cert.generateSubjectKeyIdentifier - // generate random bytes - localKeyId = forge.random.getBytes(20); - } - } - - var attrs = []; - if(localKeyId !== null) { - attrs.push( - // localKeyID - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [ - // attrId - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, - asn1.oidToDer(pki.oids.localKeyId).getBytes()), - // attrValues - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SET, true, [ - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OCTETSTRING, false, - localKeyId) - ]) - ])); - } - if('friendlyName' in options) { - attrs.push( - // friendlyName - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [ - // attrId - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, - asn1.oidToDer(pki.oids.friendlyName).getBytes()), - // attrValues - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SET, true, [ - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.BMPSTRING, false, - options.friendlyName) - ]) - ])); - } - - if(attrs.length > 0) { - bagAttrs = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SET, true, attrs); - } - - // collect contents for AuthenticatedSafe - var contents = []; - - // create safe bag(s) for certificate chain - var chain = []; - if(cert !== null) { - if(forge.util.isArray(cert)) { - chain = cert; - } else { - chain = [cert]; - } - } - - var certSafeBags = []; - for(var i = 0; i < chain.length; ++i) { - // convert cert from PEM as necessary - cert = chain[i]; - if(typeof cert === 'string') { - cert = pki.certificateFromPem(cert); - } - - // SafeBag - var certBagAttrs = (i === 0) ? bagAttrs : undefined; - var certAsn1 = pki.certificateToAsn1(cert); - var certSafeBag = - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [ - // bagId - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, - asn1.oidToDer(pki.oids.certBag).getBytes()), - // bagValue - asn1.create(asn1.Class.CONTEXT_SPECIFIC, 0, true, [ - // CertBag - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [ - // certId - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, - asn1.oidToDer(pki.oids.x509Certificate).getBytes()), - // certValue (x509Certificate) - asn1.create(asn1.Class.CONTEXT_SPECIFIC, 0, true, [ - asn1.create( - asn1.Class.UNIVERSAL, asn1.Type.OCTETSTRING, false, - asn1.toDer(certAsn1).getBytes()) - ])])]), - // bagAttributes (OPTIONAL) - certBagAttrs - ]); - certSafeBags.push(certSafeBag); - } - - if(certSafeBags.length > 0) { - // SafeContents - var certSafeContents = asn1.create( - asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, certSafeBags); - - // ContentInfo - var certCI = - // PKCS#7 ContentInfo - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [ - // contentType - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, - // OID for the content type is 'data' - asn1.oidToDer(pki.oids.data).getBytes()), - // content - asn1.create(asn1.Class.CONTEXT_SPECIFIC, 0, true, [ - asn1.create( - asn1.Class.UNIVERSAL, asn1.Type.OCTETSTRING, false, - asn1.toDer(certSafeContents).getBytes()) - ]) - ]); - contents.push(certCI); - } - - // create safe contents for private key - var keyBag = null; - if(key !== null) { - // SafeBag - var pkAsn1 = pki.wrapRsaPrivateKey(pki.privateKeyToAsn1(key)); - if(password === null) { - // no encryption - keyBag = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [ - // bagId - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, - asn1.oidToDer(pki.oids.keyBag).getBytes()), - // bagValue - asn1.create(asn1.Class.CONTEXT_SPECIFIC, 0, true, [ - // PrivateKeyInfo - pkAsn1 - ]), - // bagAttributes (OPTIONAL) - bagAttrs - ]); - } else { - // encrypted PrivateKeyInfo - keyBag = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [ - // bagId - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, - asn1.oidToDer(pki.oids.pkcs8ShroudedKeyBag).getBytes()), - // bagValue - asn1.create(asn1.Class.CONTEXT_SPECIFIC, 0, true, [ - // EncryptedPrivateKeyInfo - pki.encryptPrivateKeyInfo(pkAsn1, password, options) - ]), - // bagAttributes (OPTIONAL) - bagAttrs - ]); - } - - // SafeContents - var keySafeContents = - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [keyBag]); - - // ContentInfo - var keyCI = - // PKCS#7 ContentInfo - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [ - // contentType - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, - // OID for the content type is 'data' - asn1.oidToDer(pki.oids.data).getBytes()), - // content - asn1.create(asn1.Class.CONTEXT_SPECIFIC, 0, true, [ - asn1.create( - asn1.Class.UNIVERSAL, asn1.Type.OCTETSTRING, false, - asn1.toDer(keySafeContents).getBytes()) - ]) - ]); - contents.push(keyCI); - } - - // create AuthenticatedSafe by stringing together the contents - var safe = asn1.create( - asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, contents); - - var macData; - if(options.useMac) { - // MacData - var sha1 = forge.md.sha1.create(); - var macSalt = new forge.util.ByteBuffer( - forge.random.getBytes(options.saltSize)); - var count = options.count; - // 160-bit key - var key = p12.generateKey(password, macSalt, 3, count, 20); - var mac = forge.hmac.create(); - mac.start(sha1, key); - mac.update(asn1.toDer(safe).getBytes()); - var macValue = mac.getMac(); - macData = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [ - // mac DigestInfo - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [ - // digestAlgorithm - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [ - // algorithm = SHA-1 - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, - asn1.oidToDer(pki.oids.sha1).getBytes()), - // parameters = Null - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.NULL, false, '') - ]), - // digest - asn1.create( - asn1.Class.UNIVERSAL, asn1.Type.OCTETSTRING, - false, macValue.getBytes()) - ]), - // macSalt OCTET STRING - asn1.create( - asn1.Class.UNIVERSAL, asn1.Type.OCTETSTRING, false, macSalt.getBytes()), - // iterations INTEGER (XXX: Only support count < 65536) - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false, - asn1.integerToDer(count).getBytes() - ) - ]); - } - - // PFX - return asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [ - // version (3) - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false, - asn1.integerToDer(3).getBytes()), - // PKCS#7 ContentInfo - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [ - // contentType - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, - // OID for the content type is 'data' - asn1.oidToDer(pki.oids.data).getBytes()), - // content - asn1.create(asn1.Class.CONTEXT_SPECIFIC, 0, true, [ - asn1.create( - asn1.Class.UNIVERSAL, asn1.Type.OCTETSTRING, false, - asn1.toDer(safe).getBytes()) - ]) - ]), - macData - ]); -}; - -/** - * Derives a PKCS#12 key. - * - * @param password the password to derive the key material from, null or - * undefined for none. - * @param salt the salt, as a ByteBuffer, to use. - * @param id the PKCS#12 ID byte (1 = key material, 2 = IV, 3 = MAC). - * @param iter the iteration count. - * @param n the number of bytes to derive from the password. - * @param md the message digest to use, defaults to SHA-1. - * - * @return a ByteBuffer with the bytes derived from the password. - */ -p12.generateKey = forge.pbe.generatePkcs12Key; - -} // end module implementation - -/* ########## Begin module wrapper ########## */ -var name = 'pkcs12'; -if(typeof define !== 'function') { - // NodeJS -> AMD - if(typeof module === 'object' && module.exports) { - var nodeJS = true; - define = function(ids, factory) { - factory(require, module); - }; - } else { - // <script> - if(typeof forge === 'undefined') { - forge = {}; - } - return initModule(forge); - } -} -// AMD -var deps; -var defineFunc = function(require, module) { - module.exports = function(forge) { - var mods = deps.map(function(dep) { - return require(dep); - }).concat(initModule); - // handle circular dependencies - forge = forge || {}; - forge.defined = forge.defined || {}; - if(forge.defined[name]) { - return forge[name]; - } - forge.defined[name] = true; - for(var i = 0; i < mods.length; ++i) { - mods[i](forge); - } - return forge[name]; - }; -}; -var tmpDefine = define; -define = function(ids, factory) { - deps = (typeof ids === 'string') ? factory.slice(2) : ids.slice(2); - if(nodeJS) { - delete define; - return tmpDefine.apply(null, Array.prototype.slice.call(arguments, 0)); - } - define = tmpDefine; - return define.apply(null, Array.prototype.slice.call(arguments, 0)); -}; -define([ - 'require', - 'module', - './asn1', - './hmac', - './oids', - './pkcs7asn1', - './pbe', - './random', - './rsa', - './sha1', - './util', - './x509' -], function() { - defineFunc.apply(null, Array.prototype.slice.call(arguments, 0)); -}); -})(); diff --git a/alarm/node_modules/node-forge/js/pkcs7.js b/alarm/node_modules/node-forge/js/pkcs7.js deleted file mode 100644 index ffa7413..0000000 --- a/alarm/node_modules/node-forge/js/pkcs7.js +++ /dev/null @@ -1,842 +0,0 @@ -/** - * Javascript implementation of PKCS#7 v1.5. Currently only certain parts of - * PKCS#7 are implemented, especially the enveloped-data content type. - * - * @author Stefan Siegl - * - * Copyright (c) 2012 Stefan Siegl <stesie@brokenpipe.de> - * - * Currently this implementation only supports ContentType of either - * EnvelopedData or EncryptedData on root level. The top level elements may - * contain only a ContentInfo of ContentType Data, i.e. plain data. Further - * nesting is not (yet) supported. - * - * The Forge validators for PKCS #7's ASN.1 structures are available from - * a seperate file pkcs7asn1.js, since those are referenced from other - * PKCS standards like PKCS #12. - */ -(function() { -/* ########## Begin module implementation ########## */ -function initModule(forge) { - -// shortcut for ASN.1 API -var asn1 = forge.asn1; - -// shortcut for PKCS#7 API -var p7 = forge.pkcs7 = forge.pkcs7 || {}; - -/** - * Converts a PKCS#7 message from PEM format. - * - * @param pem the PEM-formatted PKCS#7 message. - * - * @return the PKCS#7 message. - */ -p7.messageFromPem = function(pem) { - var msg = forge.pem.decode(pem)[0]; - - if(msg.type !== 'PKCS7') { - var error = new Error('Could not convert PKCS#7 message from PEM; PEM ' + - 'header type is not "PKCS#7".'); - error.headerType = msg.type; - throw error; - } - if(msg.procType && msg.procType.type === 'ENCRYPTED') { - throw new Error('Could not convert PKCS#7 message from PEM; PEM is encrypted.'); - } - - // convert DER to ASN.1 object - var obj = asn1.fromDer(msg.body); - - return p7.messageFromAsn1(obj); -}; - -/** - * Converts a PKCS#7 message to PEM format. - * - * @param msg The PKCS#7 message object - * @param maxline The maximum characters per line, defaults to 64. - * - * @return The PEM-formatted PKCS#7 message. - */ -p7.messageToPem = function(msg, maxline) { - // convert to ASN.1, then DER, then PEM-encode - var pemObj = { - type: 'PKCS7', - body: asn1.toDer(msg.toAsn1()).getBytes() - }; - return forge.pem.encode(pemObj, {maxline: maxline}); -}; - -/** - * Converts a PKCS#7 message from an ASN.1 object. - * - * @param obj the ASN.1 representation of a ContentInfo. - * - * @return the PKCS#7 message. - */ -p7.messageFromAsn1 = function(obj) { - // validate root level ContentInfo and capture data - var capture = {}; - var errors = []; - if(!asn1.validate(obj, p7.asn1.contentInfoValidator, capture, errors)) - { - var error = new Error('Cannot read PKCS#7 message. ' + - 'ASN.1 object is not an PKCS#7 ContentInfo.'); - error.errors = errors; - throw error; - } - - var contentType = asn1.derToOid(capture.contentType); - var msg; - - switch(contentType) { - case forge.pki.oids.envelopedData: - msg = p7.createEnvelopedData(); - break; - - case forge.pki.oids.encryptedData: - msg = p7.createEncryptedData(); - break; - - case forge.pki.oids.signedData: - msg = p7.createSignedData(); - break; - - default: - throw new Error('Cannot read PKCS#7 message. ContentType with OID ' + - contentType + ' is not (yet) supported.'); - } - - msg.fromAsn1(capture.content.value[0]); - return msg; -}; - -/** - * Converts a single RecipientInfo from an ASN.1 object. - * - * @param obj The ASN.1 representation of a RecipientInfo. - * - * @return The recipientInfo object. - */ -var _recipientInfoFromAsn1 = function(obj) { - // Validate EnvelopedData content block and capture data. - var capture = {}; - var errors = []; - if(!asn1.validate(obj, p7.asn1.recipientInfoValidator, capture, errors)) - { - var error = new Error('Cannot read PKCS#7 message. ' + - 'ASN.1 object is not an PKCS#7 EnvelopedData.'); - error.errors = errors; - throw error; - } - - return { - version: capture.version.charCodeAt(0), - issuer: forge.pki.RDNAttributesAsArray(capture.issuer), - serialNumber: forge.util.createBuffer(capture.serial).toHex(), - encryptedContent: { - algorithm: asn1.derToOid(capture.encAlgorithm), - parameter: capture.encParameter.value, - content: capture.encKey - } - }; -}; - -/** - * Converts a single recipientInfo object to an ASN.1 object. - * - * @param obj The recipientInfo object. - * - * @return The ASN.1 representation of a RecipientInfo. - */ -var _recipientInfoToAsn1 = function(obj) { - return asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [ - // Version - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false, - asn1.integerToDer(obj.version).getBytes()), - // IssuerAndSerialNumber - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [ - // Name - forge.pki.distinguishedNameToAsn1({attributes: obj.issuer}), - // Serial - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false, - forge.util.hexToBytes(obj.serialNumber)) - ]), - // KeyEncryptionAlgorithmIdentifier - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [ - // Algorithm - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, - asn1.oidToDer(obj.encryptedContent.algorithm).getBytes()), - // Parameter, force NULL, only RSA supported for now. - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.NULL, false, '') - ]), - // EncryptedKey - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OCTETSTRING, false, - obj.encryptedContent.content) - ]); -}; - -/** - * Map a set of RecipientInfo ASN.1 objects to recipientInfo objects. - * - * @param objArr Array of ASN.1 representations RecipientInfo (i.e. SET OF). - * - * @return array of recipientInfo objects. - */ -var _recipientInfosFromAsn1 = function(objArr) { - var ret = []; - for(var i = 0; i < objArr.length; i ++) { - ret.push(_recipientInfoFromAsn1(objArr[i])); - } - return ret; -}; - -/** - * Map an array of recipientInfo objects to ASN.1 objects. - * - * @param recipientsArr Array of recipientInfo objects. - * - * @return Array of ASN.1 representations RecipientInfo. - */ -var _recipientInfosToAsn1 = function(recipientsArr) { - var ret = []; - for(var i = 0; i < recipientsArr.length; i ++) { - ret.push(_recipientInfoToAsn1(recipientsArr[i])); - } - return ret; -}; - -/** - * Map messages encrypted content to ASN.1 objects. - * - * @param ec The encryptedContent object of the message. - * - * @return ASN.1 representation of the encryptedContent object (SEQUENCE). - */ -var _encryptedContentToAsn1 = function(ec) { - return [ - // ContentType, always Data for the moment - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, - asn1.oidToDer(forge.pki.oids.data).getBytes()), - // ContentEncryptionAlgorithmIdentifier - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [ - // Algorithm - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, - asn1.oidToDer(ec.algorithm).getBytes()), - // Parameters (IV) - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OCTETSTRING, false, - ec.parameter.getBytes()) - ]), - // [0] EncryptedContent - asn1.create(asn1.Class.CONTEXT_SPECIFIC, 0, true, [ - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OCTETSTRING, false, - ec.content.getBytes()) - ]) - ]; -}; - -/** - * Reads the "common part" of an PKCS#7 content block (in ASN.1 format) - * - * This function reads the "common part" of the PKCS#7 content blocks - * EncryptedData and EnvelopedData, i.e. version number and symmetrically - * encrypted content block. - * - * The result of the ASN.1 validate and capture process is returned - * to allow the caller to extract further data, e.g. the list of recipients - * in case of a EnvelopedData object. - * - * @param msg the PKCS#7 object to read the data to. - * @param obj the ASN.1 representation of the content block. - * @param validator the ASN.1 structure validator object to use. - * - * @return the value map captured by validator object. - */ -var _fromAsn1 = function(msg, obj, validator) { - var capture = {}; - var errors = []; - if(!asn1.validate(obj, validator, capture, errors)) { - var error = new Error('Cannot read PKCS#7 message. ' + - 'ASN.1 object is not a supported PKCS#7 message.'); - error.errors = error; - throw error; - } - - // Check contentType, so far we only support (raw) Data. - var contentType = asn1.derToOid(capture.contentType); - if(contentType !== forge.pki.oids.data) { - throw new Error('Unsupported PKCS#7 message. ' + - 'Only wrapped ContentType Data supported.'); - } - - if(capture.encryptedContent) { - var content = ''; - if(forge.util.isArray(capture.encryptedContent)) { - for(var i = 0; i < capture.encryptedContent.length; ++i) { - if(capture.encryptedContent[i].type !== asn1.Type.OCTETSTRING) { - throw new Error('Malformed PKCS#7 message, expecting encrypted ' + - 'content constructed of only OCTET STRING objects.'); - } - content += capture.encryptedContent[i].value; - } - } else { - content = capture.encryptedContent; - } - msg.encryptedContent = { - algorithm: asn1.derToOid(capture.encAlgorithm), - parameter: forge.util.createBuffer(capture.encParameter.value), - content: forge.util.createBuffer(content) - }; - } - - if(capture.content) { - var content = ''; - if(forge.util.isArray(capture.content)) { - for(var i = 0; i < capture.content.length; ++i) { - if(capture.content[i].type !== asn1.Type.OCTETSTRING) { - throw new Error('Malformed PKCS#7 message, expecting ' + - 'content constructed of only OCTET STRING objects.'); - } - content += capture.content[i].value; - } - } else { - content = capture.content; - } - msg.content = forge.util.createBuffer(content); - } - - msg.version = capture.version.charCodeAt(0); - msg.rawCapture = capture; - - return capture; -}; - -/** - * Decrypt the symmetrically encrypted content block of the PKCS#7 message. - * - * Decryption is skipped in case the PKCS#7 message object already has a - * (decrypted) content attribute. The algorithm, key and cipher parameters - * (probably the iv) are taken from the encryptedContent attribute of the - * message object. - * - * @param The PKCS#7 message object. - */ -var _decryptContent = function (msg) { - if(msg.encryptedContent.key === undefined) { - throw new Error('Symmetric key not available.'); - } - - if(msg.content === undefined) { - var ciph; - - switch(msg.encryptedContent.algorithm) { - case forge.pki.oids['aes128-CBC']: - case forge.pki.oids['aes192-CBC']: - case forge.pki.oids['aes256-CBC']: - ciph = forge.aes.createDecryptionCipher(msg.encryptedContent.key); - break; - - case forge.pki.oids['desCBC']: - case forge.pki.oids['des-EDE3-CBC']: - ciph = forge.des.createDecryptionCipher(msg.encryptedContent.key); - break; - - default: - throw new Error('Unsupported symmetric cipher, OID ' + - msg.encryptedContent.algorithm); - } - ciph.start(msg.encryptedContent.parameter); - ciph.update(msg.encryptedContent.content); - - if(!ciph.finish()) { - throw new Error('Symmetric decryption failed.'); - } - - msg.content = ciph.output; - } -}; - -p7.createSignedData = function() { - var msg = null; - msg = { - type: forge.pki.oids.signedData, - version: 1, - certificates: [], - crls: [], - // populated during sign() - digestAlgorithmIdentifiers: [], - contentInfo: null, - signerInfos: [], - - fromAsn1: function(obj) { - // validate SignedData content block and capture data. - _fromAsn1(msg, obj, p7.asn1.signedDataValidator); - msg.certificates = []; - msg.crls = []; - msg.digestAlgorithmIdentifiers = []; - msg.contentInfo = null; - msg.signerInfos = []; - - var certs = msg.rawCapture.certificates.value; - for(var i = 0; i < certs.length; ++i) { - msg.certificates.push(forge.pki.certificateFromAsn1(certs[i])); - } - - // TODO: parse crls - }, - - toAsn1: function() { - // TODO: add support for more data types here - if('content' in msg) { - throw new Error('Signing PKCS#7 content not yet implemented.'); - } - - // degenerate case with no content - if(!msg.contentInfo) { - msg.sign(); - } - - var certs = []; - for(var i = 0; i < msg.certificates.length; ++i) { - certs.push(forge.pki.certificateToAsn1(msg.certificates[0])); - } - - var crls = []; - // TODO: implement CRLs - - // ContentInfo - return asn1.create( - asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [ - // ContentType - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, - asn1.oidToDer(msg.type).getBytes()), - // [0] SignedData - asn1.create(asn1.Class.CONTEXT_SPECIFIC, 0, true, [ - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [ - // Version - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false, - asn1.integerToDer(msg.version).getBytes()), - // DigestAlgorithmIdentifiers - asn1.create( - asn1.Class.UNIVERSAL, asn1.Type.SET, true, - msg.digestAlgorithmIdentifiers), - // ContentInfo - msg.contentInfo, - // [0] IMPLICIT ExtendedCertificatesAndCertificates - asn1.create(asn1.Class.CONTEXT_SPECIFIC, 0, true, certs), - // [1] IMPLICIT CertificateRevocationLists - asn1.create(asn1.Class.CONTEXT_SPECIFIC, 1, true, crls), - // SignerInfos - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SET, true, - msg.signerInfos) - ]) - ]) - ]); - }, - - /** - * Signs the content. - * - * @param signer the signer (or array of signers) to sign as, for each: - * key the private key to sign with. - * [md] the message digest to use, defaults to sha-1. - */ - sign: function(signer) { - if('content' in msg) { - throw new Error('PKCS#7 signing not yet implemented.'); - } - - if(typeof msg.content !== 'object') { - // use Data ContentInfo - msg.contentInfo = asn1.create( - asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [ - // ContentType - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, - asn1.oidToDer(forge.pki.oids.data).getBytes()) - ]); - - // add actual content, if present - if('content' in msg) { - msg.contentInfo.value.push( - // [0] EXPLICIT content - asn1.create(asn1.Class.CONTEXT_SPECIFIC, 0, true, [ - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OCTETSTRING, false, - msg.content) - ])); - } - } - - // TODO: generate digest algorithm identifiers - - // TODO: generate signerInfos - }, - - verify: function() { - throw new Error('PKCS#7 signature verification not yet implemented.'); - }, - - /** - * Add a certificate. - * - * @param cert the certificate to add. - */ - addCertificate: function(cert) { - // convert from PEM - if(typeof cert === 'string') { - cert = forge.pki.certificateFromPem(cert); - } - msg.certificates.push(cert); - }, - - /** - * Add a certificate revokation list. - * - * @param crl the certificate revokation list to add. - */ - addCertificateRevokationList: function(crl) { - throw new Error('PKCS#7 CRL support not yet implemented.'); - } - }; - return msg; -}; - -/** - * Creates an empty PKCS#7 message of type EncryptedData. - * - * @return the message. - */ -p7.createEncryptedData = function() { - var msg = null; - msg = { - type: forge.pki.oids.encryptedData, - version: 0, - encryptedContent: { - algorithm: forge.pki.oids['aes256-CBC'] - }, - - /** - * Reads an EncryptedData content block (in ASN.1 format) - * - * @param obj The ASN.1 representation of the EncryptedData content block - */ - fromAsn1: function(obj) { - // Validate EncryptedData content block and capture data. - _fromAsn1(msg, obj, p7.asn1.encryptedDataValidator); - }, - - /** - * Decrypt encrypted content - * - * @param key The (symmetric) key as a byte buffer - */ - decrypt: function(key) { - if(key !== undefined) { - msg.encryptedContent.key = key; - } - _decryptContent(msg); - } - }; - return msg; -}; - -/** - * Creates an empty PKCS#7 message of type EnvelopedData. - * - * @return the message. - */ -p7.createEnvelopedData = function() { - var msg = null; - msg = { - type: forge.pki.oids.envelopedData, - version: 0, - recipients: [], - encryptedContent: { - algorithm: forge.pki.oids['aes256-CBC'] - }, - - /** - * Reads an EnvelopedData content block (in ASN.1 format) - * - * @param obj the ASN.1 representation of the EnvelopedData content block. - */ - fromAsn1: function(obj) { - // validate EnvelopedData content block and capture data - var capture = _fromAsn1(msg, obj, p7.asn1.envelopedDataValidator); - msg.recipients = _recipientInfosFromAsn1(capture.recipientInfos.value); - }, - - toAsn1: function() { - // ContentInfo - return asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [ - // ContentType - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, - asn1.oidToDer(msg.type).getBytes()), - // [0] EnvelopedData - asn1.create(asn1.Class.CONTEXT_SPECIFIC, 0, true, [ - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [ - // Version - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false, - asn1.integerToDer(msg.version).getBytes()), - // RecipientInfos - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SET, true, - _recipientInfosToAsn1(msg.recipients)), - // EncryptedContentInfo - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, - _encryptedContentToAsn1(msg.encryptedContent)) - ]) - ]) - ]); - }, - - /** - * Find recipient by X.509 certificate's issuer. - * - * @param cert the certificate with the issuer to look for. - * - * @return the recipient object. - */ - findRecipient: function(cert) { - var sAttr = cert.issuer.attributes; - - for(var i = 0; i < msg.recipients.length; ++i) { - var r = msg.recipients[i]; - var rAttr = r.issuer; - - if(r.serialNumber !== cert.serialNumber) { - continue; - } - - if(rAttr.length !== sAttr.length) { - continue; - } - - var match = true; - for(var j = 0; j < sAttr.length; ++j) { - if(rAttr[j].type !== sAttr[j].type || - rAttr[j].value !== sAttr[j].value) { - match = false; - break; - } - } - - if(match) { - return r; - } - } - - return null; - }, - - /** - * Decrypt enveloped content - * - * @param recipient The recipient object related to the private key - * @param privKey The (RSA) private key object - */ - decrypt: function(recipient, privKey) { - if(msg.encryptedContent.key === undefined && recipient !== undefined && - privKey !== undefined) { - switch(recipient.encryptedContent.algorithm) { - case forge.pki.oids.rsaEncryption: - case forge.pki.oids.desCBC: - var key = privKey.decrypt(recipient.encryptedContent.content); - msg.encryptedContent.key = forge.util.createBuffer(key); - break; - - default: - throw new Error('Unsupported asymmetric cipher, ' + - 'OID ' + recipient.encryptedContent.algorithm); - } - } - - _decryptContent(msg); - }, - - /** - * Add (another) entity to list of recipients. - * - * @param cert The certificate of the entity to add. - */ - addRecipient: function(cert) { - msg.recipients.push({ - version: 0, - issuer: cert.issuer.attributes, - serialNumber: cert.serialNumber, - encryptedContent: { - // We simply assume rsaEncryption here, since forge.pki only - // supports RSA so far. If the PKI module supports other - // ciphers one day, we need to modify this one as well. - algorithm: forge.pki.oids.rsaEncryption, - key: cert.publicKey - } - }); - }, - - /** - * Encrypt enveloped content. - * - * This function supports two optional arguments, cipher and key, which - * can be used to influence symmetric encryption. Unless cipher is - * provided, the cipher specified in encryptedContent.algorithm is used - * (defaults to AES-256-CBC). If no key is provided, encryptedContent.key - * is (re-)used. If that one's not set, a random key will be generated - * automatically. - * - * @param [key] The key to be used for symmetric encryption. - * @param [cipher] The OID of the symmetric cipher to use. - */ - encrypt: function(key, cipher) { - // Part 1: Symmetric encryption - if(msg.encryptedContent.content === undefined) { - cipher = cipher || msg.encryptedContent.algorithm; - key = key || msg.encryptedContent.key; - - var keyLen, ivLen, ciphFn; - switch(cipher) { - case forge.pki.oids['aes128-CBC']: - keyLen = 16; - ivLen = 16; - ciphFn = forge.aes.createEncryptionCipher; - break; - - case forge.pki.oids['aes192-CBC']: - keyLen = 24; - ivLen = 16; - ciphFn = forge.aes.createEncryptionCipher; - break; - - case forge.pki.oids['aes256-CBC']: - keyLen = 32; - ivLen = 16; - ciphFn = forge.aes.createEncryptionCipher; - break; - - case forge.pki.oids['des-EDE3-CBC']: - keyLen = 24; - ivLen = 8; - ciphFn = forge.des.createEncryptionCipher; - break; - - default: - throw new Error('Unsupported symmetric cipher, OID ' + cipher); - } - - if(key === undefined) { - key = forge.util.createBuffer(forge.random.getBytes(keyLen)); - } else if(key.length() != keyLen) { - throw new Error('Symmetric key has wrong length; ' + - 'got ' + key.length() + ' bytes, expected ' + keyLen + '.'); - } - - // Keep a copy of the key & IV in the object, so the caller can - // use it for whatever reason. - msg.encryptedContent.algorithm = cipher; - msg.encryptedContent.key = key; - msg.encryptedContent.parameter = forge.util.createBuffer( - forge.random.getBytes(ivLen)); - - var ciph = ciphFn(key); - ciph.start(msg.encryptedContent.parameter.copy()); - ciph.update(msg.content); - - // The finish function does PKCS#7 padding by default, therefore - // no action required by us. - if(!ciph.finish()) { - throw new Error('Symmetric encryption failed.'); - } - - msg.encryptedContent.content = ciph.output; - } - - // Part 2: asymmetric encryption for each recipient - for(var i = 0; i < msg.recipients.length; i ++) { - var recipient = msg.recipients[i]; - - // Nothing to do, encryption already done. - if(recipient.encryptedContent.content !== undefined) { - continue; - } - - switch(recipient.encryptedContent.algorithm) { - case forge.pki.oids.rsaEncryption: - recipient.encryptedContent.content = - recipient.encryptedContent.key.encrypt( - msg.encryptedContent.key.data); - break; - - default: - throw new Error('Unsupported asymmetric cipher, OID ' + - recipient.encryptedContent.algorithm); - } - } - } - }; - return msg; -}; - -} // end module implementation - -/* ########## Begin module wrapper ########## */ -var name = 'pkcs7'; -if(typeof define !== 'function') { - // NodeJS -> AMD - if(typeof module === 'object' && module.exports) { - var nodeJS = true; - define = function(ids, factory) { - factory(require, module); - }; - } else { - // <script> - if(typeof forge === 'undefined') { - forge = {}; - } - return initModule(forge); - } -} -// AMD -var deps; -var defineFunc = function(require, module) { - module.exports = function(forge) { - var mods = deps.map(function(dep) { - return require(dep); - }).concat(initModule); - // handle circular dependencies - forge = forge || {}; - forge.defined = forge.defined || {}; - if(forge.defined[name]) { - return forge[name]; - } - forge.defined[name] = true; - for(var i = 0; i < mods.length; ++i) { - mods[i](forge); - } - return forge[name]; - }; -}; -var tmpDefine = define; -define = function(ids, factory) { - deps = (typeof ids === 'string') ? factory.slice(2) : ids.slice(2); - if(nodeJS) { - delete define; - return tmpDefine.apply(null, Array.prototype.slice.call(arguments, 0)); - } - define = tmpDefine; - return define.apply(null, Array.prototype.slice.call(arguments, 0)); -}; -define([ - 'require', - 'module', - './aes', - './asn1', - './des', - './oids', - './pem', - './pkcs7asn1', - './random', - './util', - './x509' -], function() { - defineFunc.apply(null, Array.prototype.slice.call(arguments, 0)); -}); -})(); diff --git a/alarm/node_modules/node-forge/js/pkcs7asn1.js b/alarm/node_modules/node-forge/js/pkcs7asn1.js deleted file mode 100644 index f7c4df6..0000000 --- a/alarm/node_modules/node-forge/js/pkcs7asn1.js +++ /dev/null @@ -1,399 +0,0 @@ -/** - * Javascript implementation of PKCS#7 v1.5. Currently only certain parts of - * PKCS#7 are implemented, especially the enveloped-data content type. - * - * @author Stefan Siegl - * - * Copyright (c) 2012 Stefan Siegl <stesie@brokenpipe.de> - * - * The ASN.1 representation of PKCS#7 is as follows - * (see RFC #2315 for details, http://www.ietf.org/rfc/rfc2315.txt): - * - * A PKCS#7 message consists of a ContentInfo on root level, which may - * contain any number of further ContentInfo nested into it. - * - * ContentInfo ::= SEQUENCE { - * contentType ContentType, - * content [0] EXPLICIT ANY DEFINED BY contentType OPTIONAL - * } - * - * ContentType ::= OBJECT IDENTIFIER - * - * EnvelopedData ::= SEQUENCE { - * version Version, - * recipientInfos RecipientInfos, - * encryptedContentInfo EncryptedContentInfo - * } - * - * EncryptedData ::= SEQUENCE { - * version Version, - * encryptedContentInfo EncryptedContentInfo - * } - * - * Version ::= INTEGER - * - * RecipientInfos ::= SET OF RecipientInfo - * - * EncryptedContentInfo ::= SEQUENCE { - * contentType ContentType, - * contentEncryptionAlgorithm ContentEncryptionAlgorithmIdentifier, - * encryptedContent [0] IMPLICIT EncryptedContent OPTIONAL - * } - * - * ContentEncryptionAlgorithmIdentifier ::= AlgorithmIdentifier - * - * The AlgorithmIdentifier contains an Object Identifier (OID) and parameters - * for the algorithm, if any. In the case of AES and DES3, there is only one, - * the IV. - * - * AlgorithmIdentifer ::= SEQUENCE { - * algorithm OBJECT IDENTIFIER, - * parameters ANY DEFINED BY algorithm OPTIONAL - * } - * - * EncryptedContent ::= OCTET STRING - * - * RecipientInfo ::= SEQUENCE { - * version Version, - * issuerAndSerialNumber IssuerAndSerialNumber, - * keyEncryptionAlgorithm KeyEncryptionAlgorithmIdentifier, - * encryptedKey EncryptedKey - * } - * - * IssuerAndSerialNumber ::= SEQUENCE { - * issuer Name, - * serialNumber CertificateSerialNumber - * } - * - * CertificateSerialNumber ::= INTEGER - * - * KeyEncryptionAlgorithmIdentifier ::= AlgorithmIdentifier - * - * EncryptedKey ::= OCTET STRING - */ -(function() { -/* ########## Begin module implementation ########## */ -function initModule(forge) { - -// shortcut for ASN.1 API -var asn1 = forge.asn1; - -// shortcut for PKCS#7 API -var p7v = forge.pkcs7asn1 = forge.pkcs7asn1 || {}; -forge.pkcs7 = forge.pkcs7 || {}; -forge.pkcs7.asn1 = p7v; - -var contentInfoValidator = { - name: 'ContentInfo', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.SEQUENCE, - constructed: true, - value: [{ - name: 'ContentInfo.ContentType', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.OID, - constructed: false, - capture: 'contentType' - }, { - name: 'ContentInfo.content', - tagClass: asn1.Class.CONTEXT_SPECIFIC, - type: 0, - constructed: true, - optional: true, - captureAsn1: 'content' - }] -}; -p7v.contentInfoValidator = contentInfoValidator; - -var encryptedContentInfoValidator = { - name: 'EncryptedContentInfo', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.SEQUENCE, - constructed: true, - value: [{ - name: 'EncryptedContentInfo.contentType', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.OID, - constructed: false, - capture: 'contentType' - }, { - name: 'EncryptedContentInfo.contentEncryptionAlgorithm', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.SEQUENCE, - constructed: true, - value: [{ - name: 'EncryptedContentInfo.contentEncryptionAlgorithm.algorithm', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.OID, - constructed: false, - capture: 'encAlgorithm' - }, { - name: 'EncryptedContentInfo.contentEncryptionAlgorithm.parameter', - tagClass: asn1.Class.UNIVERSAL, - captureAsn1: 'encParameter' - }] - }, { - name: 'EncryptedContentInfo.encryptedContent', - tagClass: asn1.Class.CONTEXT_SPECIFIC, - type: 0, - /* The PKCS#7 structure output by OpenSSL somewhat differs from what - * other implementations do generate. - * - * OpenSSL generates a structure like this: - * SEQUENCE { - * ... - * [0] - * 26 DA 67 D2 17 9C 45 3C B1 2A A8 59 2F 29 33 38 - * C3 C3 DF 86 71 74 7A 19 9F 40 D0 29 BE 85 90 45 - * ... - * } - * - * Whereas other implementations (and this PKCS#7 module) generate: - * SEQUENCE { - * ... - * [0] { - * OCTET STRING - * 26 DA 67 D2 17 9C 45 3C B1 2A A8 59 2F 29 33 38 - * C3 C3 DF 86 71 74 7A 19 9F 40 D0 29 BE 85 90 45 - * ... - * } - * } - * - * In order to support both, we just capture the context specific - * field here. The OCTET STRING bit is removed below. - */ - capture: 'encryptedContent', - captureAsn1: 'encryptedContentAsn1' - }] -}; - -p7v.envelopedDataValidator = { - name: 'EnvelopedData', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.SEQUENCE, - constructed: true, - value: [{ - name: 'EnvelopedData.Version', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.INTEGER, - constructed: false, - capture: 'version' - }, { - name: 'EnvelopedData.RecipientInfos', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.SET, - constructed: true, - captureAsn1: 'recipientInfos' - }].concat(encryptedContentInfoValidator) -}; - -p7v.encryptedDataValidator = { - name: 'EncryptedData', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.SEQUENCE, - constructed: true, - value: [{ - name: 'EncryptedData.Version', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.INTEGER, - constructed: false, - capture: 'version' - }].concat(encryptedContentInfoValidator) -}; - -var signerValidator = { - name: 'SignerInfo', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.SEQUENCE, - constructed: true, - value: [{ - name: 'SignerInfo.Version', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.INTEGER, - constructed: false - }, { - name: 'SignerInfo.IssuerAndSerialNumber', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.SEQUENCE, - constructed: true - }, { - name: 'SignerInfo.DigestAlgorithm', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.SEQUENCE, - constructed: true - }, { - name: 'SignerInfo.AuthenticatedAttributes', - tagClass: asn1.Class.CONTEXT_SPECIFIC, - type: 0, - constructed: true, - optional: true, - capture: 'authenticatedAttributes' - }, { - name: 'SignerInfo.DigestEncryptionAlgorithm', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.SEQUENCE, - constructed: true - }, { - name: 'SignerInfo.EncryptedDigest', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.OCTETSTRING, - constructed: false, - capture: 'signature' - }, { - name: 'SignerInfo.UnauthenticatedAttributes', - tagClass: asn1.Class.CONTEXT_SPECIFIC, - type: 1, - constructed: true, - optional: true - }] -}; - -p7v.signedDataValidator = { - name: 'SignedData', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.SEQUENCE, - constructed: true, - value: [{ - name: 'SignedData.Version', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.INTEGER, - constructed: false, - capture: 'version' - }, { - name: 'SignedData.DigestAlgorithms', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.SET, - constructed: true, - captureAsn1: 'digestAlgorithms' - }, - contentInfoValidator, - { - name: 'SignedData.Certificates', - tagClass: asn1.Class.CONTEXT_SPECIFIC, - type: 0, - optional: true, - captureAsn1: 'certificates' - }, { - name: 'SignedData.CertificateRevocationLists', - tagClass: asn1.Class.CONTEXT_SPECIFIC, - type: 1, - optional: true, - captureAsn1: 'crls' - }, { - name: 'SignedData.SignerInfos', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.SET, - capture: 'signerInfos', - optional: true, - value: [signerValidator] - }] -}; - -p7v.recipientInfoValidator = { - name: 'RecipientInfo', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.SEQUENCE, - constructed: true, - value: [{ - name: 'RecipientInfo.version', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.INTEGER, - constructed: false, - capture: 'version' - }, { - name: 'RecipientInfo.issuerAndSerial', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.SEQUENCE, - constructed: true, - value: [{ - name: 'RecipientInfo.issuerAndSerial.issuer', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.SEQUENCE, - constructed: true, - captureAsn1: 'issuer' - }, { - name: 'RecipientInfo.issuerAndSerial.serialNumber', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.INTEGER, - constructed: false, - capture: 'serial' - }] - }, { - name: 'RecipientInfo.keyEncryptionAlgorithm', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.SEQUENCE, - constructed: true, - value: [{ - name: 'RecipientInfo.keyEncryptionAlgorithm.algorithm', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.OID, - constructed: false, - capture: 'encAlgorithm' - }, { - name: 'RecipientInfo.keyEncryptionAlgorithm.parameter', - tagClass: asn1.Class.UNIVERSAL, - constructed: false, - captureAsn1: 'encParameter' - }] - }, { - name: 'RecipientInfo.encryptedKey', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.OCTETSTRING, - constructed: false, - capture: 'encKey' - }] -}; - -} // end module implementation - -/* ########## Begin module wrapper ########## */ -var name = 'pkcs7asn1'; -if(typeof define !== 'function') { - // NodeJS -> AMD - if(typeof module === 'object' && module.exports) { - var nodeJS = true; - define = function(ids, factory) { - factory(require, module); - }; - } else { - // <script> - if(typeof forge === 'undefined') { - forge = {}; - } - return initModule(forge); - } -} -// AMD -var deps; -var defineFunc = function(require, module) { - module.exports = function(forge) { - var mods = deps.map(function(dep) { - return require(dep); - }).concat(initModule); - // handle circular dependencies - forge = forge || {}; - forge.defined = forge.defined || {}; - if(forge.defined[name]) { - return forge[name]; - } - forge.defined[name] = true; - for(var i = 0; i < mods.length; ++i) { - mods[i](forge); - } - return forge[name]; - }; -}; -var tmpDefine = define; -define = function(ids, factory) { - deps = (typeof ids === 'string') ? factory.slice(2) : ids.slice(2); - if(nodeJS) { - delete define; - return tmpDefine.apply(null, Array.prototype.slice.call(arguments, 0)); - } - define = tmpDefine; - return define.apply(null, Array.prototype.slice.call(arguments, 0)); -}; -define(['require', 'module', './asn1', './util'], function() { - defineFunc.apply(null, Array.prototype.slice.call(arguments, 0)); -}); -})(); diff --git a/alarm/node_modules/node-forge/js/pki.js b/alarm/node_modules/node-forge/js/pki.js deleted file mode 100644 index 3df7805..0000000 --- a/alarm/node_modules/node-forge/js/pki.js +++ /dev/null @@ -1,161 +0,0 @@ -/** - * Javascript implementation of a basic Public Key Infrastructure, including - * support for RSA public and private keys. - * - * @author Dave Longley - * - * Copyright (c) 2010-2013 Digital Bazaar, Inc. - */ -(function() { -/* ########## Begin module implementation ########## */ -function initModule(forge) { - -// shortcut for asn.1 API -var asn1 = forge.asn1; - -/* Public Key Infrastructure (PKI) implementation. */ -var pki = forge.pki = forge.pki || {}; - -/** - * NOTE: THIS METHOD IS DEPRECATED. Use pem.decode() instead. - * - * Converts PEM-formatted data to DER. - * - * @param pem the PEM-formatted data. - * - * @return the DER-formatted data. - */ -pki.pemToDer = function(pem) { - var msg = forge.pem.decode(pem)[0]; - if(msg.procType && msg.procType.type === 'ENCRYPTED') { - throw new Error('Could not convert PEM to DER; PEM is encrypted.'); - } - return forge.util.createBuffer(msg.body); -}; - -/** - * Converts an RSA private key from PEM format. - * - * @param pem the PEM-formatted private key. - * - * @return the private key. - */ -pki.privateKeyFromPem = function(pem) { - var msg = forge.pem.decode(pem)[0]; - - if(msg.type !== 'PRIVATE KEY' && msg.type !== 'RSA PRIVATE KEY') { - var error = new Error('Could not convert private key from PEM; PEM ' + - 'header type is not "PRIVATE KEY" or "RSA PRIVATE KEY".'); - error.headerType = msg.type; - throw error; - } - if(msg.procType && msg.procType.type === 'ENCRYPTED') { - throw new Error('Could not convert private key from PEM; PEM is encrypted.'); - } - - // convert DER to ASN.1 object - var obj = asn1.fromDer(msg.body); - - return pki.privateKeyFromAsn1(obj); -}; - -/** - * Converts an RSA private key to PEM format. - * - * @param key the private key. - * @param maxline the maximum characters per line, defaults to 64. - * - * @return the PEM-formatted private key. - */ -pki.privateKeyToPem = function(key, maxline) { - // convert to ASN.1, then DER, then PEM-encode - var msg = { - type: 'RSA PRIVATE KEY', - body: asn1.toDer(pki.privateKeyToAsn1(key)).getBytes() - }; - return forge.pem.encode(msg, {maxline: maxline}); -}; - -/** - * Converts a PrivateKeyInfo to PEM format. - * - * @param pki the PrivateKeyInfo. - * @param maxline the maximum characters per line, defaults to 64. - * - * @return the PEM-formatted private key. - */ -pki.privateKeyInfoToPem = function(pki, maxline) { - // convert to DER, then PEM-encode - var msg = { - type: 'PRIVATE KEY', - body: asn1.toDer(pki).getBytes() - }; - return forge.pem.encode(msg, {maxline: maxline}); -}; - -} // end module implementation - -/* ########## Begin module wrapper ########## */ -var name = 'pki'; -if(typeof define !== 'function') { - // NodeJS -> AMD - if(typeof module === 'object' && module.exports) { - var nodeJS = true; - define = function(ids, factory) { - factory(require, module); - }; - } else { - // <script> - if(typeof forge === 'undefined') { - forge = {}; - } - return initModule(forge); - } -} -// AMD -var deps; -var defineFunc = function(require, module) { - module.exports = function(forge) { - var mods = deps.map(function(dep) { - return require(dep); - }).concat(initModule); - // handle circular dependencies - forge = forge || {}; - forge.defined = forge.defined || {}; - if(forge.defined[name]) { - return forge[name]; - } - forge.defined[name] = true; - for(var i = 0; i < mods.length; ++i) { - mods[i](forge); - } - return forge[name]; - }; -}; -var tmpDefine = define; -define = function(ids, factory) { - deps = (typeof ids === 'string') ? factory.slice(2) : ids.slice(2); - if(nodeJS) { - delete define; - return tmpDefine.apply(null, Array.prototype.slice.call(arguments, 0)); - } - define = tmpDefine; - return define.apply(null, Array.prototype.slice.call(arguments, 0)); -}; -define([ - 'require', - 'module', - './asn1', - './oids', - './pbe', - './pem', - './pbkdf2', - './pkcs12', - './pss', - './rsa', - './util', - './x509' -], function() { - defineFunc.apply(null, Array.prototype.slice.call(arguments, 0)); -}); -})(); diff --git a/alarm/node_modules/node-forge/js/prime.js b/alarm/node_modules/node-forge/js/prime.js deleted file mode 100644 index 2857c36..0000000 --- a/alarm/node_modules/node-forge/js/prime.js +++ /dev/null @@ -1,337 +0,0 @@ -/** - * Prime number generation API. - * - * @author Dave Longley - * - * Copyright (c) 2014 Digital Bazaar, Inc. - */ -(function() { -/* ########## Begin module implementation ########## */ -function initModule(forge) { - -// forge.prime already defined -if(forge.prime) { - return; -} - -/* PRIME API */ -var prime = forge.prime = forge.prime || {}; - -var BigInteger = forge.jsbn.BigInteger; - -// primes are 30k+i for i = 1, 7, 11, 13, 17, 19, 23, 29 -var GCD_30_DELTA = [6, 4, 2, 4, 2, 4, 6, 2]; -var THIRTY = new BigInteger(null); -THIRTY.fromInt(30); -var op_or = function(x, y) {return x|y;}; - -/** - * Generates a random probable prime with the given number of bits. - * - * Alternative algorithms can be specified by name as a string or as an - * object with custom options like so: - * - * { - * name: 'PRIMEINC', - * options: { - * maxBlockTime: <the maximum amount of time to block the main - * thread before allowing I/O other JS to run>, - * millerRabinTests: <the number of miller-rabin tests to run>, - * workerScript: <the worker script URL>, - * workers: <the number of web workers (if supported) to use, - * -1 to use estimated cores minus one>. - * workLoad: the size of the work load, ie: number of possible prime - * numbers for each web worker to check per work assignment, - * (default: 100). - * } - * } - * - * @param bits the number of bits for the prime number. - * @param options the options to use. - * [algorithm] the algorithm to use (default: 'PRIMEINC'). - * [prng] a custom crypto-secure pseudo-random number generator to use, - * that must define "getBytesSync". - * - * @return callback(err, num) called once the operation completes. - */ -prime.generateProbablePrime = function(bits, options, callback) { - if(typeof options === 'function') { - callback = options; - options = {}; - } - options = options || {}; - - // default to PRIMEINC algorithm - var algorithm = options.algorithm || 'PRIMEINC'; - if(typeof algorithm === 'string') { - algorithm = {name: algorithm}; - } - algorithm.options = algorithm.options || {}; - - // create prng with api that matches BigInteger secure random - var prng = options.prng || forge.random; - var rng = { - // x is an array to fill with bytes - nextBytes: function(x) { - var b = prng.getBytesSync(x.length); - for(var i = 0; i < x.length; ++i) { - x[i] = b.charCodeAt(i); - } - } - }; - - if(algorithm.name === 'PRIMEINC') { - return primeincFindPrime(bits, rng, algorithm.options, callback); - } - - throw new Error('Invalid prime generation algorithm: ' + algorithm.name); -}; - -function primeincFindPrime(bits, rng, options, callback) { - if('workers' in options) { - return primeincFindPrimeWithWorkers(bits, rng, options, callback); - } - return primeincFindPrimeWithoutWorkers(bits, rng, options, callback); -} - -function primeincFindPrimeWithoutWorkers(bits, rng, options, callback) { - // initialize random number - var num = generateRandom(bits, rng); - - /* Note: All primes are of the form 30k+i for i < 30 and gcd(30, i)=1. The - number we are given is always aligned at 30k + 1. Each time the number is - determined not to be prime we add to get to the next 'i', eg: if the number - was at 30k + 1 we add 6. */ - var deltaIdx = 0; - - // get required number of MR tests - var mrTests = getMillerRabinTests(num.bitLength()); - if('millerRabinTests' in options) { - mrTests = options.millerRabinTests; - } - - // find prime nearest to 'num' for maxBlockTime ms - // 10 ms gives 5ms of leeway for other calculations before dropping - // below 60fps (1000/60 == 16.67), but in reality, the number will - // likely be higher due to an 'atomic' big int modPow - var maxBlockTime = 10; - if('maxBlockTime' in options) { - maxBlockTime = options.maxBlockTime; - } - var start = +new Date(); - do { - // overflow, regenerate random number - if(num.bitLength() > bits) { - num = generateRandom(bits, rng); - } - // do primality test - if(num.isProbablePrime(mrTests)) { - return callback(null, num); - } - // get next potential prime - num.dAddOffset(GCD_30_DELTA[deltaIdx++ % 8], 0); - } while(maxBlockTime < 0 || (+new Date() - start < maxBlockTime)); - - // keep trying (setImmediate would be better here) - forge.util.setImmediate(function() { - primeincFindPrimeWithoutWorkers(bits, rng, options, callback); - }); -} - -function primeincFindPrimeWithWorkers(bits, rng, options, callback) { - // web workers unavailable - if(typeof Worker === 'undefined') { - return primeincFindPrimeWithoutWorkers(bits, rng, options, callback); - } - - // initialize random number - var num = generateRandom(bits, rng); - - // use web workers to generate keys - var numWorkers = options.workers; - var workLoad = options.workLoad || 100; - var range = workLoad * 30 / 8; - var workerScript = options.workerScript || 'forge/prime.worker.js'; - if(numWorkers === -1) { - return forge.util.estimateCores(function(err, cores) { - if(err) { - // default to 2 - cores = 2; - } - numWorkers = cores - 1; - generate(); - }); - } - generate(); - - function generate() { - // require at least 1 worker - numWorkers = Math.max(1, numWorkers); - - // TODO: consider optimizing by starting workers outside getPrime() ... - // note that in order to clean up they will have to be made internally - // asynchronous which may actually be slower - - // start workers immediately - var workers = []; - for(var i = 0; i < numWorkers; ++i) { - // FIXME: fix path or use blob URLs - workers[i] = new Worker(workerScript); - } - var running = numWorkers; - - // listen for requests from workers and assign ranges to find prime - for(var i = 0; i < numWorkers; ++i) { - workers[i].addEventListener('message', workerMessage); - } - - /* Note: The distribution of random numbers is unknown. Therefore, each - web worker is continuously allocated a range of numbers to check for a - random number until one is found. - - Every 30 numbers will be checked just 8 times, because prime numbers - have the form: - - 30k+i, for i < 30 and gcd(30, i)=1 (there are 8 values of i for this) - - Therefore, if we want a web worker to run N checks before asking for - a new range of numbers, each range must contain N*30/8 numbers. - - For 100 checks (workLoad), this is a range of 375. */ - - var found = false; - function workerMessage(e) { - // ignore message, prime already found - if(found) { - return; - } - - --running; - var data = e.data; - if(data.found) { - // terminate all workers - for(var i = 0; i < workers.length; ++i) { - workers[i].terminate(); - } - found = true; - return callback(null, new BigInteger(data.prime, 16)); - } - - // overflow, regenerate random number - if(num.bitLength() > bits) { - num = generateRandom(bits, rng); - } - - // assign new range to check - var hex = num.toString(16); - - // start prime search - e.target.postMessage({ - hex: hex, - workLoad: workLoad - }); - - num.dAddOffset(range, 0); - } - } -} - -/** - * Generates a random number using the given number of bits and RNG. - * - * @param bits the number of bits for the number. - * @param rng the random number generator to use. - * - * @return the random number. - */ -function generateRandom(bits, rng) { - var num = new BigInteger(bits, rng); - // force MSB set - var bits1 = bits - 1; - if(!num.testBit(bits1)) { - num.bitwiseTo(BigInteger.ONE.shiftLeft(bits1), op_or, num); - } - // align number on 30k+1 boundary - num.dAddOffset(31 - num.mod(THIRTY).byteValue(), 0); - return num; -} - -/** - * Returns the required number of Miller-Rabin tests to generate a - * prime with an error probability of (1/2)^80. - * - * See Handbook of Applied Cryptography Chapter 4, Table 4.4. - * - * @param bits the bit size. - * - * @return the required number of iterations. - */ -function getMillerRabinTests(bits) { - if(bits <= 100) return 27; - if(bits <= 150) return 18; - if(bits <= 200) return 15; - if(bits <= 250) return 12; - if(bits <= 300) return 9; - if(bits <= 350) return 8; - if(bits <= 400) return 7; - if(bits <= 500) return 6; - if(bits <= 600) return 5; - if(bits <= 800) return 4; - if(bits <= 1250) return 3; - return 2; -} - -} // end module implementation - -/* ########## Begin module wrapper ########## */ -var name = 'prime'; -if(typeof define !== 'function') { - // NodeJS -> AMD - if(typeof module === 'object' && module.exports) { - var nodeJS = true; - define = function(ids, factory) { - factory(require, module); - }; - } else { - // <script> - if(typeof forge === 'undefined') { - forge = {}; - } - return initModule(forge); - } -} -// AMD -var deps; -var defineFunc = function(require, module) { - module.exports = function(forge) { - var mods = deps.map(function(dep) { - return require(dep); - }).concat(initModule); - // handle circular dependencies - forge = forge || {}; - forge.defined = forge.defined || {}; - if(forge.defined[name]) { - return forge[name]; - } - forge.defined[name] = true; - for(var i = 0; i < mods.length; ++i) { - mods[i](forge); - } - return forge[name]; - }; -}; -var tmpDefine = define; -define = function(ids, factory) { - deps = (typeof ids === 'string') ? factory.slice(2) : ids.slice(2); - if(nodeJS) { - delete define; - return tmpDefine.apply(null, Array.prototype.slice.call(arguments, 0)); - } - define = tmpDefine; - return define.apply(null, Array.prototype.slice.call(arguments, 0)); -}; -define(['require', 'module', './util', './jsbn', './random'], function() { - defineFunc.apply(null, Array.prototype.slice.call(arguments, 0)); -}); - -})(); diff --git a/alarm/node_modules/node-forge/js/prime.worker.js b/alarm/node_modules/node-forge/js/prime.worker.js deleted file mode 100644 index 5fdaa7f..0000000 --- a/alarm/node_modules/node-forge/js/prime.worker.js +++ /dev/null @@ -1,165 +0,0 @@ -/** - * RSA Key Generation Worker. - * - * @author Dave Longley - * - * Copyright (c) 2013 Digital Bazaar, Inc. - */ -importScripts('jsbn.js'); - -// prime constants -var LOW_PRIMES = [2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293,307,311,313,317,331,337,347,349,353,359,367,373,379,383,389,397,401,409,419,421,431,433,439,443,449,457,461,463,467,479,487,491,499,503,509,521,523,541,547,557,563,569,571,577,587,593,599,601,607,613,617,619,631,641,643,647,653,659,661,673,677,683,691,701,709,719,727,733,739,743,751,757,761,769,773,787,797,809,811,821,823,827,829,839,853,857,859,863,877,881,883,887,907,911,919,929,937,941,947,953,967,971,977,983,991,997]; -var LP_LIMIT = (1 << 26) / LOW_PRIMES[LOW_PRIMES.length - 1]; - -var BigInteger = forge.jsbn.BigInteger; -var BIG_TWO = new BigInteger(null); -BIG_TWO.fromInt(2); - -self.addEventListener('message', function(e) { - var result = findPrime(e.data); - self.postMessage(result); -}); - -// start receiving ranges to check -self.postMessage({found: false}); - -// primes are 30k+i for i = 1, 7, 11, 13, 17, 19, 23, 29 -var GCD_30_DELTA = [6, 4, 2, 4, 2, 4, 6, 2]; - -function findPrime(data) { - // TODO: abstract based on data.algorithm (PRIMEINC vs. others) - - // create BigInteger from given random bytes - var num = new BigInteger(data.hex, 16); - - /* Note: All primes are of the form 30k+i for i < 30 and gcd(30, i)=1. The - number we are given is always aligned at 30k + 1. Each time the number is - determined not to be prime we add to get to the next 'i', eg: if the number - was at 30k + 1 we add 6. */ - var deltaIdx = 0; - - // find nearest prime - var workLoad = data.workLoad; - for(var i = 0; i < workLoad; ++i) { - // do primality test - if(isProbablePrime(num)) { - return {found: true, prime: num.toString(16)}; - } - // get next potential prime - num.dAddOffset(GCD_30_DELTA[deltaIdx++ % 8], 0); - } - - return {found: false}; -} - -function isProbablePrime(n) { - // divide by low primes, ignore even checks, etc (n alread aligned properly) - var i = 1; - while(i < LOW_PRIMES.length) { - var m = LOW_PRIMES[i]; - var j = i + 1; - while(j < LOW_PRIMES.length && m < LP_LIMIT) { - m *= LOW_PRIMES[j++]; - } - m = n.modInt(m); - while(i < j) { - if(m % LOW_PRIMES[i++] === 0) { - return false; - } - } - } - return runMillerRabin(n); -} - -// HAC 4.24, Miller-Rabin -function runMillerRabin(n) { - // n1 = n - 1 - var n1 = n.subtract(BigInteger.ONE); - - // get s and d such that n1 = 2^s * d - var s = n1.getLowestSetBit(); - if(s <= 0) { - return false; - } - var d = n1.shiftRight(s); - - var k = _getMillerRabinTests(n.bitLength()); - var prng = getPrng(); - var a; - for(var i = 0; i < k; ++i) { - // select witness 'a' at random from between 1 and n - 1 - do { - a = new BigInteger(n.bitLength(), prng); - } while(a.compareTo(BigInteger.ONE) <= 0 || a.compareTo(n1) >= 0); - - /* See if 'a' is a composite witness. */ - - // x = a^d mod n - var x = a.modPow(d, n); - - // probably prime - if(x.compareTo(BigInteger.ONE) === 0 || x.compareTo(n1) === 0) { - continue; - } - - var j = s; - while(--j) { - // x = x^2 mod a - x = x.modPowInt(2, n); - - // 'n' is composite because no previous x == -1 mod n - if(x.compareTo(BigInteger.ONE) === 0) { - return false; - } - // x == -1 mod n, so probably prime - if(x.compareTo(n1) === 0) { - break; - } - } - - // 'x' is first_x^(n1/2) and is not +/- 1, so 'n' is not prime - if(j === 0) { - return false; - } - } - - return true; -} - -// get pseudo random number generator -function getPrng() { - // create prng with api that matches BigInteger secure random - return { - // x is an array to fill with bytes - nextBytes: function(x) { - for(var i = 0; i < x.length; ++i) { - x[i] = Math.floor(Math.random() * 0xFF); - } - } - }; -} - -/** - * Returns the required number of Miller-Rabin tests to generate a - * prime with an error probability of (1/2)^80. - * - * See Handbook of Applied Cryptography Chapter 4, Table 4.4. - * - * @param bits the bit size. - * - * @return the required number of iterations. - */ -function _getMillerRabinTests(bits) { - if(bits <= 100) return 27; - if(bits <= 150) return 18; - if(bits <= 200) return 15; - if(bits <= 250) return 12; - if(bits <= 300) return 9; - if(bits <= 350) return 8; - if(bits <= 400) return 7; - if(bits <= 500) return 6; - if(bits <= 600) return 5; - if(bits <= 800) return 4; - if(bits <= 1250) return 3; - return 2; -} diff --git a/alarm/node_modules/node-forge/js/prng.js b/alarm/node_modules/node-forge/js/prng.js deleted file mode 100644 index 72b4594..0000000 --- a/alarm/node_modules/node-forge/js/prng.js +++ /dev/null @@ -1,458 +0,0 @@ -/** - * A javascript implementation of a cryptographically-secure - * Pseudo Random Number Generator (PRNG). The Fortuna algorithm is followed - * here though the use of SHA-256 is not enforced; when generating an - * a PRNG context, the hashing algorithm and block cipher used for - * the generator are specified via a plugin. - * - * @author Dave Longley - * - * Copyright (c) 2010-2014 Digital Bazaar, Inc. - */ -(function() { -/* ########## Begin module implementation ########## */ -function initModule(forge) { - -var _nodejs = ( - typeof process !== 'undefined' && process.versions && process.versions.node); -var _crypto = null; -if(!forge.disableNativeCode && _nodejs && !process.versions['node-webkit']) { - _crypto = require('crypto'); -} - -/* PRNG API */ -var prng = forge.prng = forge.prng || {}; - -/** - * Creates a new PRNG context. - * - * A PRNG plugin must be passed in that will provide: - * - * 1. A function that initializes the key and seed of a PRNG context. It - * will be given a 16 byte key and a 16 byte seed. Any key expansion - * or transformation of the seed from a byte string into an array of - * integers (or similar) should be performed. - * 2. The cryptographic function used by the generator. It takes a key and - * a seed. - * 3. A seed increment function. It takes the seed and returns seed + 1. - * 4. An api to create a message digest. - * - * For an example, see random.js. - * - * @param plugin the PRNG plugin to use. - */ -prng.create = function(plugin) { - var ctx = { - plugin: plugin, - key: null, - seed: null, - time: null, - // number of reseeds so far - reseeds: 0, - // amount of data generated so far - generated: 0 - }; - - // create 32 entropy pools (each is a message digest) - var md = plugin.md; - var pools = new Array(32); - for(var i = 0; i < 32; ++i) { - pools[i] = md.create(); - } - ctx.pools = pools; - - // entropy pools are written to cyclically, starting at index 0 - ctx.pool = 0; - - /** - * Generates random bytes. The bytes may be generated synchronously or - * asynchronously. Web workers must use the asynchronous interface or - * else the behavior is undefined. - * - * @param count the number of random bytes to generate. - * @param [callback(err, bytes)] called once the operation completes. - * - * @return count random bytes as a string. - */ - ctx.generate = function(count, callback) { - // do synchronously - if(!callback) { - return ctx.generateSync(count); - } - - // simple generator using counter-based CBC - var cipher = ctx.plugin.cipher; - var increment = ctx.plugin.increment; - var formatKey = ctx.plugin.formatKey; - var formatSeed = ctx.plugin.formatSeed; - var b = forge.util.createBuffer(); - - // reset key for every request - ctx.key = null; - - generate(); - - function generate(err) { - if(err) { - return callback(err); - } - - // sufficient bytes generated - if(b.length() >= count) { - return callback(null, b.getBytes(count)); - } - - // if amount of data generated is greater than 1 MiB, trigger reseed - if(ctx.generated > 0xfffff) { - ctx.key = null; - } - - if(ctx.key === null) { - // prevent stack overflow - return forge.util.nextTick(function() { - _reseed(generate); - }); - } - - // generate the random bytes - var bytes = cipher(ctx.key, ctx.seed); - ctx.generated += bytes.length; - b.putBytes(bytes); - - // generate bytes for a new key and seed - ctx.key = formatKey(cipher(ctx.key, increment(ctx.seed))); - ctx.seed = formatSeed(cipher(ctx.key, ctx.seed)); - - forge.util.setImmediate(generate); - } - }; - - /** - * Generates random bytes synchronously. - * - * @param count the number of random bytes to generate. - * - * @return count random bytes as a string. - */ - ctx.generateSync = function(count) { - // simple generator using counter-based CBC - var cipher = ctx.plugin.cipher; - var increment = ctx.plugin.increment; - var formatKey = ctx.plugin.formatKey; - var formatSeed = ctx.plugin.formatSeed; - - // reset key for every request - ctx.key = null; - - var b = forge.util.createBuffer(); - while(b.length() < count) { - // if amount of data generated is greater than 1 MiB, trigger reseed - if(ctx.generated > 0xfffff) { - ctx.key = null; - } - - if(ctx.key === null) { - _reseedSync(); - } - - // generate the random bytes - var bytes = cipher(ctx.key, ctx.seed); - ctx.generated += bytes.length; - b.putBytes(bytes); - - // generate bytes for a new key and seed - ctx.key = formatKey(cipher(ctx.key, increment(ctx.seed))); - ctx.seed = formatSeed(cipher(ctx.key, ctx.seed)); - } - - return b.getBytes(count); - }; - - /** - * Private function that asynchronously reseeds a generator. - * - * @param callback(err) called once the operation completes. - */ - function _reseed(callback) { - if(ctx.pools[0].messageLength >= 32) { - _seed(); - return callback(); - } - // not enough seed data... - var needed = (32 - ctx.pools[0].messageLength) << 5; - ctx.seedFile(needed, function(err, bytes) { - if(err) { - return callback(err); - } - ctx.collect(bytes); - _seed(); - callback(); - }); - } - - /** - * Private function that synchronously reseeds a generator. - */ - function _reseedSync() { - if(ctx.pools[0].messageLength >= 32) { - return _seed(); - } - // not enough seed data... - var needed = (32 - ctx.pools[0].messageLength) << 5; - ctx.collect(ctx.seedFileSync(needed)); - _seed(); - } - - /** - * Private function that seeds a generator once enough bytes are available. - */ - function _seed() { - // create a plugin-based message digest - var md = ctx.plugin.md.create(); - - // digest pool 0's entropy and restart it - md.update(ctx.pools[0].digest().getBytes()); - ctx.pools[0].start(); - - // digest the entropy of other pools whose index k meet the - // condition '2^k mod n == 0' where n is the number of reseeds - var k = 1; - for(var i = 1; i < 32; ++i) { - // prevent signed numbers from being used - k = (k === 31) ? 0x80000000 : (k << 2); - if(k % ctx.reseeds === 0) { - md.update(ctx.pools[i].digest().getBytes()); - ctx.pools[i].start(); - } - } - - // get digest for key bytes and iterate again for seed bytes - var keyBytes = md.digest().getBytes(); - md.start(); - md.update(keyBytes); - var seedBytes = md.digest().getBytes(); - - // update - ctx.key = ctx.plugin.formatKey(keyBytes); - ctx.seed = ctx.plugin.formatSeed(seedBytes); - ctx.reseeds = (ctx.reseeds === 0xffffffff) ? 0 : ctx.reseeds + 1; - ctx.generated = 0; - } - - /** - * The built-in default seedFile. This seedFile is used when entropy - * is needed immediately. - * - * @param needed the number of bytes that are needed. - * - * @return the random bytes. - */ - function defaultSeedFile(needed) { - // use window.crypto.getRandomValues strong source of entropy if available - var getRandomValues = null; - if(typeof window !== 'undefined') { - var _crypto = window.crypto || window.msCrypto; - if(_crypto && _crypto.getRandomValues) { - getRandomValues = function(arr) { - return _crypto.getRandomValues(arr); - }; - } - } - - var b = forge.util.createBuffer(); - if(getRandomValues) { - while(b.length() < needed) { - // max byte length is 65536 before QuotaExceededError is thrown - // http://www.w3.org/TR/WebCryptoAPI/#RandomSource-method-getRandomValues - var count = Math.max(1, Math.min(needed - b.length(), 65536) / 4); - var entropy = new Uint32Array(Math.floor(count)); - try { - getRandomValues(entropy); - for(var i = 0; i < entropy.length; ++i) { - b.putInt32(entropy[i]); - } - } catch(e) { - /* only ignore QuotaExceededError */ - if(!(typeof QuotaExceededError !== 'undefined' && - e instanceof QuotaExceededError)) { - throw e; - } - } - } - } - - // be sad and add some weak random data - if(b.length() < needed) { - /* Draws from Park-Miller "minimal standard" 31 bit PRNG, - implemented with David G. Carta's optimization: with 32 bit math - and without division (Public Domain). */ - var hi, lo, next; - var seed = Math.floor(Math.random() * 0x010000); - while(b.length() < needed) { - lo = 16807 * (seed & 0xFFFF); - hi = 16807 * (seed >> 16); - lo += (hi & 0x7FFF) << 16; - lo += hi >> 15; - lo = (lo & 0x7FFFFFFF) + (lo >> 31); - seed = lo & 0xFFFFFFFF; - - // consume lower 3 bytes of seed - for(var i = 0; i < 3; ++i) { - // throw in more pseudo random - next = seed >>> (i << 3); - next ^= Math.floor(Math.random() * 0x0100); - b.putByte(String.fromCharCode(next & 0xFF)); - } - } - } - - return b.getBytes(needed); - } - // initialize seed file APIs - if(_crypto) { - // use nodejs async API - ctx.seedFile = function(needed, callback) { - _crypto.randomBytes(needed, function(err, bytes) { - if(err) { - return callback(err); - } - callback(null, bytes.toString()); - }); - }; - // use nodejs sync API - ctx.seedFileSync = function(needed) { - return _crypto.randomBytes(needed).toString(); - }; - } else { - ctx.seedFile = function(needed, callback) { - try { - callback(null, defaultSeedFile(needed)); - } catch(e) { - callback(e); - } - }; - ctx.seedFileSync = defaultSeedFile; - } - - /** - * Adds entropy to a prng ctx's accumulator. - * - * @param bytes the bytes of entropy as a string. - */ - ctx.collect = function(bytes) { - // iterate over pools distributing entropy cyclically - var count = bytes.length; - for(var i = 0; i < count; ++i) { - ctx.pools[ctx.pool].update(bytes.substr(i, 1)); - ctx.pool = (ctx.pool === 31) ? 0 : ctx.pool + 1; - } - }; - - /** - * Collects an integer of n bits. - * - * @param i the integer entropy. - * @param n the number of bits in the integer. - */ - ctx.collectInt = function(i, n) { - var bytes = ''; - for(var x = 0; x < n; x += 8) { - bytes += String.fromCharCode((i >> x) & 0xFF); - } - ctx.collect(bytes); - }; - - /** - * Registers a Web Worker to receive immediate entropy from the main thread. - * This method is required until Web Workers can access the native crypto - * API. This method should be called twice for each created worker, once in - * the main thread, and once in the worker itself. - * - * @param worker the worker to register. - */ - ctx.registerWorker = function(worker) { - // worker receives random bytes - if(worker === self) { - ctx.seedFile = function(needed, callback) { - function listener(e) { - var data = e.data; - if(data.forge && data.forge.prng) { - self.removeEventListener('message', listener); - callback(data.forge.prng.err, data.forge.prng.bytes); - } - } - self.addEventListener('message', listener); - self.postMessage({forge: {prng: {needed: needed}}}); - }; - } else { - // main thread sends random bytes upon request - var listener = function(e) { - var data = e.data; - if(data.forge && data.forge.prng) { - ctx.seedFile(data.forge.prng.needed, function(err, bytes) { - worker.postMessage({forge: {prng: {err: err, bytes: bytes}}}); - }); - } - }; - // TODO: do we need to remove the event listener when the worker dies? - worker.addEventListener('message', listener); - } - }; - - return ctx; -}; - -} // end module implementation - -/* ########## Begin module wrapper ########## */ -var name = 'prng'; -if(typeof define !== 'function') { - // NodeJS -> AMD - if(typeof module === 'object' && module.exports) { - var nodeJS = true; - define = function(ids, factory) { - factory(require, module); - }; - } else { - // <script> - if(typeof forge === 'undefined') { - forge = {}; - } - return initModule(forge); - } -} -// AMD -var deps; -var defineFunc = function(require, module) { - module.exports = function(forge) { - var mods = deps.map(function(dep) { - return require(dep); - }).concat(initModule); - // handle circular dependencies - forge = forge || {}; - forge.defined = forge.defined || {}; - if(forge.defined[name]) { - return forge[name]; - } - forge.defined[name] = true; - for(var i = 0; i < mods.length; ++i) { - mods[i](forge); - } - return forge[name]; - }; -}; -var tmpDefine = define; -define = function(ids, factory) { - deps = (typeof ids === 'string') ? factory.slice(2) : ids.slice(2); - if(nodeJS) { - delete define; - return tmpDefine.apply(null, Array.prototype.slice.call(arguments, 0)); - } - define = tmpDefine; - return define.apply(null, Array.prototype.slice.call(arguments, 0)); -}; -define(['require', 'module', './md', './util'], function() { - defineFunc.apply(null, Array.prototype.slice.call(arguments, 0)); -}); - -})(); diff --git a/alarm/node_modules/node-forge/js/pss.js b/alarm/node_modules/node-forge/js/pss.js deleted file mode 100644 index 1b284fc..0000000 --- a/alarm/node_modules/node-forge/js/pss.js +++ /dev/null @@ -1,295 +0,0 @@ -/** - * Javascript implementation of PKCS#1 PSS signature padding. - * - * @author Stefan Siegl - * - * Copyright (c) 2012 Stefan Siegl <stesie@brokenpipe.de> - */ -(function() { -/* ########## Begin module implementation ########## */ -function initModule(forge) { - -// shortcut for PSS API -var pss = forge.pss = forge.pss || {}; - -/** - * Creates a PSS signature scheme object. - * - * There are several ways to provide a salt for encoding: - * - * 1. Specify the saltLength only and the built-in PRNG will generate it. - * 2. Specify the saltLength and a custom PRNG with 'getBytesSync' defined that - * will be used. - * 3. Specify the salt itself as a forge.util.ByteBuffer. - * - * @param options the options to use: - * md the message digest object to use, a forge md instance. - * mgf the mask generation function to use, a forge mgf instance. - * [saltLength] the length of the salt in octets. - * [prng] the pseudo-random number generator to use to produce a salt. - * [salt] the salt to use when encoding. - * - * @return a signature scheme object. - */ -pss.create = function(options) { - // backwards compatibility w/legacy args: hash, mgf, sLen - if(arguments.length === 3) { - options = { - md: arguments[0], - mgf: arguments[1], - saltLength: arguments[2] - }; - } - - var hash = options.md; - var mgf = options.mgf; - var hLen = hash.digestLength; - - var salt_ = options.salt || null; - if(typeof salt_ === 'string') { - // assume binary-encoded string - salt_ = forge.util.createBuffer(salt_); - } - - var sLen; - if('saltLength' in options) { - sLen = options.saltLength; - } else if(salt_ !== null) { - sLen = salt_.length(); - } else { - throw new Error('Salt length not specified or specific salt not given.'); - } - - if(salt_ !== null && salt_.length() !== sLen) { - throw new Error('Given salt length does not match length of given salt.'); - } - - var prng = options.prng || forge.random; - - var pssobj = {}; - - /** - * Encodes a PSS signature. - * - * This function implements EMSA-PSS-ENCODE as per RFC 3447, section 9.1.1. - * - * @param md the message digest object with the hash to sign. - * @param modsBits the length of the RSA modulus in bits. - * - * @return the encoded message as a binary-encoded string of length - * ceil((modBits - 1) / 8). - */ - pssobj.encode = function(md, modBits) { - var i; - var emBits = modBits - 1; - var emLen = Math.ceil(emBits / 8); - - /* 2. Let mHash = Hash(M), an octet string of length hLen. */ - var mHash = md.digest().getBytes(); - - /* 3. If emLen < hLen + sLen + 2, output "encoding error" and stop. */ - if(emLen < hLen + sLen + 2) { - throw new Error('Message is too long to encrypt.'); - } - - /* 4. Generate a random octet string salt of length sLen; if sLen = 0, - * then salt is the empty string. */ - var salt; - if(salt_ === null) { - salt = prng.getBytesSync(sLen); - } else { - salt = salt_.bytes(); - } - - /* 5. Let M' = (0x)00 00 00 00 00 00 00 00 || mHash || salt; */ - var m_ = new forge.util.ByteBuffer(); - m_.fillWithByte(0, 8); - m_.putBytes(mHash); - m_.putBytes(salt); - - /* 6. Let H = Hash(M'), an octet string of length hLen. */ - hash.start(); - hash.update(m_.getBytes()); - var h = hash.digest().getBytes(); - - /* 7. Generate an octet string PS consisting of emLen - sLen - hLen - 2 - * zero octets. The length of PS may be 0. */ - var ps = new forge.util.ByteBuffer(); - ps.fillWithByte(0, emLen - sLen - hLen - 2); - - /* 8. Let DB = PS || 0x01 || salt; DB is an octet string of length - * emLen - hLen - 1. */ - ps.putByte(0x01); - ps.putBytes(salt); - var db = ps.getBytes(); - - /* 9. Let dbMask = MGF(H, emLen - hLen - 1). */ - var maskLen = emLen - hLen - 1; - var dbMask = mgf.generate(h, maskLen); - - /* 10. Let maskedDB = DB \xor dbMask. */ - var maskedDB = ''; - for(i = 0; i < maskLen; i ++) { - maskedDB += String.fromCharCode(db.charCodeAt(i) ^ dbMask.charCodeAt(i)); - } - - /* 11. Set the leftmost 8emLen - emBits bits of the leftmost octet in - * maskedDB to zero. */ - var mask = (0xFF00 >> (8 * emLen - emBits)) & 0xFF; - maskedDB = String.fromCharCode(maskedDB.charCodeAt(0) & ~mask) + - maskedDB.substr(1); - - /* 12. Let EM = maskedDB || H || 0xbc. - * 13. Output EM. */ - return maskedDB + h + String.fromCharCode(0xbc); - }; - - /** - * Verifies a PSS signature. - * - * This function implements EMSA-PSS-VERIFY as per RFC 3447, section 9.1.2. - * - * @param mHash the message digest hash, as a binary-encoded string, to - * compare against the signature. - * @param em the encoded message, as a binary-encoded string - * (RSA decryption result). - * @param modsBits the length of the RSA modulus in bits. - * - * @return true if the signature was verified, false if not. - */ - pssobj.verify = function(mHash, em, modBits) { - var i; - var emBits = modBits - 1; - var emLen = Math.ceil(emBits / 8); - - /* c. Convert the message representative m to an encoded message EM - * of length emLen = ceil((modBits - 1) / 8) octets, where modBits - * is the length in bits of the RSA modulus n */ - em = em.substr(-emLen); - - /* 3. If emLen < hLen + sLen + 2, output "inconsistent" and stop. */ - if(emLen < hLen + sLen + 2) { - throw new Error('Inconsistent parameters to PSS signature verification.'); - } - - /* 4. If the rightmost octet of EM does not have hexadecimal value - * 0xbc, output "inconsistent" and stop. */ - if(em.charCodeAt(emLen - 1) !== 0xbc) { - throw new Error('Encoded message does not end in 0xBC.'); - } - - /* 5. Let maskedDB be the leftmost emLen - hLen - 1 octets of EM, and - * let H be the next hLen octets. */ - var maskLen = emLen - hLen - 1; - var maskedDB = em.substr(0, maskLen); - var h = em.substr(maskLen, hLen); - - /* 6. If the leftmost 8emLen - emBits bits of the leftmost octet in - * maskedDB are not all equal to zero, output "inconsistent" and stop. */ - var mask = (0xFF00 >> (8 * emLen - emBits)) & 0xFF; - if((maskedDB.charCodeAt(0) & mask) !== 0) { - throw new Error('Bits beyond keysize not zero as expected.'); - } - - /* 7. Let dbMask = MGF(H, emLen - hLen - 1). */ - var dbMask = mgf.generate(h, maskLen); - - /* 8. Let DB = maskedDB \xor dbMask. */ - var db = ''; - for(i = 0; i < maskLen; i ++) { - db += String.fromCharCode(maskedDB.charCodeAt(i) ^ dbMask.charCodeAt(i)); - } - - /* 9. Set the leftmost 8emLen - emBits bits of the leftmost octet - * in DB to zero. */ - db = String.fromCharCode(db.charCodeAt(0) & ~mask) + db.substr(1); - - /* 10. If the emLen - hLen - sLen - 2 leftmost octets of DB are not zero - * or if the octet at position emLen - hLen - sLen - 1 (the leftmost - * position is "position 1") does not have hexadecimal value 0x01, - * output "inconsistent" and stop. */ - var checkLen = emLen - hLen - sLen - 2; - for(i = 0; i < checkLen; i ++) { - if(db.charCodeAt(i) !== 0x00) { - throw new Error('Leftmost octets not zero as expected'); - } - } - - if(db.charCodeAt(checkLen) !== 0x01) { - throw new Error('Inconsistent PSS signature, 0x01 marker not found'); - } - - /* 11. Let salt be the last sLen octets of DB. */ - var salt = db.substr(-sLen); - - /* 12. Let M' = (0x)00 00 00 00 00 00 00 00 || mHash || salt */ - var m_ = new forge.util.ByteBuffer(); - m_.fillWithByte(0, 8); - m_.putBytes(mHash); - m_.putBytes(salt); - - /* 13. Let H' = Hash(M'), an octet string of length hLen. */ - hash.start(); - hash.update(m_.getBytes()); - var h_ = hash.digest().getBytes(); - - /* 14. If H = H', output "consistent." Otherwise, output "inconsistent." */ - return h === h_; - }; - - return pssobj; -}; - -} // end module implementation - -/* ########## Begin module wrapper ########## */ -var name = 'pss'; -if(typeof define !== 'function') { - // NodeJS -> AMD - if(typeof module === 'object' && module.exports) { - var nodeJS = true; - define = function(ids, factory) { - factory(require, module); - }; - } else { - // <script> - if(typeof forge === 'undefined') { - forge = {}; - } - return initModule(forge); - } -} -// AMD -var deps; -var defineFunc = function(require, module) { - module.exports = function(forge) { - var mods = deps.map(function(dep) { - return require(dep); - }).concat(initModule); - // handle circular dependencies - forge = forge || {}; - forge.defined = forge.defined || {}; - if(forge.defined[name]) { - return forge[name]; - } - forge.defined[name] = true; - for(var i = 0; i < mods.length; ++i) { - mods[i](forge); - } - return forge[name]; - }; -}; -var tmpDefine = define; -define = function(ids, factory) { - deps = (typeof ids === 'string') ? factory.slice(2) : ids.slice(2); - if(nodeJS) { - delete define; - return tmpDefine.apply(null, Array.prototype.slice.call(arguments, 0)); - } - define = tmpDefine; - return define.apply(null, Array.prototype.slice.call(arguments, 0)); -}; -define(['require', 'module', './random', './util'], function() { - defineFunc.apply(null, Array.prototype.slice.call(arguments, 0)); -}); -})(); diff --git a/alarm/node_modules/node-forge/js/random.js b/alarm/node_modules/node-forge/js/random.js deleted file mode 100644 index febc1fd..0000000 --- a/alarm/node_modules/node-forge/js/random.js +++ /dev/null @@ -1,237 +0,0 @@ -/** - * An API for getting cryptographically-secure random bytes. The bytes are - * generated using the Fortuna algorithm devised by Bruce Schneier and - * Niels Ferguson. - * - * Getting strong random bytes is not yet easy to do in javascript. The only - * truish random entropy that can be collected is from the mouse, keyboard, or - * from timing with respect to page loads, etc. This generator makes a poor - * attempt at providing random bytes when those sources haven't yet provided - * enough entropy to initially seed or to reseed the PRNG. - * - * @author Dave Longley - * - * Copyright (c) 2009-2014 Digital Bazaar, Inc. - */ -(function() { -/* ########## Begin module implementation ########## */ -function initModule(forge) { - -// forge.random already defined -if(forge.random && forge.random.getBytes) { - return; -} - -(function(jQuery) { - -// the default prng plugin, uses AES-128 -var prng_aes = {}; -var _prng_aes_output = new Array(4); -var _prng_aes_buffer = forge.util.createBuffer(); -prng_aes.formatKey = function(key) { - // convert the key into 32-bit integers - var tmp = forge.util.createBuffer(key); - key = new Array(4); - key[0] = tmp.getInt32(); - key[1] = tmp.getInt32(); - key[2] = tmp.getInt32(); - key[3] = tmp.getInt32(); - - // return the expanded key - return forge.aes._expandKey(key, false); -}; -prng_aes.formatSeed = function(seed) { - // convert seed into 32-bit integers - var tmp = forge.util.createBuffer(seed); - seed = new Array(4); - seed[0] = tmp.getInt32(); - seed[1] = tmp.getInt32(); - seed[2] = tmp.getInt32(); - seed[3] = tmp.getInt32(); - return seed; -}; -prng_aes.cipher = function(key, seed) { - forge.aes._updateBlock(key, seed, _prng_aes_output, false); - _prng_aes_buffer.putInt32(_prng_aes_output[0]); - _prng_aes_buffer.putInt32(_prng_aes_output[1]); - _prng_aes_buffer.putInt32(_prng_aes_output[2]); - _prng_aes_buffer.putInt32(_prng_aes_output[3]); - return _prng_aes_buffer.getBytes(); -}; -prng_aes.increment = function(seed) { - // FIXME: do we care about carry or signed issues? - ++seed[3]; - return seed; -}; -prng_aes.md = forge.md.sha256; - -/** - * Creates a new PRNG. - */ -function spawnPrng() { - var ctx = forge.prng.create(prng_aes); - - /** - * Gets random bytes. If a native secure crypto API is unavailable, this - * method tries to make the bytes more unpredictable by drawing from data that - * can be collected from the user of the browser, eg: mouse movement. - * - * If a callback is given, this method will be called asynchronously. - * - * @param count the number of random bytes to get. - * @param [callback(err, bytes)] called once the operation completes. - * - * @return the random bytes in a string. - */ - ctx.getBytes = function(count, callback) { - return ctx.generate(count, callback); - }; - - /** - * Gets random bytes asynchronously. If a native secure crypto API is - * unavailable, this method tries to make the bytes more unpredictable by - * drawing from data that can be collected from the user of the browser, - * eg: mouse movement. - * - * @param count the number of random bytes to get. - * - * @return the random bytes in a string. - */ - ctx.getBytesSync = function(count) { - return ctx.generate(count); - }; - - return ctx; -} - -// create default prng context -var _ctx = spawnPrng(); - -// add other sources of entropy only if window.crypto.getRandomValues is not -// available -- otherwise this source will be automatically used by the prng -var _nodejs = ( - typeof process !== 'undefined' && process.versions && process.versions.node); -var getRandomValues = null; -if(typeof window !== 'undefined') { - var _crypto = window.crypto || window.msCrypto; - if(_crypto && _crypto.getRandomValues) { - getRandomValues = function(arr) { - return _crypto.getRandomValues(arr); - }; - } -} -if(forge.disableNativeCode || (!_nodejs && !getRandomValues)) { - // if this is a web worker, do not use weak entropy, instead register to - // receive strong entropy asynchronously from the main thread - if(typeof window === 'undefined' || window.document === undefined) { - // FIXME: - } - - // get load time entropy - _ctx.collectInt(+new Date(), 32); - - // add some entropy from navigator object - if(typeof(navigator) !== 'undefined') { - var _navBytes = ''; - for(var key in navigator) { - try { - if(typeof(navigator[key]) == 'string') { - _navBytes += navigator[key]; - } - } catch(e) { - /* Some navigator keys might not be accessible, e.g. the geolocation - attribute throws an exception if touched in Mozilla chrome:// - context. - - Silently ignore this and just don't use this as a source of - entropy. */ - } - } - _ctx.collect(_navBytes); - _navBytes = null; - } - - // add mouse and keyboard collectors if jquery is available - if(jQuery) { - // set up mouse entropy capture - jQuery().mousemove(function(e) { - // add mouse coords - _ctx.collectInt(e.clientX, 16); - _ctx.collectInt(e.clientY, 16); - }); - - // set up keyboard entropy capture - jQuery().keypress(function(e) { - _ctx.collectInt(e.charCode, 8); - }); - } -} - -/* Random API */ -if(!forge.random) { - forge.random = _ctx; -} else { - // extend forge.random with _ctx - for(var key in _ctx) { - forge.random[key] = _ctx[key]; - } -} - -// expose spawn PRNG -forge.random.createInstance = spawnPrng; - -})(typeof(jQuery) !== 'undefined' ? jQuery : null); - -} // end module implementation - -/* ########## Begin module wrapper ########## */ -var name = 'random'; -if(typeof define !== 'function') { - // NodeJS -> AMD - if(typeof module === 'object' && module.exports) { - var nodeJS = true; - define = function(ids, factory) { - factory(require, module); - }; - } else { - // <script> - if(typeof forge === 'undefined') { - forge = {}; - } - return initModule(forge); - } -} -// AMD -var deps; -var defineFunc = function(require, module) { - module.exports = function(forge) { - var mods = deps.map(function(dep) { - return require(dep); - }).concat(initModule); - // handle circular dependencies - forge = forge || {}; - forge.defined = forge.defined || {}; - if(forge.defined[name]) { - return forge[name]; - } - forge.defined[name] = true; - for(var i = 0; i < mods.length; ++i) { - mods[i](forge); - } - return forge[name]; - }; -}; -var tmpDefine = define; -define = function(ids, factory) { - deps = (typeof ids === 'string') ? factory.slice(2) : ids.slice(2); - if(nodeJS) { - delete define; - return tmpDefine.apply(null, Array.prototype.slice.call(arguments, 0)); - } - define = tmpDefine; - return define.apply(null, Array.prototype.slice.call(arguments, 0)); -}; -define(['require', 'module', './aes', './md', './prng', './util'], function() { - defineFunc.apply(null, Array.prototype.slice.call(arguments, 0)); -}); -})(); diff --git a/alarm/node_modules/node-forge/js/rc2.js b/alarm/node_modules/node-forge/js/rc2.js deleted file mode 100644 index 0a67011..0000000 --- a/alarm/node_modules/node-forge/js/rc2.js +++ /dev/null @@ -1,470 +0,0 @@ -/** - * RC2 implementation. - * - * @author Stefan Siegl - * - * Copyright (c) 2012 Stefan Siegl <stesie@brokenpipe.de> - * - * Information on the RC2 cipher is available from RFC #2268, - * http://www.ietf.org/rfc/rfc2268.txt - */ -(function() { -/* ########## Begin module implementation ########## */ -function initModule(forge) { - -var piTable = [ - 0xd9, 0x78, 0xf9, 0xc4, 0x19, 0xdd, 0xb5, 0xed, 0x28, 0xe9, 0xfd, 0x79, 0x4a, 0xa0, 0xd8, 0x9d, - 0xc6, 0x7e, 0x37, 0x83, 0x2b, 0x76, 0x53, 0x8e, 0x62, 0x4c, 0x64, 0x88, 0x44, 0x8b, 0xfb, 0xa2, - 0x17, 0x9a, 0x59, 0xf5, 0x87, 0xb3, 0x4f, 0x13, 0x61, 0x45, 0x6d, 0x8d, 0x09, 0x81, 0x7d, 0x32, - 0xbd, 0x8f, 0x40, 0xeb, 0x86, 0xb7, 0x7b, 0x0b, 0xf0, 0x95, 0x21, 0x22, 0x5c, 0x6b, 0x4e, 0x82, - 0x54, 0xd6, 0x65, 0x93, 0xce, 0x60, 0xb2, 0x1c, 0x73, 0x56, 0xc0, 0x14, 0xa7, 0x8c, 0xf1, 0xdc, - 0x12, 0x75, 0xca, 0x1f, 0x3b, 0xbe, 0xe4, 0xd1, 0x42, 0x3d, 0xd4, 0x30, 0xa3, 0x3c, 0xb6, 0x26, - 0x6f, 0xbf, 0x0e, 0xda, 0x46, 0x69, 0x07, 0x57, 0x27, 0xf2, 0x1d, 0x9b, 0xbc, 0x94, 0x43, 0x03, - 0xf8, 0x11, 0xc7, 0xf6, 0x90, 0xef, 0x3e, 0xe7, 0x06, 0xc3, 0xd5, 0x2f, 0xc8, 0x66, 0x1e, 0xd7, - 0x08, 0xe8, 0xea, 0xde, 0x80, 0x52, 0xee, 0xf7, 0x84, 0xaa, 0x72, 0xac, 0x35, 0x4d, 0x6a, 0x2a, - 0x96, 0x1a, 0xd2, 0x71, 0x5a, 0x15, 0x49, 0x74, 0x4b, 0x9f, 0xd0, 0x5e, 0x04, 0x18, 0xa4, 0xec, - 0xc2, 0xe0, 0x41, 0x6e, 0x0f, 0x51, 0xcb, 0xcc, 0x24, 0x91, 0xaf, 0x50, 0xa1, 0xf4, 0x70, 0x39, - 0x99, 0x7c, 0x3a, 0x85, 0x23, 0xb8, 0xb4, 0x7a, 0xfc, 0x02, 0x36, 0x5b, 0x25, 0x55, 0x97, 0x31, - 0x2d, 0x5d, 0xfa, 0x98, 0xe3, 0x8a, 0x92, 0xae, 0x05, 0xdf, 0x29, 0x10, 0x67, 0x6c, 0xba, 0xc9, - 0xd3, 0x00, 0xe6, 0xcf, 0xe1, 0x9e, 0xa8, 0x2c, 0x63, 0x16, 0x01, 0x3f, 0x58, 0xe2, 0x89, 0xa9, - 0x0d, 0x38, 0x34, 0x1b, 0xab, 0x33, 0xff, 0xb0, 0xbb, 0x48, 0x0c, 0x5f, 0xb9, 0xb1, 0xcd, 0x2e, - 0xc5, 0xf3, 0xdb, 0x47, 0xe5, 0xa5, 0x9c, 0x77, 0x0a, 0xa6, 0x20, 0x68, 0xfe, 0x7f, 0xc1, 0xad -]; - -var s = [1, 2, 3, 5]; - - -/** - * Rotate a word left by given number of bits. - * - * Bits that are shifted out on the left are put back in on the right - * hand side. - * - * @param word The word to shift left. - * @param bits The number of bits to shift by. - * @return The rotated word. - */ -var rol = function(word, bits) { - return ((word << bits) & 0xffff) | ((word & 0xffff) >> (16 - bits)); -}; - -/** - * Rotate a word right by given number of bits. - * - * Bits that are shifted out on the right are put back in on the left - * hand side. - * - * @param word The word to shift right. - * @param bits The number of bits to shift by. - * @return The rotated word. - */ -var ror = function(word, bits) { - return ((word & 0xffff) >> bits) | ((word << (16 - bits)) & 0xffff); -}; - - -/* RC2 API */ -forge.rc2 = forge.rc2 || {}; - -/** - * Perform RC2 key expansion as per RFC #2268, section 2. - * - * @param key variable-length user key (between 1 and 128 bytes) - * @param effKeyBits number of effective key bits (default: 128) - * @return the expanded RC2 key (ByteBuffer of 128 bytes) - */ -forge.rc2.expandKey = function(key, effKeyBits) { - if(typeof key === 'string') { - key = forge.util.createBuffer(key); - } - effKeyBits = effKeyBits || 128; - - /* introduce variables that match the names used in RFC #2268 */ - var L = key; - var T = key.length(); - var T1 = effKeyBits; - var T8 = Math.ceil(T1 / 8); - var TM = 0xff >> (T1 & 0x07); - var i; - - for(i = T; i < 128; i ++) { - L.putByte(piTable[(L.at(i - 1) + L.at(i - T)) & 0xff]); - } - - L.setAt(128 - T8, piTable[L.at(128 - T8) & TM]); - - for(i = 127 - T8; i >= 0; i --) { - L.setAt(i, piTable[L.at(i + 1) ^ L.at(i + T8)]); - } - - return L; -}; - - -/** - * Creates a RC2 cipher object. - * - * @param key the symmetric key to use (as base for key generation). - * @param bits the number of effective key bits. - * @param encrypt false for decryption, true for encryption. - * - * @return the cipher. - */ -var createCipher = function(key, bits, encrypt) { - var _finish = false, _input = null, _output = null, _iv = null; - var mixRound, mashRound; - var i, j, K = []; - - /* Expand key and fill into K[] Array */ - key = forge.rc2.expandKey(key, bits); - for(i = 0; i < 64; i ++) { - K.push(key.getInt16Le()); - } - - if(encrypt) { - /** - * Perform one mixing round "in place". - * - * @param R Array of four words to perform mixing on. - */ - mixRound = function(R) { - for(i = 0; i < 4; i++) { - R[i] += K[j] + (R[(i + 3) % 4] & R[(i + 2) % 4]) + - ((~R[(i + 3) % 4]) & R[(i + 1) % 4]); - R[i] = rol(R[i], s[i]); - j ++; - } - }; - - /** - * Perform one mashing round "in place". - * - * @param R Array of four words to perform mashing on. - */ - mashRound = function(R) { - for(i = 0; i < 4; i ++) { - R[i] += K[R[(i + 3) % 4] & 63]; - } - }; - } else { - /** - * Perform one r-mixing round "in place". - * - * @param R Array of four words to perform mixing on. - */ - mixRound = function(R) { - for(i = 3; i >= 0; i--) { - R[i] = ror(R[i], s[i]); - R[i] -= K[j] + (R[(i + 3) % 4] & R[(i + 2) % 4]) + - ((~R[(i + 3) % 4]) & R[(i + 1) % 4]); - j --; - } - }; - - /** - * Perform one r-mashing round "in place". - * - * @param R Array of four words to perform mashing on. - */ - mashRound = function(R) { - for(i = 3; i >= 0; i--) { - R[i] -= K[R[(i + 3) % 4] & 63]; - } - }; - } - - /** - * Run the specified cipher execution plan. - * - * This function takes four words from the input buffer, applies the IV on - * it (if requested) and runs the provided execution plan. - * - * The plan must be put together in form of a array of arrays. Where the - * outer one is simply a list of steps to perform and the inner one needs - * to have two elements: the first one telling how many rounds to perform, - * the second one telling what to do (i.e. the function to call). - * - * @param {Array} plan The plan to execute. - */ - var runPlan = function(plan) { - var R = []; - - /* Get data from input buffer and fill the four words into R */ - for(i = 0; i < 4; i ++) { - var val = _input.getInt16Le(); - - if(_iv !== null) { - if(encrypt) { - /* We're encrypting, apply the IV first. */ - val ^= _iv.getInt16Le(); - } else { - /* We're decryption, keep cipher text for next block. */ - _iv.putInt16Le(val); - } - } - - R.push(val & 0xffff); - } - - /* Reset global "j" variable as per spec. */ - j = encrypt ? 0 : 63; - - /* Run execution plan. */ - for(var ptr = 0; ptr < plan.length; ptr ++) { - for(var ctr = 0; ctr < plan[ptr][0]; ctr ++) { - plan[ptr][1](R); - } - } - - /* Write back result to output buffer. */ - for(i = 0; i < 4; i ++) { - if(_iv !== null) { - if(encrypt) { - /* We're encrypting in CBC-mode, feed back encrypted bytes into - IV buffer to carry it forward to next block. */ - _iv.putInt16Le(R[i]); - } else { - R[i] ^= _iv.getInt16Le(); - } - } - - _output.putInt16Le(R[i]); - } - }; - - - /* Create cipher object */ - var cipher = null; - cipher = { - /** - * Starts or restarts the encryption or decryption process, whichever - * was previously configured. - * - * To use the cipher in CBC mode, iv may be given either as a string - * of bytes, or as a byte buffer. For ECB mode, give null as iv. - * - * @param iv the initialization vector to use, null for ECB mode. - * @param output the output the buffer to write to, null to create one. - */ - start: function(iv, output) { - if(iv) { - /* CBC mode */ - if(typeof iv === 'string') { - iv = forge.util.createBuffer(iv); - } - } - - _finish = false; - _input = forge.util.createBuffer(); - _output = output || new forge.util.createBuffer(); - _iv = iv; - - cipher.output = _output; - }, - - /** - * Updates the next block. - * - * @param input the buffer to read from. - */ - update: function(input) { - if(!_finish) { - // not finishing, so fill the input buffer with more input - _input.putBuffer(input); - } - - while(_input.length() >= 8) { - runPlan([ - [ 5, mixRound ], - [ 1, mashRound ], - [ 6, mixRound ], - [ 1, mashRound ], - [ 5, mixRound ] - ]); - } - }, - - /** - * Finishes encrypting or decrypting. - * - * @param pad a padding function to use, null for PKCS#7 padding, - * signature(blockSize, buffer, decrypt). - * - * @return true if successful, false on error. - */ - finish: function(pad) { - var rval = true; - - if(encrypt) { - if(pad) { - rval = pad(8, _input, !encrypt); - } else { - // add PKCS#7 padding to block (each pad byte is the - // value of the number of pad bytes) - var padding = (_input.length() === 8) ? 8 : (8 - _input.length()); - _input.fillWithByte(padding, padding); - } - } - - if(rval) { - // do final update - _finish = true; - cipher.update(); - } - - if(!encrypt) { - // check for error: input data not a multiple of block size - rval = (_input.length() === 0); - if(rval) { - if(pad) { - rval = pad(8, _output, !encrypt); - } else { - // ensure padding byte count is valid - var len = _output.length(); - var count = _output.at(len - 1); - - if(count > len) { - rval = false; - } else { - // trim off padding bytes - _output.truncate(count); - } - } - } - } - - return rval; - } - }; - - return cipher; -}; - - -/** - * Creates an RC2 cipher object to encrypt data in ECB or CBC mode using the - * given symmetric key. The output will be stored in the 'output' member - * of the returned cipher. - * - * The key and iv may be given as a string of bytes or a byte buffer. - * The cipher is initialized to use 128 effective key bits. - * - * @param key the symmetric key to use. - * @param iv the initialization vector to use. - * @param output the buffer to write to, null to create one. - * - * @return the cipher. - */ -forge.rc2.startEncrypting = function(key, iv, output) { - var cipher = forge.rc2.createEncryptionCipher(key, 128); - cipher.start(iv, output); - return cipher; -}; - -/** - * Creates an RC2 cipher object to encrypt data in ECB or CBC mode using the - * given symmetric key. - * - * The key may be given as a string of bytes or a byte buffer. - * - * To start encrypting call start() on the cipher with an iv and optional - * output buffer. - * - * @param key the symmetric key to use. - * - * @return the cipher. - */ -forge.rc2.createEncryptionCipher = function(key, bits) { - return createCipher(key, bits, true); -}; - -/** - * Creates an RC2 cipher object to decrypt data in ECB or CBC mode using the - * given symmetric key. The output will be stored in the 'output' member - * of the returned cipher. - * - * The key and iv may be given as a string of bytes or a byte buffer. - * The cipher is initialized to use 128 effective key bits. - * - * @param key the symmetric key to use. - * @param iv the initialization vector to use. - * @param output the buffer to write to, null to create one. - * - * @return the cipher. - */ -forge.rc2.startDecrypting = function(key, iv, output) { - var cipher = forge.rc2.createDecryptionCipher(key, 128); - cipher.start(iv, output); - return cipher; -}; - -/** - * Creates an RC2 cipher object to decrypt data in ECB or CBC mode using the - * given symmetric key. - * - * The key may be given as a string of bytes or a byte buffer. - * - * To start decrypting call start() on the cipher with an iv and optional - * output buffer. - * - * @param key the symmetric key to use. - * - * @return the cipher. - */ -forge.rc2.createDecryptionCipher = function(key, bits) { - return createCipher(key, bits, false); -}; - -} // end module implementation - -/* ########## Begin module wrapper ########## */ -var name = 'rc2'; -if(typeof define !== 'function') { - // NodeJS -> AMD - if(typeof module === 'object' && module.exports) { - var nodeJS = true; - define = function(ids, factory) { - factory(require, module); - }; - } else { - // <script> - if(typeof forge === 'undefined') { - forge = {}; - } - return initModule(forge); - } -} -// AMD -var deps; -var defineFunc = function(require, module) { - module.exports = function(forge) { - var mods = deps.map(function(dep) { - return require(dep); - }).concat(initModule); - // handle circular dependencies - forge = forge || {}; - forge.defined = forge.defined || {}; - if(forge.defined[name]) { - return forge[name]; - } - forge.defined[name] = true; - for(var i = 0; i < mods.length; ++i) { - mods[i](forge); - } - return forge[name]; - }; -}; -var tmpDefine = define; -define = function(ids, factory) { - deps = (typeof ids === 'string') ? factory.slice(2) : ids.slice(2); - if(nodeJS) { - delete define; - return tmpDefine.apply(null, Array.prototype.slice.call(arguments, 0)); - } - define = tmpDefine; - return define.apply(null, Array.prototype.slice.call(arguments, 0)); -}; -define(['require', 'module', './util'], function() { - defineFunc.apply(null, Array.prototype.slice.call(arguments, 0)); -}); -})(); diff --git a/alarm/node_modules/node-forge/js/rsa.js b/alarm/node_modules/node-forge/js/rsa.js deleted file mode 100644 index 90f8c0a..0000000 --- a/alarm/node_modules/node-forge/js/rsa.js +++ /dev/null @@ -1,1712 +0,0 @@ -/** - * Javascript implementation of basic RSA algorithms. - * - * @author Dave Longley - * - * Copyright (c) 2010-2014 Digital Bazaar, Inc. - * - * The only algorithm currently supported for PKI is RSA. - * - * An RSA key is often stored in ASN.1 DER format. The SubjectPublicKeyInfo - * ASN.1 structure is composed of an algorithm of type AlgorithmIdentifier - * and a subjectPublicKey of type bit string. - * - * The AlgorithmIdentifier contains an Object Identifier (OID) and parameters - * for the algorithm, if any. In the case of RSA, there aren't any. - * - * SubjectPublicKeyInfo ::= SEQUENCE { - * algorithm AlgorithmIdentifier, - * subjectPublicKey BIT STRING - * } - * - * AlgorithmIdentifer ::= SEQUENCE { - * algorithm OBJECT IDENTIFIER, - * parameters ANY DEFINED BY algorithm OPTIONAL - * } - * - * For an RSA public key, the subjectPublicKey is: - * - * RSAPublicKey ::= SEQUENCE { - * modulus INTEGER, -- n - * publicExponent INTEGER -- e - * } - * - * PrivateKeyInfo ::= SEQUENCE { - * version Version, - * privateKeyAlgorithm PrivateKeyAlgorithmIdentifier, - * privateKey PrivateKey, - * attributes [0] IMPLICIT Attributes OPTIONAL - * } - * - * Version ::= INTEGER - * PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier - * PrivateKey ::= OCTET STRING - * Attributes ::= SET OF Attribute - * - * An RSA private key as the following structure: - * - * RSAPrivateKey ::= SEQUENCE { - * version Version, - * modulus INTEGER, -- n - * publicExponent INTEGER, -- e - * privateExponent INTEGER, -- d - * prime1 INTEGER, -- p - * prime2 INTEGER, -- q - * exponent1 INTEGER, -- d mod (p-1) - * exponent2 INTEGER, -- d mod (q-1) - * coefficient INTEGER -- (inverse of q) mod p - * } - * - * Version ::= INTEGER - * - * The OID for the RSA key algorithm is: 1.2.840.113549.1.1.1 - */ -(function() { -function initModule(forge) { -/* ########## Begin module implementation ########## */ - -if(typeof BigInteger === 'undefined') { - var BigInteger = forge.jsbn.BigInteger; -} - -// shortcut for asn.1 API -var asn1 = forge.asn1; - -/* - * RSA encryption and decryption, see RFC 2313. - */ -forge.pki = forge.pki || {}; -forge.pki.rsa = forge.rsa = forge.rsa || {}; -var pki = forge.pki; - -// for finding primes, which are 30k+i for i = 1, 7, 11, 13, 17, 19, 23, 29 -var GCD_30_DELTA = [6, 4, 2, 4, 2, 4, 6, 2]; - -// validator for a PrivateKeyInfo structure -var privateKeyValidator = { - // PrivateKeyInfo - name: 'PrivateKeyInfo', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.SEQUENCE, - constructed: true, - value: [{ - // Version (INTEGER) - name: 'PrivateKeyInfo.version', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.INTEGER, - constructed: false, - capture: 'privateKeyVersion' - }, { - // privateKeyAlgorithm - name: 'PrivateKeyInfo.privateKeyAlgorithm', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.SEQUENCE, - constructed: true, - value: [{ - name: 'AlgorithmIdentifier.algorithm', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.OID, - constructed: false, - capture: 'privateKeyOid' - }] - }, { - // PrivateKey - name: 'PrivateKeyInfo', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.OCTETSTRING, - constructed: false, - capture: 'privateKey' - }] -}; - -// validator for an RSA private key -var rsaPrivateKeyValidator = { - // RSAPrivateKey - name: 'RSAPrivateKey', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.SEQUENCE, - constructed: true, - value: [{ - // Version (INTEGER) - name: 'RSAPrivateKey.version', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.INTEGER, - constructed: false, - capture: 'privateKeyVersion' - }, { - // modulus (n) - name: 'RSAPrivateKey.modulus', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.INTEGER, - constructed: false, - capture: 'privateKeyModulus' - }, { - // publicExponent (e) - name: 'RSAPrivateKey.publicExponent', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.INTEGER, - constructed: false, - capture: 'privateKeyPublicExponent' - }, { - // privateExponent (d) - name: 'RSAPrivateKey.privateExponent', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.INTEGER, - constructed: false, - capture: 'privateKeyPrivateExponent' - }, { - // prime1 (p) - name: 'RSAPrivateKey.prime1', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.INTEGER, - constructed: false, - capture: 'privateKeyPrime1' - }, { - // prime2 (q) - name: 'RSAPrivateKey.prime2', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.INTEGER, - constructed: false, - capture: 'privateKeyPrime2' - }, { - // exponent1 (d mod (p-1)) - name: 'RSAPrivateKey.exponent1', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.INTEGER, - constructed: false, - capture: 'privateKeyExponent1' - }, { - // exponent2 (d mod (q-1)) - name: 'RSAPrivateKey.exponent2', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.INTEGER, - constructed: false, - capture: 'privateKeyExponent2' - }, { - // coefficient ((inverse of q) mod p) - name: 'RSAPrivateKey.coefficient', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.INTEGER, - constructed: false, - capture: 'privateKeyCoefficient' - }] -}; - -// validator for an RSA public key -var rsaPublicKeyValidator = { - // RSAPublicKey - name: 'RSAPublicKey', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.SEQUENCE, - constructed: true, - value: [{ - // modulus (n) - name: 'RSAPublicKey.modulus', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.INTEGER, - constructed: false, - capture: 'publicKeyModulus' - }, { - // publicExponent (e) - name: 'RSAPublicKey.exponent', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.INTEGER, - constructed: false, - capture: 'publicKeyExponent' - }] -}; - -// validator for an SubjectPublicKeyInfo structure -// Note: Currently only works with an RSA public key -var publicKeyValidator = forge.pki.rsa.publicKeyValidator = { - name: 'SubjectPublicKeyInfo', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.SEQUENCE, - constructed: true, - captureAsn1: 'subjectPublicKeyInfo', - value: [{ - name: 'SubjectPublicKeyInfo.AlgorithmIdentifier', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.SEQUENCE, - constructed: true, - value: [{ - name: 'AlgorithmIdentifier.algorithm', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.OID, - constructed: false, - capture: 'publicKeyOid' - }] - }, { - // subjectPublicKey - name: 'SubjectPublicKeyInfo.subjectPublicKey', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.BITSTRING, - constructed: false, - value: [{ - // RSAPublicKey - name: 'SubjectPublicKeyInfo.subjectPublicKey.RSAPublicKey', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.SEQUENCE, - constructed: true, - optional: true, - captureAsn1: 'rsaPublicKey' - }] - }] -}; - -/** - * Wrap digest in DigestInfo object. - * - * This function implements EMSA-PKCS1-v1_5-ENCODE as per RFC 3447. - * - * DigestInfo ::= SEQUENCE { - * digestAlgorithm DigestAlgorithmIdentifier, - * digest Digest - * } - * - * DigestAlgorithmIdentifier ::= AlgorithmIdentifier - * Digest ::= OCTET STRING - * - * @param md the message digest object with the hash to sign. - * - * @return the encoded message (ready for RSA encrytion) - */ -var emsaPkcs1v15encode = function(md) { - // get the oid for the algorithm - var oid; - if(md.algorithm in pki.oids) { - oid = pki.oids[md.algorithm]; - } else { - var error = new Error('Unknown message digest algorithm.'); - error.algorithm = md.algorithm; - throw error; - } - var oidBytes = asn1.oidToDer(oid).getBytes(); - - // create the digest info - var digestInfo = asn1.create( - asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, []); - var digestAlgorithm = asn1.create( - asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, []); - digestAlgorithm.value.push(asn1.create( - asn1.Class.UNIVERSAL, asn1.Type.OID, false, oidBytes)); - digestAlgorithm.value.push(asn1.create( - asn1.Class.UNIVERSAL, asn1.Type.NULL, false, '')); - var digest = asn1.create( - asn1.Class.UNIVERSAL, asn1.Type.OCTETSTRING, - false, md.digest().getBytes()); - digestInfo.value.push(digestAlgorithm); - digestInfo.value.push(digest); - - // encode digest info - return asn1.toDer(digestInfo).getBytes(); -}; - -/** - * Performs x^c mod n (RSA encryption or decryption operation). - * - * @param x the number to raise and mod. - * @param key the key to use. - * @param pub true if the key is public, false if private. - * - * @return the result of x^c mod n. - */ -var _modPow = function(x, key, pub) { - if(pub) { - return x.modPow(key.e, key.n); - } - - if(!key.p || !key.q) { - // allow calculation without CRT params (slow) - return x.modPow(key.d, key.n); - } - - // pre-compute dP, dQ, and qInv if necessary - if(!key.dP) { - key.dP = key.d.mod(key.p.subtract(BigInteger.ONE)); - } - if(!key.dQ) { - key.dQ = key.d.mod(key.q.subtract(BigInteger.ONE)); - } - if(!key.qInv) { - key.qInv = key.q.modInverse(key.p); - } - - /* Chinese remainder theorem (CRT) states: - - Suppose n1, n2, ..., nk are positive integers which are pairwise - coprime (n1 and n2 have no common factors other than 1). For any - integers x1, x2, ..., xk there exists an integer x solving the - system of simultaneous congruences (where ~= means modularly - congruent so a ~= b mod n means a mod n = b mod n): - - x ~= x1 mod n1 - x ~= x2 mod n2 - ... - x ~= xk mod nk - - This system of congruences has a single simultaneous solution x - between 0 and n - 1. Furthermore, each xk solution and x itself - is congruent modulo the product n = n1*n2*...*nk. - So x1 mod n = x2 mod n = xk mod n = x mod n. - - The single simultaneous solution x can be solved with the following - equation: - - x = sum(xi*ri*si) mod n where ri = n/ni and si = ri^-1 mod ni. - - Where x is less than n, xi = x mod ni. - - For RSA we are only concerned with k = 2. The modulus n = pq, where - p and q are coprime. The RSA decryption algorithm is: - - y = x^d mod n - - Given the above: - - x1 = x^d mod p - r1 = n/p = q - s1 = q^-1 mod p - x2 = x^d mod q - r2 = n/q = p - s2 = p^-1 mod q - - So y = (x1r1s1 + x2r2s2) mod n - = ((x^d mod p)q(q^-1 mod p) + (x^d mod q)p(p^-1 mod q)) mod n - - According to Fermat's Little Theorem, if the modulus P is prime, - for any integer A not evenly divisible by P, A^(P-1) ~= 1 mod P. - Since A is not divisible by P it follows that if: - N ~= M mod (P - 1), then A^N mod P = A^M mod P. Therefore: - - A^N mod P = A^(M mod (P - 1)) mod P. (The latter takes less effort - to calculate). In order to calculate x^d mod p more quickly the - exponent d mod (p - 1) is stored in the RSA private key (the same - is done for x^d mod q). These values are referred to as dP and dQ - respectively. Therefore we now have: - - y = ((x^dP mod p)q(q^-1 mod p) + (x^dQ mod q)p(p^-1 mod q)) mod n - - Since we'll be reducing x^dP by modulo p (same for q) we can also - reduce x by p (and q respectively) before hand. Therefore, let - - xp = ((x mod p)^dP mod p), and - xq = ((x mod q)^dQ mod q), yielding: - - y = (xp*q*(q^-1 mod p) + xq*p*(p^-1 mod q)) mod n - - This can be further reduced to a simple algorithm that only - requires 1 inverse (the q inverse is used) to be used and stored. - The algorithm is called Garner's algorithm. If qInv is the - inverse of q, we simply calculate: - - y = (qInv*(xp - xq) mod p) * q + xq - - However, there are two further complications. First, we need to - ensure that xp > xq to prevent signed BigIntegers from being used - so we add p until this is true (since we will be mod'ing with - p anyway). Then, there is a known timing attack on algorithms - using the CRT. To mitigate this risk, "cryptographic blinding" - should be used. This requires simply generating a random number r between - 0 and n-1 and its inverse and multiplying x by r^e before calculating y - and then multiplying y by r^-1 afterwards. - */ - - // cryptographic blinding - var r; - do { - r = new BigInteger( - forge.util.bytesToHex(forge.random.getBytes(key.n.bitLength() / 8)), - 16).mod(key.n); - } while(r.equals(BigInteger.ZERO)); - x = x.multiply(r.modPow(key.e, key.n)).mod(key.n); - - // calculate xp and xq - var xp = x.mod(key.p).modPow(key.dP, key.p); - var xq = x.mod(key.q).modPow(key.dQ, key.q); - - // xp must be larger than xq to avoid signed bit usage - while(xp.compareTo(xq) < 0) { - xp = xp.add(key.p); - } - - // do last step - var y = xp.subtract(xq) - .multiply(key.qInv).mod(key.p) - .multiply(key.q).add(xq); - - // remove effect of random for cryptographic blinding - y = y.multiply(r.modInverse(key.n)).mod(key.n); - - return y; -}; - -/** - * NOTE: THIS METHOD IS DEPRECATED, use 'sign' on a private key object or - * 'encrypt' on a public key object instead. - * - * Performs RSA encryption. - * - * The parameter bt controls whether to put padding bytes before the - * message passed in. Set bt to either true or false to disable padding - * completely (in order to handle e.g. EMSA-PSS encoding seperately before), - * signaling whether the encryption operation is a public key operation - * (i.e. encrypting data) or not, i.e. private key operation (data signing). - * - * For PKCS#1 v1.5 padding pass in the block type to use, i.e. either 0x01 - * (for signing) or 0x02 (for encryption). The key operation mode (private - * or public) is derived from this flag in that case). - * - * @param m the message to encrypt as a byte string. - * @param key the RSA key to use. - * @param bt for PKCS#1 v1.5 padding, the block type to use - * (0x01 for private key, 0x02 for public), - * to disable padding: true = public key, false = private key. - * - * @return the encrypted bytes as a string. - */ -pki.rsa.encrypt = function(m, key, bt) { - var pub = bt; - var eb; - - // get the length of the modulus in bytes - var k = Math.ceil(key.n.bitLength() / 8); - - if(bt !== false && bt !== true) { - // legacy, default to PKCS#1 v1.5 padding - pub = (bt === 0x02); - eb = _encodePkcs1_v1_5(m, key, bt); - } else { - eb = forge.util.createBuffer(); - eb.putBytes(m); - } - - // load encryption block as big integer 'x' - // FIXME: hex conversion inefficient, get BigInteger w/byte strings - var x = new BigInteger(eb.toHex(), 16); - - // do RSA encryption - var y = _modPow(x, key, pub); - - // convert y into the encrypted data byte string, if y is shorter in - // bytes than k, then prepend zero bytes to fill up ed - // FIXME: hex conversion inefficient, get BigInteger w/byte strings - var yhex = y.toString(16); - var ed = forge.util.createBuffer(); - var zeros = k - Math.ceil(yhex.length / 2); - while(zeros > 0) { - ed.putByte(0x00); - --zeros; - } - ed.putBytes(forge.util.hexToBytes(yhex)); - return ed.getBytes(); -}; - -/** - * NOTE: THIS METHOD IS DEPRECATED, use 'decrypt' on a private key object or - * 'verify' on a public key object instead. - * - * Performs RSA decryption. - * - * The parameter ml controls whether to apply PKCS#1 v1.5 padding - * or not. Set ml = false to disable padding removal completely - * (in order to handle e.g. EMSA-PSS later on) and simply pass back - * the RSA encryption block. - * - * @param ed the encrypted data to decrypt in as a byte string. - * @param key the RSA key to use. - * @param pub true for a public key operation, false for private. - * @param ml the message length, if known, false to disable padding. - * - * @return the decrypted message as a byte string. - */ -pki.rsa.decrypt = function(ed, key, pub, ml) { - // get the length of the modulus in bytes - var k = Math.ceil(key.n.bitLength() / 8); - - // error if the length of the encrypted data ED is not k - if(ed.length !== k) { - var error = new Error('Encrypted message length is invalid.'); - error.length = ed.length; - error.expected = k; - throw error; - } - - // convert encrypted data into a big integer - // FIXME: hex conversion inefficient, get BigInteger w/byte strings - var y = new BigInteger(forge.util.createBuffer(ed).toHex(), 16); - - // y must be less than the modulus or it wasn't the result of - // a previous mod operation (encryption) using that modulus - if(y.compareTo(key.n) >= 0) { - throw new Error('Encrypted message is invalid.'); - } - - // do RSA decryption - var x = _modPow(y, key, pub); - - // create the encryption block, if x is shorter in bytes than k, then - // prepend zero bytes to fill up eb - // FIXME: hex conversion inefficient, get BigInteger w/byte strings - var xhex = x.toString(16); - var eb = forge.util.createBuffer(); - var zeros = k - Math.ceil(xhex.length / 2); - while(zeros > 0) { - eb.putByte(0x00); - --zeros; - } - eb.putBytes(forge.util.hexToBytes(xhex)); - - if(ml !== false) { - // legacy, default to PKCS#1 v1.5 padding - return _decodePkcs1_v1_5(eb.getBytes(), key, pub); - } - - // return message - return eb.getBytes(); -}; - -/** - * Creates an RSA key-pair generation state object. It is used to allow - * key-generation to be performed in steps. It also allows for a UI to - * display progress updates. - * - * @param bits the size for the private key in bits, defaults to 2048. - * @param e the public exponent to use, defaults to 65537 (0x10001). - * @param [options] the options to use. - * prng a custom crypto-secure pseudo-random number generator to use, - * that must define "getBytesSync". - * algorithm the algorithm to use (default: 'PRIMEINC'). - * - * @return the state object to use to generate the key-pair. - */ -pki.rsa.createKeyPairGenerationState = function(bits, e, options) { - // TODO: migrate step-based prime generation code to forge.prime - - // set default bits - if(typeof(bits) === 'string') { - bits = parseInt(bits, 10); - } - bits = bits || 2048; - - // create prng with api that matches BigInteger secure random - options = options || {}; - var prng = options.prng || forge.random; - var rng = { - // x is an array to fill with bytes - nextBytes: function(x) { - var b = prng.getBytesSync(x.length); - for(var i = 0; i < x.length; ++i) { - x[i] = b.charCodeAt(i); - } - } - }; - - var algorithm = options.algorithm || 'PRIMEINC'; - - // create PRIMEINC algorithm state - var rval; - if(algorithm === 'PRIMEINC') { - rval = { - algorithm: algorithm, - state: 0, - bits: bits, - rng: rng, - eInt: e || 65537, - e: new BigInteger(null), - p: null, - q: null, - qBits: bits >> 1, - pBits: bits - (bits >> 1), - pqState: 0, - num: null, - keys: null - }; - rval.e.fromInt(rval.eInt); - } else { - throw new Error('Invalid key generation algorithm: ' + algorithm); - } - - return rval; -}; - -/** - * Attempts to runs the key-generation algorithm for at most n seconds - * (approximately) using the given state. When key-generation has completed, - * the keys will be stored in state.keys. - * - * To use this function to update a UI while generating a key or to prevent - * causing browser lockups/warnings, set "n" to a value other than 0. A - * simple pattern for generating a key and showing a progress indicator is: - * - * var state = pki.rsa.createKeyPairGenerationState(2048); - * var step = function() { - * // step key-generation, run algorithm for 100 ms, repeat - * if(!forge.pki.rsa.stepKeyPairGenerationState(state, 100)) { - * setTimeout(step, 1); - * } else { - * // key-generation complete - * // TODO: turn off progress indicator here - * // TODO: use the generated key-pair in "state.keys" - * } - * }; - * // TODO: turn on progress indicator here - * setTimeout(step, 0); - * - * @param state the state to use. - * @param n the maximum number of milliseconds to run the algorithm for, 0 - * to run the algorithm to completion. - * - * @return true if the key-generation completed, false if not. - */ -pki.rsa.stepKeyPairGenerationState = function(state, n) { - // set default algorithm if not set - if(!('algorithm' in state)) { - state.algorithm = 'PRIMEINC'; - } - - // TODO: migrate step-based prime generation code to forge.prime - // TODO: abstract as PRIMEINC algorithm - - // do key generation (based on Tom Wu's rsa.js, see jsbn.js license) - // with some minor optimizations and designed to run in steps - - // local state vars - var THIRTY = new BigInteger(null); - THIRTY.fromInt(30); - var deltaIdx = 0; - var op_or = function(x,y) { return x|y; }; - - // keep stepping until time limit is reached or done - var t1 = +new Date(); - var t2; - var total = 0; - while(state.keys === null && (n <= 0 || total < n)) { - // generate p or q - if(state.state === 0) { - /* Note: All primes are of the form: - - 30k+i, for i < 30 and gcd(30, i)=1, where there are 8 values for i - - When we generate a random number, we always align it at 30k + 1. Each - time the number is determined not to be prime we add to get to the - next 'i', eg: if the number was at 30k + 1 we add 6. */ - var bits = (state.p === null) ? state.pBits : state.qBits; - var bits1 = bits - 1; - - // get a random number - if(state.pqState === 0) { - state.num = new BigInteger(bits, state.rng); - // force MSB set - if(!state.num.testBit(bits1)) { - state.num.bitwiseTo( - BigInteger.ONE.shiftLeft(bits1), op_or, state.num); - } - // align number on 30k+1 boundary - state.num.dAddOffset(31 - state.num.mod(THIRTY).byteValue(), 0); - deltaIdx = 0; - - ++state.pqState; - } else if(state.pqState === 1) { - // try to make the number a prime - if(state.num.bitLength() > bits) { - // overflow, try again - state.pqState = 0; - // do primality test - } else if(state.num.isProbablePrime( - _getMillerRabinTests(state.num.bitLength()))) { - ++state.pqState; - } else { - // get next potential prime - state.num.dAddOffset(GCD_30_DELTA[deltaIdx++ % 8], 0); - } - } else if(state.pqState === 2) { - // ensure number is coprime with e - state.pqState = - (state.num.subtract(BigInteger.ONE).gcd(state.e) - .compareTo(BigInteger.ONE) === 0) ? 3 : 0; - } else if(state.pqState === 3) { - // store p or q - state.pqState = 0; - if(state.p === null) { - state.p = state.num; - } else { - state.q = state.num; - } - - // advance state if both p and q are ready - if(state.p !== null && state.q !== null) { - ++state.state; - } - state.num = null; - } - } else if(state.state === 1) { - // ensure p is larger than q (swap them if not) - if(state.p.compareTo(state.q) < 0) { - state.num = state.p; - state.p = state.q; - state.q = state.num; - } - ++state.state; - } else if(state.state === 2) { - // compute phi: (p - 1)(q - 1) (Euler's totient function) - state.p1 = state.p.subtract(BigInteger.ONE); - state.q1 = state.q.subtract(BigInteger.ONE); - state.phi = state.p1.multiply(state.q1); - ++state.state; - } else if(state.state === 3) { - // ensure e and phi are coprime - if(state.phi.gcd(state.e).compareTo(BigInteger.ONE) === 0) { - // phi and e are coprime, advance - ++state.state; - } else { - // phi and e aren't coprime, so generate a new p and q - state.p = null; - state.q = null; - state.state = 0; - } - } else if(state.state === 4) { - // create n, ensure n is has the right number of bits - state.n = state.p.multiply(state.q); - - // ensure n is right number of bits - if(state.n.bitLength() === state.bits) { - // success, advance - ++state.state; - } else { - // failed, get new q - state.q = null; - state.state = 0; - } - } else if(state.state === 5) { - // set keys - var d = state.e.modInverse(state.phi); - state.keys = { - privateKey: pki.rsa.setPrivateKey( - state.n, state.e, d, state.p, state.q, - d.mod(state.p1), d.mod(state.q1), - state.q.modInverse(state.p)), - publicKey: pki.rsa.setPublicKey(state.n, state.e) - }; - } - - // update timing - t2 = +new Date(); - total += t2 - t1; - t1 = t2; - } - - return state.keys !== null; -}; - -/** - * Generates an RSA public-private key pair in a single call. - * - * To generate a key-pair in steps (to allow for progress updates and to - * prevent blocking or warnings in slow browsers) then use the key-pair - * generation state functions. - * - * To generate a key-pair asynchronously (either through web-workers, if - * available, or by breaking up the work on the main thread), pass a - * callback function. - * - * @param [bits] the size for the private key in bits, defaults to 2048. - * @param [e] the public exponent to use, defaults to 65537. - * @param [options] options for key-pair generation, if given then 'bits' - * and 'e' must *not* be given: - * bits the size for the private key in bits, (default: 2048). - * e the public exponent to use, (default: 65537 (0x10001)). - * workerScript the worker script URL. - * workers the number of web workers (if supported) to use, - * (default: 2). - * workLoad the size of the work load, ie: number of possible prime - * numbers for each web worker to check per work assignment, - * (default: 100). - * e the public exponent to use, defaults to 65537. - * prng a custom crypto-secure pseudo-random number generator to use, - * that must define "getBytesSync". - * algorithm the algorithm to use (default: 'PRIMEINC'). - * @param [callback(err, keypair)] called once the operation completes. - * - * @return an object with privateKey and publicKey properties. - */ -pki.rsa.generateKeyPair = function(bits, e, options, callback) { - // (bits), (options), (callback) - if(arguments.length === 1) { - if(typeof bits === 'object') { - options = bits; - bits = undefined; - } else if(typeof bits === 'function') { - callback = bits; - bits = undefined; - } - } else if(arguments.length === 2) { - // (bits, e), (bits, options), (bits, callback), (options, callback) - if(typeof bits === 'number') { - if(typeof e === 'function') { - callback = e; - e = undefined; - } else if(typeof e !== 'number') { - options = e; - e = undefined; - } - } else { - options = bits; - callback = e; - bits = undefined; - e = undefined; - } - } else if(arguments.length === 3) { - // (bits, e, options), (bits, e, callback), (bits, options, callback) - if(typeof e === 'number') { - if(typeof options === 'function') { - callback = options; - options = undefined; - } - } else { - callback = options; - options = e; - e = undefined; - } - } - options = options || {}; - if(bits === undefined) { - bits = options.bits || 2048; - } - if(e === undefined) { - e = options.e || 0x10001; - } - var state = pki.rsa.createKeyPairGenerationState(bits, e, options); - if(!callback) { - pki.rsa.stepKeyPairGenerationState(state, 0); - return state.keys; - } - _generateKeyPair(state, options, callback); -}; - -/** - * Sets an RSA public key from BigIntegers modulus and exponent. - * - * @param n the modulus. - * @param e the exponent. - * - * @return the public key. - */ -pki.setRsaPublicKey = pki.rsa.setPublicKey = function(n, e) { - var key = { - n: n, - e: e - }; - - /** - * Encrypts the given data with this public key. Newer applications - * should use the 'RSA-OAEP' decryption scheme, 'RSAES-PKCS1-V1_5' is for - * legacy applications. - * - * @param data the byte string to encrypt. - * @param scheme the encryption scheme to use: - * 'RSAES-PKCS1-V1_5' (default), - * 'RSA-OAEP', - * 'RAW', 'NONE', or null to perform raw RSA encryption, - * an object with an 'encode' property set to a function - * with the signature 'function(data, key)' that returns - * a binary-encoded string representing the encoded data. - * @param schemeOptions any scheme-specific options. - * - * @return the encrypted byte string. - */ - key.encrypt = function(data, scheme, schemeOptions) { - if(typeof scheme === 'string') { - scheme = scheme.toUpperCase(); - } else if(scheme === undefined) { - scheme = 'RSAES-PKCS1-V1_5'; - } - - if(scheme === 'RSAES-PKCS1-V1_5') { - scheme = { - encode: function(m, key, pub) { - return _encodePkcs1_v1_5(m, key, 0x02).getBytes(); - } - }; - } else if(scheme === 'RSA-OAEP' || scheme === 'RSAES-OAEP') { - scheme = { - encode: function(m, key) { - return forge.pkcs1.encode_rsa_oaep(key, m, schemeOptions); - } - }; - } else if(['RAW', 'NONE', 'NULL', null].indexOf(scheme) !== -1) { - scheme = { encode: function(e) { return e; } }; - } else if(typeof scheme === 'string') { - throw new Error('Unsupported encryption scheme: "' + scheme + '".'); - } - - // do scheme-based encoding then rsa encryption - var e = scheme.encode(data, key, true); - return pki.rsa.encrypt(e, key, true); - }; - - /** - * Verifies the given signature against the given digest. - * - * PKCS#1 supports multiple (currently two) signature schemes: - * RSASSA-PKCS1-V1_5 and RSASSA-PSS. - * - * By default this implementation uses the "old scheme", i.e. - * RSASSA-PKCS1-V1_5, in which case once RSA-decrypted, the - * signature is an OCTET STRING that holds a DigestInfo. - * - * DigestInfo ::= SEQUENCE { - * digestAlgorithm DigestAlgorithmIdentifier, - * digest Digest - * } - * DigestAlgorithmIdentifier ::= AlgorithmIdentifier - * Digest ::= OCTET STRING - * - * To perform PSS signature verification, provide an instance - * of Forge PSS object as the scheme parameter. - * - * @param digest the message digest hash to compare against the signature, - * as a binary-encoded string. - * @param signature the signature to verify, as a binary-encoded string. - * @param scheme signature verification scheme to use: - * 'RSASSA-PKCS1-V1_5' or undefined for RSASSA PKCS#1 v1.5, - * a Forge PSS object for RSASSA-PSS, - * 'NONE' or null for none, DigestInfo will not be expected, but - * PKCS#1 v1.5 padding will still be used. - * - * @return true if the signature was verified, false if not. - */ - key.verify = function(digest, signature, scheme) { - if(typeof scheme === 'string') { - scheme = scheme.toUpperCase(); - } else if(scheme === undefined) { - scheme = 'RSASSA-PKCS1-V1_5'; - } - - if(scheme === 'RSASSA-PKCS1-V1_5') { - scheme = { - verify: function(digest, d) { - // remove padding - d = _decodePkcs1_v1_5(d, key, true); - // d is ASN.1 BER-encoded DigestInfo - var obj = asn1.fromDer(d); - // compare the given digest to the decrypted one - return digest === obj.value[1].value; - } - }; - } else if(scheme === 'NONE' || scheme === 'NULL' || scheme === null) { - scheme = { - verify: function(digest, d) { - // remove padding - d = _decodePkcs1_v1_5(d, key, true); - return digest === d; - } - }; - } - - // do rsa decryption w/o any decoding, then verify -- which does decoding - var d = pki.rsa.decrypt(signature, key, true, false); - return scheme.verify(digest, d, key.n.bitLength()); - }; - - return key; -}; - -/** - * Sets an RSA private key from BigIntegers modulus, exponent, primes, - * prime exponents, and modular multiplicative inverse. - * - * @param n the modulus. - * @param e the public exponent. - * @param d the private exponent ((inverse of e) mod n). - * @param p the first prime. - * @param q the second prime. - * @param dP exponent1 (d mod (p-1)). - * @param dQ exponent2 (d mod (q-1)). - * @param qInv ((inverse of q) mod p) - * - * @return the private key. - */ -pki.setRsaPrivateKey = pki.rsa.setPrivateKey = function( - n, e, d, p, q, dP, dQ, qInv) { - var key = { - n: n, - e: e, - d: d, - p: p, - q: q, - dP: dP, - dQ: dQ, - qInv: qInv - }; - - /** - * Decrypts the given data with this private key. The decryption scheme - * must match the one used to encrypt the data. - * - * @param data the byte string to decrypt. - * @param scheme the decryption scheme to use: - * 'RSAES-PKCS1-V1_5' (default), - * 'RSA-OAEP', - * 'RAW', 'NONE', or null to perform raw RSA decryption. - * @param schemeOptions any scheme-specific options. - * - * @return the decrypted byte string. - */ - key.decrypt = function(data, scheme, schemeOptions) { - if(typeof scheme === 'string') { - scheme = scheme.toUpperCase(); - } else if(scheme === undefined) { - scheme = 'RSAES-PKCS1-V1_5'; - } - - // do rsa decryption w/o any decoding - var d = pki.rsa.decrypt(data, key, false, false); - - if(scheme === 'RSAES-PKCS1-V1_5') { - scheme = { decode: _decodePkcs1_v1_5 }; - } else if(scheme === 'RSA-OAEP' || scheme === 'RSAES-OAEP') { - scheme = { - decode: function(d, key) { - return forge.pkcs1.decode_rsa_oaep(key, d, schemeOptions); - } - }; - } else if(['RAW', 'NONE', 'NULL', null].indexOf(scheme) !== -1) { - scheme = { decode: function(d) { return d; } }; - } else { - throw new Error('Unsupported encryption scheme: "' + scheme + '".'); - } - - // decode according to scheme - return scheme.decode(d, key, false); - }; - - /** - * Signs the given digest, producing a signature. - * - * PKCS#1 supports multiple (currently two) signature schemes: - * RSASSA-PKCS1-V1_5 and RSASSA-PSS. - * - * By default this implementation uses the "old scheme", i.e. - * RSASSA-PKCS1-V1_5. In order to generate a PSS signature, provide - * an instance of Forge PSS object as the scheme parameter. - * - * @param md the message digest object with the hash to sign. - * @param scheme the signature scheme to use: - * 'RSASSA-PKCS1-V1_5' or undefined for RSASSA PKCS#1 v1.5, - * a Forge PSS object for RSASSA-PSS, - * 'NONE' or null for none, DigestInfo will not be used but - * PKCS#1 v1.5 padding will still be used. - * - * @return the signature as a byte string. - */ - key.sign = function(md, scheme) { - /* Note: The internal implementation of RSA operations is being - transitioned away from a PKCS#1 v1.5 hard-coded scheme. Some legacy - code like the use of an encoding block identifier 'bt' will eventually - be removed. */ - - // private key operation - var bt = false; - - if(typeof scheme === 'string') { - scheme = scheme.toUpperCase(); - } - - if(scheme === undefined || scheme === 'RSASSA-PKCS1-V1_5') { - scheme = { encode: emsaPkcs1v15encode }; - bt = 0x01; - } else if(scheme === 'NONE' || scheme === 'NULL' || scheme === null) { - scheme = { encode: function() { return md; } }; - bt = 0x01; - } - - // encode and then encrypt - var d = scheme.encode(md, key.n.bitLength()); - return pki.rsa.encrypt(d, key, bt); - }; - - return key; -}; - -/** - * Wraps an RSAPrivateKey ASN.1 object in an ASN.1 PrivateKeyInfo object. - * - * @param rsaKey the ASN.1 RSAPrivateKey. - * - * @return the ASN.1 PrivateKeyInfo. - */ -pki.wrapRsaPrivateKey = function(rsaKey) { - // PrivateKeyInfo - return asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [ - // version (0) - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false, - asn1.integerToDer(0).getBytes()), - // privateKeyAlgorithm - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [ - asn1.create( - asn1.Class.UNIVERSAL, asn1.Type.OID, false, - asn1.oidToDer(pki.oids.rsaEncryption).getBytes()), - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.NULL, false, '') - ]), - // PrivateKey - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OCTETSTRING, false, - asn1.toDer(rsaKey).getBytes()) - ]); -}; - -/** - * Converts a private key from an ASN.1 object. - * - * @param obj the ASN.1 representation of a PrivateKeyInfo containing an - * RSAPrivateKey or an RSAPrivateKey. - * - * @return the private key. - */ -pki.privateKeyFromAsn1 = function(obj) { - // get PrivateKeyInfo - var capture = {}; - var errors = []; - if(asn1.validate(obj, privateKeyValidator, capture, errors)) { - obj = asn1.fromDer(forge.util.createBuffer(capture.privateKey)); - } - - // get RSAPrivateKey - capture = {}; - errors = []; - if(!asn1.validate(obj, rsaPrivateKeyValidator, capture, errors)) { - var error = new Error('Cannot read private key. ' + - 'ASN.1 object does not contain an RSAPrivateKey.'); - error.errors = errors; - throw error; - } - - // Note: Version is currently ignored. - // capture.privateKeyVersion - // FIXME: inefficient, get a BigInteger that uses byte strings - var n, e, d, p, q, dP, dQ, qInv; - n = forge.util.createBuffer(capture.privateKeyModulus).toHex(); - e = forge.util.createBuffer(capture.privateKeyPublicExponent).toHex(); - d = forge.util.createBuffer(capture.privateKeyPrivateExponent).toHex(); - p = forge.util.createBuffer(capture.privateKeyPrime1).toHex(); - q = forge.util.createBuffer(capture.privateKeyPrime2).toHex(); - dP = forge.util.createBuffer(capture.privateKeyExponent1).toHex(); - dQ = forge.util.createBuffer(capture.privateKeyExponent2).toHex(); - qInv = forge.util.createBuffer(capture.privateKeyCoefficient).toHex(); - - // set private key - return pki.setRsaPrivateKey( - new BigInteger(n, 16), - new BigInteger(e, 16), - new BigInteger(d, 16), - new BigInteger(p, 16), - new BigInteger(q, 16), - new BigInteger(dP, 16), - new BigInteger(dQ, 16), - new BigInteger(qInv, 16)); -}; - -/** - * Converts a private key to an ASN.1 RSAPrivateKey. - * - * @param key the private key. - * - * @return the ASN.1 representation of an RSAPrivateKey. - */ -pki.privateKeyToAsn1 = pki.privateKeyToRSAPrivateKey = function(key) { - // RSAPrivateKey - return asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [ - // version (0 = only 2 primes, 1 multiple primes) - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false, - asn1.integerToDer(0).getBytes()), - // modulus (n) - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false, - _bnToBytes(key.n)), - // publicExponent (e) - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false, - _bnToBytes(key.e)), - // privateExponent (d) - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false, - _bnToBytes(key.d)), - // privateKeyPrime1 (p) - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false, - _bnToBytes(key.p)), - // privateKeyPrime2 (q) - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false, - _bnToBytes(key.q)), - // privateKeyExponent1 (dP) - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false, - _bnToBytes(key.dP)), - // privateKeyExponent2 (dQ) - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false, - _bnToBytes(key.dQ)), - // coefficient (qInv) - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false, - _bnToBytes(key.qInv)) - ]); -}; - -/** - * Converts a public key from an ASN.1 SubjectPublicKeyInfo or RSAPublicKey. - * - * @param obj the asn1 representation of a SubjectPublicKeyInfo or RSAPublicKey. - * - * @return the public key. - */ -pki.publicKeyFromAsn1 = function(obj) { - // get SubjectPublicKeyInfo - var capture = {}; - var errors = []; - if(asn1.validate(obj, publicKeyValidator, capture, errors)) { - // get oid - var oid = asn1.derToOid(capture.publicKeyOid); - if(oid !== pki.oids.rsaEncryption) { - var error = new Error('Cannot read public key. Unknown OID.'); - error.oid = oid; - throw error; - } - obj = capture.rsaPublicKey; - } - - // get RSA params - errors = []; - if(!asn1.validate(obj, rsaPublicKeyValidator, capture, errors)) { - var error = new Error('Cannot read public key. ' + - 'ASN.1 object does not contain an RSAPublicKey.'); - error.errors = errors; - throw error; - } - - // FIXME: inefficient, get a BigInteger that uses byte strings - var n = forge.util.createBuffer(capture.publicKeyModulus).toHex(); - var e = forge.util.createBuffer(capture.publicKeyExponent).toHex(); - - // set public key - return pki.setRsaPublicKey( - new BigInteger(n, 16), - new BigInteger(e, 16)); -}; - -/** - * Converts a public key to an ASN.1 SubjectPublicKeyInfo. - * - * @param key the public key. - * - * @return the asn1 representation of a SubjectPublicKeyInfo. - */ -pki.publicKeyToAsn1 = pki.publicKeyToSubjectPublicKeyInfo = function(key) { - // SubjectPublicKeyInfo - return asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [ - // AlgorithmIdentifier - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [ - // algorithm - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, - asn1.oidToDer(pki.oids.rsaEncryption).getBytes()), - // parameters (null) - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.NULL, false, '') - ]), - // subjectPublicKey - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.BITSTRING, false, [ - pki.publicKeyToRSAPublicKey(key) - ]) - ]); -}; - -/** - * Converts a public key to an ASN.1 RSAPublicKey. - * - * @param key the public key. - * - * @return the asn1 representation of a RSAPublicKey. - */ -pki.publicKeyToRSAPublicKey = function(key) { - // RSAPublicKey - return asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [ - // modulus (n) - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false, - _bnToBytes(key.n)), - // publicExponent (e) - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false, - _bnToBytes(key.e)) - ]); -}; - -/** - * Encodes a message using PKCS#1 v1.5 padding. - * - * @param m the message to encode. - * @param key the RSA key to use. - * @param bt the block type to use, i.e. either 0x01 (for signing) or 0x02 - * (for encryption). - * - * @return the padded byte buffer. - */ -function _encodePkcs1_v1_5(m, key, bt) { - var eb = forge.util.createBuffer(); - - // get the length of the modulus in bytes - var k = Math.ceil(key.n.bitLength() / 8); - - /* use PKCS#1 v1.5 padding */ - if(m.length > (k - 11)) { - var error = new Error('Message is too long for PKCS#1 v1.5 padding.'); - error.length = m.length; - error.max = k - 11; - throw error; - } - - /* A block type BT, a padding string PS, and the data D shall be - formatted into an octet string EB, the encryption block: - - EB = 00 || BT || PS || 00 || D - - The block type BT shall be a single octet indicating the structure of - the encryption block. For this version of the document it shall have - value 00, 01, or 02. For a private-key operation, the block type - shall be 00 or 01. For a public-key operation, it shall be 02. - - The padding string PS shall consist of k-3-||D|| octets. For block - type 00, the octets shall have value 00; for block type 01, they - shall have value FF; and for block type 02, they shall be - pseudorandomly generated and nonzero. This makes the length of the - encryption block EB equal to k. */ - - // build the encryption block - eb.putByte(0x00); - eb.putByte(bt); - - // create the padding - var padNum = k - 3 - m.length; - var padByte; - // private key op - if(bt === 0x00 || bt === 0x01) { - padByte = (bt === 0x00) ? 0x00 : 0xFF; - for(var i = 0; i < padNum; ++i) { - eb.putByte(padByte); - } - } else { - // public key op - // pad with random non-zero values - while(padNum > 0) { - var numZeros = 0; - var padBytes = forge.random.getBytes(padNum); - for(var i = 0; i < padNum; ++i) { - padByte = padBytes.charCodeAt(i); - if(padByte === 0) { - ++numZeros; - } else { - eb.putByte(padByte); - } - } - padNum = numZeros; - } - } - - // zero followed by message - eb.putByte(0x00); - eb.putBytes(m); - - return eb; -} - -/** - * Decodes a message using PKCS#1 v1.5 padding. - * - * @param em the message to decode. - * @param key the RSA key to use. - * @param pub true if the key is a public key, false if it is private. - * @param ml the message length, if specified. - * - * @return the decoded bytes. - */ -function _decodePkcs1_v1_5(em, key, pub, ml) { - // get the length of the modulus in bytes - var k = Math.ceil(key.n.bitLength() / 8); - - /* It is an error if any of the following conditions occurs: - - 1. The encryption block EB cannot be parsed unambiguously. - 2. The padding string PS consists of fewer than eight octets - or is inconsisent with the block type BT. - 3. The decryption process is a public-key operation and the block - type BT is not 00 or 01, or the decryption process is a - private-key operation and the block type is not 02. - */ - - // parse the encryption block - var eb = forge.util.createBuffer(em); - var first = eb.getByte(); - var bt = eb.getByte(); - if(first !== 0x00 || - (pub && bt !== 0x00 && bt !== 0x01) || - (!pub && bt != 0x02) || - (pub && bt === 0x00 && typeof(ml) === 'undefined')) { - throw new Error('Encryption block is invalid.'); - } - - var padNum = 0; - if(bt === 0x00) { - // check all padding bytes for 0x00 - padNum = k - 3 - ml; - for(var i = 0; i < padNum; ++i) { - if(eb.getByte() !== 0x00) { - throw new Error('Encryption block is invalid.'); - } - } - } else if(bt === 0x01) { - // find the first byte that isn't 0xFF, should be after all padding - padNum = 0; - while(eb.length() > 1) { - if(eb.getByte() !== 0xFF) { - --eb.read; - break; - } - ++padNum; - } - } else if(bt === 0x02) { - // look for 0x00 byte - padNum = 0; - while(eb.length() > 1) { - if(eb.getByte() === 0x00) { - --eb.read; - break; - } - ++padNum; - } - } - - // zero must be 0x00 and padNum must be (k - 3 - message length) - var zero = eb.getByte(); - if(zero !== 0x00 || padNum !== (k - 3 - eb.length())) { - throw new Error('Encryption block is invalid.'); - } - - return eb.getBytes(); -} - -/** - * Runs the key-generation algorithm asynchronously, either in the background - * via Web Workers, or using the main thread and setImmediate. - * - * @param state the key-pair generation state. - * @param [options] options for key-pair generation: - * workerScript the worker script URL. - * workers the number of web workers (if supported) to use, - * (default: 2, -1 to use estimated cores minus one). - * workLoad the size of the work load, ie: number of possible prime - * numbers for each web worker to check per work assignment, - * (default: 100). - * @param callback(err, keypair) called once the operation completes. - */ -function _generateKeyPair(state, options, callback) { - if(typeof options === 'function') { - callback = options; - options = {}; - } - options = options || {}; - - var opts = { - algorithm: { - name: options.algorithm || 'PRIMEINC', - options: { - workers: options.workers || 2, - workLoad: options.workLoad || 100, - workerScript: options.workerScript - } - } - }; - if('prng' in options) { - opts.prng = options.prng; - } - - generate(); - - function generate() { - // find p and then q (done in series to simplify) - getPrime(state.pBits, function(err, num) { - if(err) { - return callback(err); - } - state.p = num; - if(state.q !== null) { - return finish(err, state.q); - } - getPrime(state.qBits, finish); - }); - } - - function getPrime(bits, callback) { - forge.prime.generateProbablePrime(bits, opts, callback); - } - - function finish(err, num) { - if(err) { - return callback(err); - } - - // set q - state.q = num; - - // ensure p is larger than q (swap them if not) - if(state.p.compareTo(state.q) < 0) { - var tmp = state.p; - state.p = state.q; - state.q = tmp; - } - - // ensure p is coprime with e - if(state.p.subtract(BigInteger.ONE).gcd(state.e) - .compareTo(BigInteger.ONE) !== 0) { - state.p = null; - generate(); - return; - } - - // ensure q is coprime with e - if(state.q.subtract(BigInteger.ONE).gcd(state.e) - .compareTo(BigInteger.ONE) !== 0) { - state.q = null; - getPrime(state.qBits, finish); - return; - } - - // compute phi: (p - 1)(q - 1) (Euler's totient function) - state.p1 = state.p.subtract(BigInteger.ONE); - state.q1 = state.q.subtract(BigInteger.ONE); - state.phi = state.p1.multiply(state.q1); - - // ensure e and phi are coprime - if(state.phi.gcd(state.e).compareTo(BigInteger.ONE) !== 0) { - // phi and e aren't coprime, so generate a new p and q - state.p = state.q = null; - generate(); - return; - } - - // create n, ensure n is has the right number of bits - state.n = state.p.multiply(state.q); - if(state.n.bitLength() !== state.bits) { - // failed, get new q - state.q = null; - getPrime(state.qBits, finish); - return; - } - - // set keys - var d = state.e.modInverse(state.phi); - state.keys = { - privateKey: pki.rsa.setPrivateKey( - state.n, state.e, d, state.p, state.q, - d.mod(state.p1), d.mod(state.q1), - state.q.modInverse(state.p)), - publicKey: pki.rsa.setPublicKey(state.n, state.e) - }; - - callback(null, state.keys); - } -} - -/** - * Converts a positive BigInteger into 2's-complement big-endian bytes. - * - * @param b the big integer to convert. - * - * @return the bytes. - */ -function _bnToBytes(b) { - // prepend 0x00 if first byte >= 0x80 - var hex = b.toString(16); - if(hex[0] >= '8') { - hex = '00' + hex; - } - return forge.util.hexToBytes(hex); -} - -/** - * Returns the required number of Miller-Rabin tests to generate a - * prime with an error probability of (1/2)^80. - * - * See Handbook of Applied Cryptography Chapter 4, Table 4.4. - * - * @param bits the bit size. - * - * @return the required number of iterations. - */ -function _getMillerRabinTests(bits) { - if(bits <= 100) return 27; - if(bits <= 150) return 18; - if(bits <= 200) return 15; - if(bits <= 250) return 12; - if(bits <= 300) return 9; - if(bits <= 350) return 8; - if(bits <= 400) return 7; - if(bits <= 500) return 6; - if(bits <= 600) return 5; - if(bits <= 800) return 4; - if(bits <= 1250) return 3; - return 2; -} - -} // end module implementation - -/* ########## Begin module wrapper ########## */ -var name = 'rsa'; -if(typeof define !== 'function') { - // NodeJS -> AMD - if(typeof module === 'object' && module.exports) { - var nodeJS = true; - define = function(ids, factory) { - factory(require, module); - }; - } else { - // <script> - if(typeof forge === 'undefined') { - forge = {}; - } - return initModule(forge); - } -} -// AMD -var deps; -var defineFunc = function(require, module) { - module.exports = function(forge) { - var mods = deps.map(function(dep) { - return require(dep); - }).concat(initModule); - // handle circular dependencies - forge = forge || {}; - forge.defined = forge.defined || {}; - if(forge.defined[name]) { - return forge[name]; - } - forge.defined[name] = true; - for(var i = 0; i < mods.length; ++i) { - mods[i](forge); - } - return forge[name]; - }; -}; -var tmpDefine = define; -define = function(ids, factory) { - deps = (typeof ids === 'string') ? factory.slice(2) : ids.slice(2); - if(nodeJS) { - delete define; - return tmpDefine.apply(null, Array.prototype.slice.call(arguments, 0)); - } - define = tmpDefine; - return define.apply(null, Array.prototype.slice.call(arguments, 0)); -}; -define([ - 'require', - 'module', - './asn1', - './jsbn', - './oids', - './pkcs1', - './prime', - './random', - './util' -], function() { - defineFunc.apply(null, Array.prototype.slice.call(arguments, 0)); -}); -})(); diff --git a/alarm/node_modules/node-forge/js/sha1.js b/alarm/node_modules/node-forge/js/sha1.js deleted file mode 100644 index 53f65d2..0000000 --- a/alarm/node_modules/node-forge/js/sha1.js +++ /dev/null @@ -1,342 +0,0 @@ -/** - * Secure Hash Algorithm with 160-bit digest (SHA-1) implementation. - * - * @author Dave Longley - * - * Copyright (c) 2010-2014 Digital Bazaar, Inc. - */ -(function() { -/* ########## Begin module implementation ########## */ -function initModule(forge) { - -var sha1 = forge.sha1 = forge.sha1 || {}; -forge.md = forge.md || {}; -forge.md.algorithms = forge.md.algorithms || {}; -forge.md.sha1 = forge.md.algorithms.sha1 = sha1; - -/** - * Creates a SHA-1 message digest object. - * - * @return a message digest object. - */ -sha1.create = function() { - // do initialization as necessary - if(!_initialized) { - _init(); - } - - // SHA-1 state contains five 32-bit integers - var _state = null; - - // input buffer - var _input = forge.util.createBuffer(); - - // used for word storage - var _w = new Array(80); - - // message digest object - var md = { - algorithm: 'sha1', - blockLength: 64, - digestLength: 20, - // 56-bit length of message so far (does not including padding) - messageLength: 0, - // true 64-bit message length as two 32-bit ints - messageLength64: [0, 0] - }; - - /** - * Starts the digest. - * - * @return this digest object. - */ - md.start = function() { - md.messageLength = 0; - md.messageLength64 = [0, 0]; - _input = forge.util.createBuffer(); - _state = { - h0: 0x67452301, - h1: 0xEFCDAB89, - h2: 0x98BADCFE, - h3: 0x10325476, - h4: 0xC3D2E1F0 - }; - return md; - }; - // start digest automatically for first time - md.start(); - - /** - * Updates the digest with the given message input. The given input can - * treated as raw input (no encoding will be applied) or an encoding of - * 'utf8' maybe given to encode the input using UTF-8. - * - * @param msg the message input to update with. - * @param encoding the encoding to use (default: 'raw', other: 'utf8'). - * - * @return this digest object. - */ - md.update = function(msg, encoding) { - if(encoding === 'utf8') { - msg = forge.util.encodeUtf8(msg); - } - - // update message length - md.messageLength += msg.length; - md.messageLength64[0] += (msg.length / 0x100000000) >>> 0; - md.messageLength64[1] += msg.length >>> 0; - - // add bytes to input buffer - _input.putBytes(msg); - - // process bytes - _update(_state, _w, _input); - - // compact input buffer every 2K or if empty - if(_input.read > 2048 || _input.length() === 0) { - _input.compact(); - } - - return md; - }; - - /** - * Produces the digest. - * - * @return a byte buffer containing the digest value. - */ - md.digest = function() { - /* Note: Here we copy the remaining bytes in the input buffer and - add the appropriate SHA-1 padding. Then we do the final update - on a copy of the state so that if the user wants to get - intermediate digests they can do so. */ - - /* Determine the number of bytes that must be added to the message - to ensure its length is congruent to 448 mod 512. In other words, - the data to be digested must be a multiple of 512 bits (or 128 bytes). - This data includes the message, some padding, and the length of the - message. Since the length of the message will be encoded as 8 bytes (64 - bits), that means that the last segment of the data must have 56 bytes - (448 bits) of message and padding. Therefore, the length of the message - plus the padding must be congruent to 448 mod 512 because - 512 - 128 = 448. - - In order to fill up the message length it must be filled with - padding that begins with 1 bit followed by all 0 bits. Padding - must *always* be present, so if the message length is already - congruent to 448 mod 512, then 512 padding bits must be added. */ - - // 512 bits == 64 bytes, 448 bits == 56 bytes, 64 bits = 8 bytes - // _padding starts with 1 byte with first bit is set in it which - // is byte value 128, then there may be up to 63 other pad bytes - var padBytes = forge.util.createBuffer(); - padBytes.putBytes(_input.bytes()); - // 64 - (remaining msg + 8 bytes msg length) mod 64 - padBytes.putBytes( - _padding.substr(0, 64 - ((md.messageLength64[1] + 8) & 0x3F))); - - /* Now append length of the message. The length is appended in bits - as a 64-bit number in big-endian order. Since we store the length in - bytes, we must multiply the 64-bit length by 8 (or left shift by 3). */ - padBytes.putInt32( - (md.messageLength64[0] << 3) | (md.messageLength64[0] >>> 28)); - padBytes.putInt32(md.messageLength64[1] << 3); - var s2 = { - h0: _state.h0, - h1: _state.h1, - h2: _state.h2, - h3: _state.h3, - h4: _state.h4 - }; - _update(s2, _w, padBytes); - var rval = forge.util.createBuffer(); - rval.putInt32(s2.h0); - rval.putInt32(s2.h1); - rval.putInt32(s2.h2); - rval.putInt32(s2.h3); - rval.putInt32(s2.h4); - return rval; - }; - - return md; -}; - -// sha-1 padding bytes not initialized yet -var _padding = null; -var _initialized = false; - -/** - * Initializes the constant tables. - */ -function _init() { - // create padding - _padding = String.fromCharCode(128); - _padding += forge.util.fillString(String.fromCharCode(0x00), 64); - - // now initialized - _initialized = true; -} - -/** - * Updates a SHA-1 state with the given byte buffer. - * - * @param s the SHA-1 state to update. - * @param w the array to use to store words. - * @param bytes the byte buffer to update with. - */ -function _update(s, w, bytes) { - // consume 512 bit (64 byte) chunks - var t, a, b, c, d, e, f, i; - var len = bytes.length(); - while(len >= 64) { - // the w array will be populated with sixteen 32-bit big-endian words - // and then extended into 80 32-bit words according to SHA-1 algorithm - // and for 32-79 using Max Locktyukhin's optimization - - // initialize hash value for this chunk - a = s.h0; - b = s.h1; - c = s.h2; - d = s.h3; - e = s.h4; - - // round 1 - for(i = 0; i < 16; ++i) { - t = bytes.getInt32(); - w[i] = t; - f = d ^ (b & (c ^ d)); - t = ((a << 5) | (a >>> 27)) + f + e + 0x5A827999 + t; - e = d; - d = c; - c = (b << 30) | (b >>> 2); - b = a; - a = t; - } - for(; i < 20; ++i) { - t = (w[i - 3] ^ w[i - 8] ^ w[i - 14] ^ w[i - 16]); - t = (t << 1) | (t >>> 31); - w[i] = t; - f = d ^ (b & (c ^ d)); - t = ((a << 5) | (a >>> 27)) + f + e + 0x5A827999 + t; - e = d; - d = c; - c = (b << 30) | (b >>> 2); - b = a; - a = t; - } - // round 2 - for(; i < 32; ++i) { - t = (w[i - 3] ^ w[i - 8] ^ w[i - 14] ^ w[i - 16]); - t = (t << 1) | (t >>> 31); - w[i] = t; - f = b ^ c ^ d; - t = ((a << 5) | (a >>> 27)) + f + e + 0x6ED9EBA1 + t; - e = d; - d = c; - c = (b << 30) | (b >>> 2); - b = a; - a = t; - } - for(; i < 40; ++i) { - t = (w[i - 6] ^ w[i - 16] ^ w[i - 28] ^ w[i - 32]); - t = (t << 2) | (t >>> 30); - w[i] = t; - f = b ^ c ^ d; - t = ((a << 5) | (a >>> 27)) + f + e + 0x6ED9EBA1 + t; - e = d; - d = c; - c = (b << 30) | (b >>> 2); - b = a; - a = t; - } - // round 3 - for(; i < 60; ++i) { - t = (w[i - 6] ^ w[i - 16] ^ w[i - 28] ^ w[i - 32]); - t = (t << 2) | (t >>> 30); - w[i] = t; - f = (b & c) | (d & (b ^ c)); - t = ((a << 5) | (a >>> 27)) + f + e + 0x8F1BBCDC + t; - e = d; - d = c; - c = (b << 30) | (b >>> 2); - b = a; - a = t; - } - // round 4 - for(; i < 80; ++i) { - t = (w[i - 6] ^ w[i - 16] ^ w[i - 28] ^ w[i - 32]); - t = (t << 2) | (t >>> 30); - w[i] = t; - f = b ^ c ^ d; - t = ((a << 5) | (a >>> 27)) + f + e + 0xCA62C1D6 + t; - e = d; - d = c; - c = (b << 30) | (b >>> 2); - b = a; - a = t; - } - - // update hash state - s.h0 = (s.h0 + a) | 0; - s.h1 = (s.h1 + b) | 0; - s.h2 = (s.h2 + c) | 0; - s.h3 = (s.h3 + d) | 0; - s.h4 = (s.h4 + e) | 0; - - len -= 64; - } -} - -} // end module implementation - -/* ########## Begin module wrapper ########## */ -var name = 'sha1'; -if(typeof define !== 'function') { - // NodeJS -> AMD - if(typeof module === 'object' && module.exports) { - var nodeJS = true; - define = function(ids, factory) { - factory(require, module); - }; - } else { - // <script> - if(typeof forge === 'undefined') { - forge = {}; - } - return initModule(forge); - } -} -// AMD -var deps; -var defineFunc = function(require, module) { - module.exports = function(forge) { - var mods = deps.map(function(dep) { - return require(dep); - }).concat(initModule); - // handle circular dependencies - forge = forge || {}; - forge.defined = forge.defined || {}; - if(forge.defined[name]) { - return forge[name]; - } - forge.defined[name] = true; - for(var i = 0; i < mods.length; ++i) { - mods[i](forge); - } - return forge[name]; - }; -}; -var tmpDefine = define; -define = function(ids, factory) { - deps = (typeof ids === 'string') ? factory.slice(2) : ids.slice(2); - if(nodeJS) { - delete define; - return tmpDefine.apply(null, Array.prototype.slice.call(arguments, 0)); - } - define = tmpDefine; - return define.apply(null, Array.prototype.slice.call(arguments, 0)); -}; -define(['require', 'module', './util'], function() { - defineFunc.apply(null, Array.prototype.slice.call(arguments, 0)); -}); -})(); diff --git a/alarm/node_modules/node-forge/js/sha256.js b/alarm/node_modules/node-forge/js/sha256.js deleted file mode 100644 index fdbc4fc..0000000 --- a/alarm/node_modules/node-forge/js/sha256.js +++ /dev/null @@ -1,352 +0,0 @@ -/** - * Secure Hash Algorithm with 256-bit digest (SHA-256) implementation. - * - * See FIPS 180-2 for details. - * - * @author Dave Longley - * - * Copyright (c) 2010-2014 Digital Bazaar, Inc. - */ -(function() { -/* ########## Begin module implementation ########## */ -function initModule(forge) { - -var sha256 = forge.sha256 = forge.sha256 || {}; -forge.md = forge.md || {}; -forge.md.algorithms = forge.md.algorithms || {}; -forge.md.sha256 = forge.md.algorithms.sha256 = sha256; - -/** - * Creates a SHA-256 message digest object. - * - * @return a message digest object. - */ -sha256.create = function() { - // do initialization as necessary - if(!_initialized) { - _init(); - } - - // SHA-256 state contains eight 32-bit integers - var _state = null; - - // input buffer - var _input = forge.util.createBuffer(); - - // used for word storage - var _w = new Array(64); - - // message digest object - var md = { - algorithm: 'sha256', - blockLength: 64, - digestLength: 32, - // 56-bit length of message so far (does not including padding) - messageLength: 0, - // true 64-bit message length as two 32-bit ints - messageLength64: [0, 0] - }; - - /** - * Starts the digest. - * - * @return this digest object. - */ - md.start = function() { - md.messageLength = 0; - md.messageLength64 = [0, 0]; - _input = forge.util.createBuffer(); - _state = { - h0: 0x6A09E667, - h1: 0xBB67AE85, - h2: 0x3C6EF372, - h3: 0xA54FF53A, - h4: 0x510E527F, - h5: 0x9B05688C, - h6: 0x1F83D9AB, - h7: 0x5BE0CD19 - }; - return md; - }; - // start digest automatically for first time - md.start(); - - /** - * Updates the digest with the given message input. The given input can - * treated as raw input (no encoding will be applied) or an encoding of - * 'utf8' maybe given to encode the input using UTF-8. - * - * @param msg the message input to update with. - * @param encoding the encoding to use (default: 'raw', other: 'utf8'). - * - * @return this digest object. - */ - md.update = function(msg, encoding) { - if(encoding === 'utf8') { - msg = forge.util.encodeUtf8(msg); - } - - // update message length - md.messageLength += msg.length; - md.messageLength64[0] += (msg.length / 0x100000000) >>> 0; - md.messageLength64[1] += msg.length >>> 0; - - // add bytes to input buffer - _input.putBytes(msg); - - // process bytes - _update(_state, _w, _input); - - // compact input buffer every 2K or if empty - if(_input.read > 2048 || _input.length() === 0) { - _input.compact(); - } - - return md; - }; - - /** - * Produces the digest. - * - * @return a byte buffer containing the digest value. - */ - md.digest = function() { - /* Note: Here we copy the remaining bytes in the input buffer and - add the appropriate SHA-256 padding. Then we do the final update - on a copy of the state so that if the user wants to get - intermediate digests they can do so. */ - - /* Determine the number of bytes that must be added to the message - to ensure its length is congruent to 448 mod 512. In other words, - the data to be digested must be a multiple of 512 bits (or 128 bytes). - This data includes the message, some padding, and the length of the - message. Since the length of the message will be encoded as 8 bytes (64 - bits), that means that the last segment of the data must have 56 bytes - (448 bits) of message and padding. Therefore, the length of the message - plus the padding must be congruent to 448 mod 512 because - 512 - 128 = 448. - - In order to fill up the message length it must be filled with - padding that begins with 1 bit followed by all 0 bits. Padding - must *always* be present, so if the message length is already - congruent to 448 mod 512, then 512 padding bits must be added. */ - - // 512 bits == 64 bytes, 448 bits == 56 bytes, 64 bits = 8 bytes - // _padding starts with 1 byte with first bit is set in it which - // is byte value 128, then there may be up to 63 other pad bytes - var padBytes = forge.util.createBuffer(); - padBytes.putBytes(_input.bytes()); - // 64 - (remaining msg + 8 bytes msg length) mod 64 - padBytes.putBytes( - _padding.substr(0, 64 - ((md.messageLength64[1] + 8) & 0x3F))); - - /* Now append length of the message. The length is appended in bits - as a 64-bit number in big-endian order. Since we store the length in - bytes, we must multiply the 64-bit length by 8 (or left shift by 3). */ - padBytes.putInt32( - (md.messageLength64[0] << 3) | (md.messageLength64[0] >>> 28)); - padBytes.putInt32(md.messageLength64[1] << 3); - var s2 = { - h0: _state.h0, - h1: _state.h1, - h2: _state.h2, - h3: _state.h3, - h4: _state.h4, - h5: _state.h5, - h6: _state.h6, - h7: _state.h7 - }; - _update(s2, _w, padBytes); - var rval = forge.util.createBuffer(); - rval.putInt32(s2.h0); - rval.putInt32(s2.h1); - rval.putInt32(s2.h2); - rval.putInt32(s2.h3); - rval.putInt32(s2.h4); - rval.putInt32(s2.h5); - rval.putInt32(s2.h6); - rval.putInt32(s2.h7); - return rval; - }; - - return md; -}; - -// sha-256 padding bytes not initialized yet -var _padding = null; -var _initialized = false; - -// table of constants -var _k = null; - -/** - * Initializes the constant tables. - */ -function _init() { - // create padding - _padding = String.fromCharCode(128); - _padding += forge.util.fillString(String.fromCharCode(0x00), 64); - - // create K table for SHA-256 - _k = [ - 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]; - - // now initialized - _initialized = true; -} - -/** - * Updates a SHA-256 state with the given byte buffer. - * - * @param s the SHA-256 state to update. - * @param w the array to use to store words. - * @param bytes the byte buffer to update with. - */ -function _update(s, w, bytes) { - // consume 512 bit (64 byte) chunks - var t1, t2, s0, s1, ch, maj, i, a, b, c, d, e, f, g, h; - var len = bytes.length(); - while(len >= 64) { - // the w array will be populated with sixteen 32-bit big-endian words - // and then extended into 64 32-bit words according to SHA-256 - for(i = 0; i < 16; ++i) { - w[i] = bytes.getInt32(); - } - for(; i < 64; ++i) { - // XOR word 2 words ago rot right 17, rot right 19, shft right 10 - t1 = w[i - 2]; - t1 = - ((t1 >>> 17) | (t1 << 15)) ^ - ((t1 >>> 19) | (t1 << 13)) ^ - (t1 >>> 10); - // XOR word 15 words ago rot right 7, rot right 18, shft right 3 - t2 = w[i - 15]; - t2 = - ((t2 >>> 7) | (t2 << 25)) ^ - ((t2 >>> 18) | (t2 << 14)) ^ - (t2 >>> 3); - // sum(t1, word 7 ago, t2, word 16 ago) modulo 2^32 - w[i] = (t1 + w[i - 7] + t2 + w[i - 16]) | 0; - } - - // initialize hash value for this chunk - a = s.h0; - b = s.h1; - c = s.h2; - d = s.h3; - e = s.h4; - f = s.h5; - g = s.h6; - h = s.h7; - - // round function - for(i = 0; i < 64; ++i) { - // Sum1(e) - s1 = - ((e >>> 6) | (e << 26)) ^ - ((e >>> 11) | (e << 21)) ^ - ((e >>> 25) | (e << 7)); - // Ch(e, f, g) (optimized the same way as SHA-1) - ch = g ^ (e & (f ^ g)); - // Sum0(a) - s0 = - ((a >>> 2) | (a << 30)) ^ - ((a >>> 13) | (a << 19)) ^ - ((a >>> 22) | (a << 10)); - // Maj(a, b, c) (optimized the same way as SHA-1) - maj = (a & b) | (c & (a ^ b)); - - // main algorithm - t1 = h + s1 + ch + _k[i] + w[i]; - t2 = s0 + maj; - h = g; - g = f; - f = e; - e = (d + t1) | 0; - d = c; - c = b; - b = a; - a = (t1 + t2) | 0; - } - - // update hash state - s.h0 = (s.h0 + a) | 0; - s.h1 = (s.h1 + b) | 0; - s.h2 = (s.h2 + c) | 0; - s.h3 = (s.h3 + d) | 0; - s.h4 = (s.h4 + e) | 0; - s.h5 = (s.h5 + f) | 0; - s.h6 = (s.h6 + g) | 0; - s.h7 = (s.h7 + h) | 0; - len -= 64; - } -} - -} // end module implementation - -/* ########## Begin module wrapper ########## */ -var name = 'sha256'; -if(typeof define !== 'function') { - // NodeJS -> AMD - if(typeof module === 'object' && module.exports) { - var nodeJS = true; - define = function(ids, factory) { - factory(require, module); - }; - } else { - // <script> - if(typeof forge === 'undefined') { - forge = {}; - } - return initModule(forge); - } -} -// AMD -var deps; -var defineFunc = function(require, module) { - module.exports = function(forge) { - var mods = deps.map(function(dep) { - return require(dep); - }).concat(initModule); - // handle circular dependencies - forge = forge || {}; - forge.defined = forge.defined || {}; - if(forge.defined[name]) { - return forge[name]; - } - forge.defined[name] = true; - for(var i = 0; i < mods.length; ++i) { - mods[i](forge); - } - return forge[name]; - }; -}; -var tmpDefine = define; -define = function(ids, factory) { - deps = (typeof ids === 'string') ? factory.slice(2) : ids.slice(2); - if(nodeJS) { - delete define; - return tmpDefine.apply(null, Array.prototype.slice.call(arguments, 0)); - } - define = tmpDefine; - return define.apply(null, Array.prototype.slice.call(arguments, 0)); -}; -define(['require', 'module', './util'], function() { - defineFunc.apply(null, Array.prototype.slice.call(arguments, 0)); -}); -})(); diff --git a/alarm/node_modules/node-forge/js/sha512.js b/alarm/node_modules/node-forge/js/sha512.js deleted file mode 100644 index 12a9d94..0000000 --- a/alarm/node_modules/node-forge/js/sha512.js +++ /dev/null @@ -1,590 +0,0 @@ -/** - * Secure Hash Algorithm with a 1024-bit block size implementation. - * - * This includes: SHA-512, SHA-384, SHA-512/224, and SHA-512/256. For - * SHA-256 (block size 512 bits), see sha256.js. - * - * See FIPS 180-4 for details. - * - * @author Dave Longley - * - * Copyright (c) 2014 Digital Bazaar, Inc. - */ -(function() { -/* ########## Begin module implementation ########## */ -function initModule(forge) { - -var sha512 = forge.sha512 = forge.sha512 || {}; -forge.md = forge.md || {}; -forge.md.algorithms = forge.md.algorithms || {}; - -// SHA-512 -forge.md.sha512 = forge.md.algorithms.sha512 = sha512; - -// SHA-384 -var sha384 = forge.sha384 = forge.sha512.sha384 = forge.sha512.sha384 || {}; -sha384.create = function() { - return sha512.create('SHA-384'); -}; -forge.md.sha384 = forge.md.algorithms.sha384 = sha384; - -// SHA-512/256 -forge.sha512.sha256 = forge.sha512.sha256 || { - create: function() { - return sha512.create('SHA-512/256'); - } -}; -forge.md['sha512/256'] = forge.md.algorithms['sha512/256'] = - forge.sha512.sha256; - -// SHA-512/224 -forge.sha512.sha224 = forge.sha512.sha224 || { - create: function() { - return sha512.create('SHA-512/224'); - } -}; -forge.md['sha512/224'] = forge.md.algorithms['sha512/224'] = - forge.sha512.sha224; - -/** - * Creates a SHA-2 message digest object. - * - * @param algorithm the algorithm to use (SHA-512, SHA-384, SHA-512/224, - * SHA-512/256). - * - * @return a message digest object. - */ -sha512.create = function(algorithm) { - // do initialization as necessary - if(!_initialized) { - _init(); - } - - if(typeof algorithm === 'undefined') { - algorithm = 'SHA-512'; - } - - if(!(algorithm in _states)) { - throw new Error('Invalid SHA-512 algorithm: ' + algorithm); - } - - // SHA-512 state contains eight 64-bit integers (each as two 32-bit ints) - var _state = _states[algorithm]; - var _h = null; - - // input buffer - var _input = forge.util.createBuffer(); - - // used for 64-bit word storage - var _w = new Array(80); - for(var wi = 0; wi < 80; ++wi) { - _w[wi] = new Array(2); - } - - // message digest object - var md = { - // SHA-512 => sha512 - algorithm: algorithm.replace('-', '').toLowerCase(), - blockLength: 128, - digestLength: 64, - // 56-bit length of message so far (does not including padding) - messageLength: 0, - // true 128-bit message length as four 32-bit ints - messageLength128: [0, 0, 0, 0] - }; - - /** - * Starts the digest. - * - * @return this digest object. - */ - md.start = function() { - md.messageLength = 0; - md.messageLength128 = [0, 0, 0, 0]; - _input = forge.util.createBuffer(); - _h = new Array(_state.length); - for(var i = 0; i < _state.length; ++i) { - _h[i] = _state[i].slice(0); - } - return md; - }; - // start digest automatically for first time - md.start(); - - /** - * Updates the digest with the given message input. The given input can - * treated as raw input (no encoding will be applied) or an encoding of - * 'utf8' maybe given to encode the input using UTF-8. - * - * @param msg the message input to update with. - * @param encoding the encoding to use (default: 'raw', other: 'utf8'). - * - * @return this digest object. - */ - md.update = function(msg, encoding) { - if(encoding === 'utf8') { - msg = forge.util.encodeUtf8(msg); - } - - // update message length - md.messageLength += msg.length; - var len = msg.length; - len = [(len / 0x100000000) >>> 0, len >>> 0]; - for(var i = 3; i >= 0; --i) { - md.messageLength128[i] += len[1]; - len[1] = len[0] + ((md.messageLength128[i] / 0x100000000) >>> 0); - md.messageLength128[i] = md.messageLength128[i] >>> 0; - len[0] = ((len[1] / 0x100000000) >>> 0); - } - - // add bytes to input buffer - _input.putBytes(msg); - - // process bytes - _update(_h, _w, _input); - - // compact input buffer every 2K or if empty - if(_input.read > 2048 || _input.length() === 0) { - _input.compact(); - } - - return md; - }; - - /** - * Produces the digest. - * - * @return a byte buffer containing the digest value. - */ - md.digest = function() { - /* Note: Here we copy the remaining bytes in the input buffer and - add the appropriate SHA-512 padding. Then we do the final update - on a copy of the state so that if the user wants to get - intermediate digests they can do so. */ - - /* Determine the number of bytes that must be added to the message - to ensure its length is congruent to 896 mod 1024. In other words, - the data to be digested must be a multiple of 1024 bits (or 128 bytes). - This data includes the message, some padding, and the length of the - message. Since the length of the message will be encoded as 16 bytes (128 - bits), that means that the last segment of the data must have 112 bytes - (896 bits) of message and padding. Therefore, the length of the message - plus the padding must be congruent to 896 mod 1024 because - 1024 - 128 = 896. - - In order to fill up the message length it must be filled with - padding that begins with 1 bit followed by all 0 bits. Padding - must *always* be present, so if the message length is already - congruent to 896 mod 1024, then 1024 padding bits must be added. */ - - // 1024 bits == 128 bytes, 896 bits == 112 bytes, 128 bits = 16 bytes - // _padding starts with 1 byte with first bit is set in it which - // is byte value 128, then there may be up to 127 other pad bytes - var padBytes = forge.util.createBuffer(); - padBytes.putBytes(_input.bytes()); - // 128 - (remaining msg + 16 bytes msg length) mod 128 - padBytes.putBytes( - _padding.substr(0, 128 - ((md.messageLength128[3] + 16) & 0x7F))); - - /* Now append length of the message. The length is appended in bits - as a 128-bit number in big-endian order. Since we store the length in - bytes, we must multiply the 128-bit length by 8 (or left shift by 3). */ - var bitLength = []; - for(var i = 0; i < 3; ++i) { - bitLength[i] = ((md.messageLength128[i] << 3) | - (md.messageLength128[i - 1] >>> 28)); - } - // shift the last integer normally - bitLength[3] = md.messageLength128[3] << 3; - padBytes.putInt32(bitLength[0]); - padBytes.putInt32(bitLength[1]); - padBytes.putInt32(bitLength[2]); - padBytes.putInt32(bitLength[3]); - var h = new Array(_h.length); - for(var i = 0; i < _h.length; ++i) { - h[i] = _h[i].slice(0); - } - _update(h, _w, padBytes); - var rval = forge.util.createBuffer(); - var hlen; - if(algorithm === 'SHA-512') { - hlen = h.length; - } else if(algorithm === 'SHA-384') { - hlen = h.length - 2; - } else { - hlen = h.length - 4; - } - for(var i = 0; i < hlen; ++i) { - rval.putInt32(h[i][0]); - if(i !== hlen - 1 || algorithm !== 'SHA-512/224') { - rval.putInt32(h[i][1]); - } - } - return rval; - }; - - return md; -}; - -// sha-512 padding bytes not initialized yet -var _padding = null; -var _initialized = false; - -// table of constants -var _k = null; - -// initial hash states -var _states = null; - -/** - * Initializes the constant tables. - */ -function _init() { - // create padding - _padding = String.fromCharCode(128); - _padding += forge.util.fillString(String.fromCharCode(0x00), 128); - - // create K table for SHA-512 - _k = [ - [0x428a2f98, 0xd728ae22], [0x71374491, 0x23ef65cd], - [0xb5c0fbcf, 0xec4d3b2f], [0xe9b5dba5, 0x8189dbbc], - [0x3956c25b, 0xf348b538], [0x59f111f1, 0xb605d019], - [0x923f82a4, 0xaf194f9b], [0xab1c5ed5, 0xda6d8118], - [0xd807aa98, 0xa3030242], [0x12835b01, 0x45706fbe], - [0x243185be, 0x4ee4b28c], [0x550c7dc3, 0xd5ffb4e2], - [0x72be5d74, 0xf27b896f], [0x80deb1fe, 0x3b1696b1], - [0x9bdc06a7, 0x25c71235], [0xc19bf174, 0xcf692694], - [0xe49b69c1, 0x9ef14ad2], [0xefbe4786, 0x384f25e3], - [0x0fc19dc6, 0x8b8cd5b5], [0x240ca1cc, 0x77ac9c65], - [0x2de92c6f, 0x592b0275], [0x4a7484aa, 0x6ea6e483], - [0x5cb0a9dc, 0xbd41fbd4], [0x76f988da, 0x831153b5], - [0x983e5152, 0xee66dfab], [0xa831c66d, 0x2db43210], - [0xb00327c8, 0x98fb213f], [0xbf597fc7, 0xbeef0ee4], - [0xc6e00bf3, 0x3da88fc2], [0xd5a79147, 0x930aa725], - [0x06ca6351, 0xe003826f], [0x14292967, 0x0a0e6e70], - [0x27b70a85, 0x46d22ffc], [0x2e1b2138, 0x5c26c926], - [0x4d2c6dfc, 0x5ac42aed], [0x53380d13, 0x9d95b3df], - [0x650a7354, 0x8baf63de], [0x766a0abb, 0x3c77b2a8], - [0x81c2c92e, 0x47edaee6], [0x92722c85, 0x1482353b], - [0xa2bfe8a1, 0x4cf10364], [0xa81a664b, 0xbc423001], - [0xc24b8b70, 0xd0f89791], [0xc76c51a3, 0x0654be30], - [0xd192e819, 0xd6ef5218], [0xd6990624, 0x5565a910], - [0xf40e3585, 0x5771202a], [0x106aa070, 0x32bbd1b8], - [0x19a4c116, 0xb8d2d0c8], [0x1e376c08, 0x5141ab53], - [0x2748774c, 0xdf8eeb99], [0x34b0bcb5, 0xe19b48a8], - [0x391c0cb3, 0xc5c95a63], [0x4ed8aa4a, 0xe3418acb], - [0x5b9cca4f, 0x7763e373], [0x682e6ff3, 0xd6b2b8a3], - [0x748f82ee, 0x5defb2fc], [0x78a5636f, 0x43172f60], - [0x84c87814, 0xa1f0ab72], [0x8cc70208, 0x1a6439ec], - [0x90befffa, 0x23631e28], [0xa4506ceb, 0xde82bde9], - [0xbef9a3f7, 0xb2c67915], [0xc67178f2, 0xe372532b], - [0xca273ece, 0xea26619c], [0xd186b8c7, 0x21c0c207], - [0xeada7dd6, 0xcde0eb1e], [0xf57d4f7f, 0xee6ed178], - [0x06f067aa, 0x72176fba], [0x0a637dc5, 0xa2c898a6], - [0x113f9804, 0xbef90dae], [0x1b710b35, 0x131c471b], - [0x28db77f5, 0x23047d84], [0x32caab7b, 0x40c72493], - [0x3c9ebe0a, 0x15c9bebc], [0x431d67c4, 0x9c100d4c], - [0x4cc5d4be, 0xcb3e42b6], [0x597f299c, 0xfc657e2a], - [0x5fcb6fab, 0x3ad6faec], [0x6c44198c, 0x4a475817] - ]; - - // initial hash states - _states = {}; - _states['SHA-512'] = [ - [0x6a09e667, 0xf3bcc908], - [0xbb67ae85, 0x84caa73b], - [0x3c6ef372, 0xfe94f82b], - [0xa54ff53a, 0x5f1d36f1], - [0x510e527f, 0xade682d1], - [0x9b05688c, 0x2b3e6c1f], - [0x1f83d9ab, 0xfb41bd6b], - [0x5be0cd19, 0x137e2179] - ]; - _states['SHA-384'] = [ - [0xcbbb9d5d, 0xc1059ed8], - [0x629a292a, 0x367cd507], - [0x9159015a, 0x3070dd17], - [0x152fecd8, 0xf70e5939], - [0x67332667, 0xffc00b31], - [0x8eb44a87, 0x68581511], - [0xdb0c2e0d, 0x64f98fa7], - [0x47b5481d, 0xbefa4fa4] - ]; - _states['SHA-512/256'] = [ - [0x22312194, 0xFC2BF72C], - [0x9F555FA3, 0xC84C64C2], - [0x2393B86B, 0x6F53B151], - [0x96387719, 0x5940EABD], - [0x96283EE2, 0xA88EFFE3], - [0xBE5E1E25, 0x53863992], - [0x2B0199FC, 0x2C85B8AA], - [0x0EB72DDC, 0x81C52CA2] - ]; - _states['SHA-512/224'] = [ - [0x8C3D37C8, 0x19544DA2], - [0x73E19966, 0x89DCD4D6], - [0x1DFAB7AE, 0x32FF9C82], - [0x679DD514, 0x582F9FCF], - [0x0F6D2B69, 0x7BD44DA8], - [0x77E36F73, 0x04C48942], - [0x3F9D85A8, 0x6A1D36C8], - [0x1112E6AD, 0x91D692A1] - ]; - - // now initialized - _initialized = true; -} - -/** - * Updates a SHA-512 state with the given byte buffer. - * - * @param s the SHA-512 state to update. - * @param w the array to use to store words. - * @param bytes the byte buffer to update with. - */ -function _update(s, w, bytes) { - // consume 512 bit (128 byte) chunks - var t1_hi, t1_lo; - var t2_hi, t2_lo; - var s0_hi, s0_lo; - var s1_hi, s1_lo; - var ch_hi, ch_lo; - var maj_hi, maj_lo; - var a_hi, a_lo; - var b_hi, b_lo; - var c_hi, c_lo; - var d_hi, d_lo; - var e_hi, e_lo; - var f_hi, f_lo; - var g_hi, g_lo; - var h_hi, h_lo; - var i, hi, lo, w2, w7, w15, w16; - var len = bytes.length(); - while(len >= 128) { - // the w array will be populated with sixteen 64-bit big-endian words - // and then extended into 64 64-bit words according to SHA-512 - for(i = 0; i < 16; ++i) { - w[i][0] = bytes.getInt32() >>> 0; - w[i][1] = bytes.getInt32() >>> 0; - } - for(; i < 80; ++i) { - // for word 2 words ago: ROTR 19(x) ^ ROTR 61(x) ^ SHR 6(x) - w2 = w[i - 2]; - hi = w2[0]; - lo = w2[1]; - - // high bits - t1_hi = ( - ((hi >>> 19) | (lo << 13)) ^ // ROTR 19 - ((lo >>> 29) | (hi << 3)) ^ // ROTR 61/(swap + ROTR 29) - (hi >>> 6)) >>> 0; // SHR 6 - // low bits - t1_lo = ( - ((hi << 13) | (lo >>> 19)) ^ // ROTR 19 - ((lo << 3) | (hi >>> 29)) ^ // ROTR 61/(swap + ROTR 29) - ((hi << 26) | (lo >>> 6))) >>> 0; // SHR 6 - - // for word 15 words ago: ROTR 1(x) ^ ROTR 8(x) ^ SHR 7(x) - w15 = w[i - 15]; - hi = w15[0]; - lo = w15[1]; - - // high bits - t2_hi = ( - ((hi >>> 1) | (lo << 31)) ^ // ROTR 1 - ((hi >>> 8) | (lo << 24)) ^ // ROTR 8 - (hi >>> 7)) >>> 0; // SHR 7 - // low bits - t2_lo = ( - ((hi << 31) | (lo >>> 1)) ^ // ROTR 1 - ((hi << 24) | (lo >>> 8)) ^ // ROTR 8 - ((hi << 25) | (lo >>> 7))) >>> 0; // SHR 7 - - // sum(t1, word 7 ago, t2, word 16 ago) modulo 2^64 (carry lo overflow) - w7 = w[i - 7]; - w16 = w[i - 16]; - lo = (t1_lo + w7[1] + t2_lo + w16[1]); - w[i][0] = (t1_hi + w7[0] + t2_hi + w16[0] + - ((lo / 0x100000000) >>> 0)) >>> 0; - w[i][1] = lo >>> 0; - } - - // initialize hash value for this chunk - a_hi = s[0][0]; - a_lo = s[0][1]; - b_hi = s[1][0]; - b_lo = s[1][1]; - c_hi = s[2][0]; - c_lo = s[2][1]; - d_hi = s[3][0]; - d_lo = s[3][1]; - e_hi = s[4][0]; - e_lo = s[4][1]; - f_hi = s[5][0]; - f_lo = s[5][1]; - g_hi = s[6][0]; - g_lo = s[6][1]; - h_hi = s[7][0]; - h_lo = s[7][1]; - - // round function - for(i = 0; i < 80; ++i) { - // Sum1(e) = ROTR 14(e) ^ ROTR 18(e) ^ ROTR 41(e) - s1_hi = ( - ((e_hi >>> 14) | (e_lo << 18)) ^ // ROTR 14 - ((e_hi >>> 18) | (e_lo << 14)) ^ // ROTR 18 - ((e_lo >>> 9) | (e_hi << 23))) >>> 0; // ROTR 41/(swap + ROTR 9) - s1_lo = ( - ((e_hi << 18) | (e_lo >>> 14)) ^ // ROTR 14 - ((e_hi << 14) | (e_lo >>> 18)) ^ // ROTR 18 - ((e_lo << 23) | (e_hi >>> 9))) >>> 0; // ROTR 41/(swap + ROTR 9) - - // Ch(e, f, g) (optimized the same way as SHA-1) - ch_hi = (g_hi ^ (e_hi & (f_hi ^ g_hi))) >>> 0; - ch_lo = (g_lo ^ (e_lo & (f_lo ^ g_lo))) >>> 0; - - // Sum0(a) = ROTR 28(a) ^ ROTR 34(a) ^ ROTR 39(a) - s0_hi = ( - ((a_hi >>> 28) | (a_lo << 4)) ^ // ROTR 28 - ((a_lo >>> 2) | (a_hi << 30)) ^ // ROTR 34/(swap + ROTR 2) - ((a_lo >>> 7) | (a_hi << 25))) >>> 0; // ROTR 39/(swap + ROTR 7) - s0_lo = ( - ((a_hi << 4) | (a_lo >>> 28)) ^ // ROTR 28 - ((a_lo << 30) | (a_hi >>> 2)) ^ // ROTR 34/(swap + ROTR 2) - ((a_lo << 25) | (a_hi >>> 7))) >>> 0; // ROTR 39/(swap + ROTR 7) - - // Maj(a, b, c) (optimized the same way as SHA-1) - maj_hi = ((a_hi & b_hi) | (c_hi & (a_hi ^ b_hi))) >>> 0; - maj_lo = ((a_lo & b_lo) | (c_lo & (a_lo ^ b_lo))) >>> 0; - - // main algorithm - // t1 = (h + s1 + ch + _k[i] + _w[i]) modulo 2^64 (carry lo overflow) - lo = (h_lo + s1_lo + ch_lo + _k[i][1] + w[i][1]); - t1_hi = (h_hi + s1_hi + ch_hi + _k[i][0] + w[i][0] + - ((lo / 0x100000000) >>> 0)) >>> 0; - t1_lo = lo >>> 0; - - // t2 = s0 + maj modulo 2^64 (carry lo overflow) - lo = s0_lo + maj_lo; - t2_hi = (s0_hi + maj_hi + ((lo / 0x100000000) >>> 0)) >>> 0; - t2_lo = lo >>> 0; - - h_hi = g_hi; - h_lo = g_lo; - - g_hi = f_hi; - g_lo = f_lo; - - f_hi = e_hi; - f_lo = e_lo; - - // e = (d + t1) modulo 2^64 (carry lo overflow) - lo = d_lo + t1_lo; - e_hi = (d_hi + t1_hi + ((lo / 0x100000000) >>> 0)) >>> 0; - e_lo = lo >>> 0; - - d_hi = c_hi; - d_lo = c_lo; - - c_hi = b_hi; - c_lo = b_lo; - - b_hi = a_hi; - b_lo = a_lo; - - // a = (t1 + t2) modulo 2^64 (carry lo overflow) - lo = t1_lo + t2_lo; - a_hi = (t1_hi + t2_hi + ((lo / 0x100000000) >>> 0)) >>> 0; - a_lo = lo >>> 0; - } - - // update hash state (additional modulo 2^64) - lo = s[0][1] + a_lo; - s[0][0] = (s[0][0] + a_hi + ((lo / 0x100000000) >>> 0)) >>> 0; - s[0][1] = lo >>> 0; - - lo = s[1][1] + b_lo; - s[1][0] = (s[1][0] + b_hi + ((lo / 0x100000000) >>> 0)) >>> 0; - s[1][1] = lo >>> 0; - - lo = s[2][1] + c_lo; - s[2][0] = (s[2][0] + c_hi + ((lo / 0x100000000) >>> 0)) >>> 0; - s[2][1] = lo >>> 0; - - lo = s[3][1] + d_lo; - s[3][0] = (s[3][0] + d_hi + ((lo / 0x100000000) >>> 0)) >>> 0; - s[3][1] = lo >>> 0; - - lo = s[4][1] + e_lo; - s[4][0] = (s[4][0] + e_hi + ((lo / 0x100000000) >>> 0)) >>> 0; - s[4][1] = lo >>> 0; - - lo = s[5][1] + f_lo; - s[5][0] = (s[5][0] + f_hi + ((lo / 0x100000000) >>> 0)) >>> 0; - s[5][1] = lo >>> 0; - - lo = s[6][1] + g_lo; - s[6][0] = (s[6][0] + g_hi + ((lo / 0x100000000) >>> 0)) >>> 0; - s[6][1] = lo >>> 0; - - lo = s[7][1] + h_lo; - s[7][0] = (s[7][0] + h_hi + ((lo / 0x100000000) >>> 0)) >>> 0; - s[7][1] = lo >>> 0; - - len -= 128; - } -} - -} // end module implementation - -/* ########## Begin module wrapper ########## */ -var name = 'sha512'; -if(typeof define !== 'function') { - // NodeJS -> AMD - if(typeof module === 'object' && module.exports) { - var nodeJS = true; - define = function(ids, factory) { - factory(require, module); - }; - } else { - // <script> - if(typeof forge === 'undefined') { - forge = {}; - } - return initModule(forge); - } -} -// AMD -var deps; -var defineFunc = function(require, module) { - module.exports = function(forge) { - var mods = deps.map(function(dep) { - return require(dep); - }).concat(initModule); - // handle circular dependencies - forge = forge || {}; - forge.defined = forge.defined || {}; - if(forge.defined[name]) { - return forge[name]; - } - forge.defined[name] = true; - for(var i = 0; i < mods.length; ++i) { - mods[i](forge); - } - return forge[name]; - }; -}; -var tmpDefine = define; -define = function(ids, factory) { - deps = (typeof ids === 'string') ? factory.slice(2) : ids.slice(2); - if(nodeJS) { - delete define; - return tmpDefine.apply(null, Array.prototype.slice.call(arguments, 0)); - } - define = tmpDefine; - return define.apply(null, Array.prototype.slice.call(arguments, 0)); -}; -define(['require', 'module', './util'], function() { - defineFunc.apply(null, Array.prototype.slice.call(arguments, 0)); -}); -})(); diff --git a/alarm/node_modules/node-forge/js/socket.js b/alarm/node_modules/node-forge/js/socket.js deleted file mode 100644 index e50e1aa..0000000 --- a/alarm/node_modules/node-forge/js/socket.js +++ /dev/null @@ -1,342 +0,0 @@ -/** - * Socket implementation that uses flash SocketPool class as a backend. - * - * @author Dave Longley - * - * Copyright (c) 2010-2013 Digital Bazaar, Inc. - */ -(function() { -/* ########## Begin module implementation ########## */ -function initModule(forge) { - -// define net namespace -var net = forge.net = forge.net || {}; - -// map of flash ID to socket pool -net.socketPools = {}; - -/** - * Creates a flash socket pool. - * - * @param options: - * flashId: the dom ID for the flash object element. - * policyPort: the default policy port for sockets, 0 to use the - * flash default. - * policyUrl: the default policy file URL for sockets (if provided - * used instead of a policy port). - * msie: true if the browser is msie, false if not. - * - * @return the created socket pool. - */ -net.createSocketPool = function(options) { - // set default - options.msie = options.msie || false; - - // initialize the flash interface - var spId = options.flashId; - var api = document.getElementById(spId); - api.init({marshallExceptions: !options.msie}); - - // create socket pool entry - var sp = { - // ID of the socket pool - id: spId, - // flash interface - flashApi: api, - // map of socket ID to sockets - sockets: {}, - // default policy port - policyPort: options.policyPort || 0, - // default policy URL - policyUrl: options.policyUrl || null - }; - net.socketPools[spId] = sp; - - // create event handler, subscribe to flash events - if(options.msie === true) { - sp.handler = function(e) { - if(e.id in sp.sockets) { - // get handler function - var f; - switch(e.type) { - case 'connect': - f = 'connected'; - break; - case 'close': - f = 'closed'; - break; - case 'socketData': - f = 'data'; - break; - default: - f = 'error'; - break; - } - /* IE calls javascript on the thread of the external object - that triggered the event (in this case flash) ... which will - either run concurrently with other javascript or pre-empt any - running javascript in the middle of its execution (BAD!) ... - calling setTimeout() will schedule the javascript to run on - the javascript thread and solve this EVIL problem. */ - setTimeout(function(){sp.sockets[e.id][f](e);}, 0); - } - }; - } else { - sp.handler = function(e) { - if(e.id in sp.sockets) { - // get handler function - var f; - switch(e.type) { - case 'connect': - f = 'connected'; - break; - case 'close': - f = 'closed'; - break; - case 'socketData': - f = 'data'; - break; - default: - f = 'error'; - break; - } - sp.sockets[e.id][f](e); - } - }; - } - var handler = 'forge.net.socketPools[\'' + spId + '\'].handler'; - api.subscribe('connect', handler); - api.subscribe('close', handler); - api.subscribe('socketData', handler); - api.subscribe('ioError', handler); - api.subscribe('securityError', handler); - - /** - * Destroys a socket pool. The socket pool still needs to be cleaned - * up via net.cleanup(). - */ - sp.destroy = function() { - delete net.socketPools[options.flashId]; - for(var id in sp.sockets) { - sp.sockets[id].destroy(); - } - sp.sockets = {}; - api.cleanup(); - }; - - /** - * Creates a new socket. - * - * @param options: - * connected: function(event) called when the socket connects. - * closed: function(event) called when the socket closes. - * data: function(event) called when socket data has arrived, - * it can be read from the socket using receive(). - * error: function(event) called when a socket error occurs. - */ - sp.createSocket = function(options) { - // default to empty options - options = options || {}; - - // create flash socket - var id = api.create(); - - // create javascript socket wrapper - var socket = { - id: id, - // set handlers - connected: options.connected || function(e){}, - closed: options.closed || function(e){}, - data: options.data || function(e){}, - error: options.error || function(e){} - }; - - /** - * Destroys this socket. - */ - socket.destroy = function() { - api.destroy(id); - delete sp.sockets[id]; - }; - - /** - * Connects this socket. - * - * @param options: - * host: the host to connect to. - * port: the port to connect to. - * policyPort: the policy port to use (if non-default), 0 to - * use the flash default. - * policyUrl: the policy file URL to use (instead of port). - */ - socket.connect = function(options) { - // give precedence to policy URL over policy port - // if no policy URL and passed port isn't 0, use default port, - // otherwise use 0 for the port - var policyUrl = options.policyUrl || null; - var policyPort = 0; - if(policyUrl === null && options.policyPort !== 0) { - policyPort = options.policyPort || sp.policyPort; - } - api.connect(id, options.host, options.port, policyPort, policyUrl); - }; - - /** - * Closes this socket. - */ - socket.close = function() { - api.close(id); - socket.closed({ - id: socket.id, - type: 'close', - bytesAvailable: 0 - }); - }; - - /** - * Determines if the socket is connected or not. - * - * @return true if connected, false if not. - */ - socket.isConnected = function() { - return api.isConnected(id); - }; - - /** - * Writes bytes to this socket. - * - * @param bytes the bytes (as a string) to write. - * - * @return true on success, false on failure. - */ - socket.send = function(bytes) { - return api.send(id, forge.util.encode64(bytes)); - }; - - /** - * Reads bytes from this socket (non-blocking). Fewer than the number - * of bytes requested may be read if enough bytes are not available. - * - * This method should be called from the data handler if there are - * enough bytes available. To see how many bytes are available, check - * the 'bytesAvailable' property on the event in the data handler or - * call the bytesAvailable() function on the socket. If the browser is - * msie, then the bytesAvailable() function should be used to avoid - * race conditions. Otherwise, using the property on the data handler's - * event may be quicker. - * - * @param count the maximum number of bytes to read. - * - * @return the bytes read (as a string) or null on error. - */ - socket.receive = function(count) { - var rval = api.receive(id, count).rval; - return (rval === null) ? null : forge.util.decode64(rval); - }; - - /** - * Gets the number of bytes available for receiving on the socket. - * - * @return the number of bytes available for receiving. - */ - socket.bytesAvailable = function() { - return api.getBytesAvailable(id); - }; - - // store and return socket - sp.sockets[id] = socket; - return socket; - }; - - return sp; -}; - -/** - * Destroys a flash socket pool. - * - * @param options: - * flashId: the dom ID for the flash object element. - */ -net.destroySocketPool = function(options) { - if(options.flashId in net.socketPools) { - var sp = net.socketPools[options.flashId]; - sp.destroy(); - } -}; - -/** - * Creates a new socket. - * - * @param options: - * flashId: the dom ID for the flash object element. - * connected: function(event) called when the socket connects. - * closed: function(event) called when the socket closes. - * data: function(event) called when socket data has arrived, it - * can be read from the socket using receive(). - * error: function(event) called when a socket error occurs. - * - * @return the created socket. - */ -net.createSocket = function(options) { - var socket = null; - if(options.flashId in net.socketPools) { - // get related socket pool - var sp = net.socketPools[options.flashId]; - socket = sp.createSocket(options); - } - return socket; -}; - -} // end module implementation - -/* ########## Begin module wrapper ########## */ -var name = 'net'; -if(typeof define !== 'function') { - // NodeJS -> AMD - if(typeof module === 'object' && module.exports) { - var nodeJS = true; - define = function(ids, factory) { - factory(require, module); - }; - } else { - // <script> - if(typeof forge === 'undefined') { - forge = {}; - } - return initModule(forge); - } -} -// AMD -var deps; -var defineFunc = function(require, module) { - module.exports = function(forge) { - var mods = deps.map(function(dep) { - return require(dep); - }).concat(initModule); - // handle circular dependencies - forge = forge || {}; - forge.defined = forge.defined || {}; - if(forge.defined[name]) { - return forge[name]; - } - forge.defined[name] = true; - for(var i = 0; i < mods.length; ++i) { - mods[i](forge); - } - return forge[name]; - }; -}; -var tmpDefine = define; -define = function(ids, factory) { - deps = (typeof ids === 'string') ? factory.slice(2) : ids.slice(2); - if(nodeJS) { - delete define; - return tmpDefine.apply(null, Array.prototype.slice.call(arguments, 0)); - } - define = tmpDefine; - return define.apply(null, Array.prototype.slice.call(arguments, 0)); -}; -define(['require', 'module'], function() { - defineFunc.apply(null, Array.prototype.slice.call(arguments, 0)); -}); -})(); diff --git a/alarm/node_modules/node-forge/js/ssh.js b/alarm/node_modules/node-forge/js/ssh.js deleted file mode 100644 index ef76c82..0000000 --- a/alarm/node_modules/node-forge/js/ssh.js +++ /dev/null @@ -1,295 +0,0 @@ -/** - * Functions to output keys in SSH-friendly formats. - * - * This is part of the Forge project which may be used under the terms of - * either the BSD License or the GNU General Public License (GPL) Version 2. - * - * See: https://github.com/digitalbazaar/forge/blob/cbebca3780658703d925b61b2caffb1d263a6c1d/LICENSE - * - * @author https://github.com/shellac - */ -(function() { -/* ########## Begin module implementation ########## */ -function initModule(forge) { - -var ssh = forge.ssh = forge.ssh || {}; - -/** - * Encodes (and optionally encrypts) a private RSA key as a Putty PPK file. - * - * @param privateKey the key. - * @param passphrase a passphrase to protect the key (falsy for no encryption). - * @param comment a comment to include in the key file. - * - * @return the PPK file as a string. - */ -ssh.privateKeyToPutty = function(privateKey, passphrase, comment) { - comment = comment || ''; - passphrase = passphrase || ''; - var algorithm = 'ssh-rsa'; - var encryptionAlgorithm = (passphrase === '') ? 'none' : 'aes256-cbc'; - - var ppk = 'PuTTY-User-Key-File-2: ' + algorithm + '\r\n'; - ppk += 'Encryption: ' + encryptionAlgorithm + '\r\n'; - ppk += 'Comment: ' + comment + '\r\n'; - - // public key into buffer for ppk - var pubbuffer = forge.util.createBuffer(); - _addStringToBuffer(pubbuffer, algorithm); - _addBigIntegerToBuffer(pubbuffer, privateKey.e); - _addBigIntegerToBuffer(pubbuffer, privateKey.n); - - // write public key - var pub = forge.util.encode64(pubbuffer.bytes(), 64); - var length = Math.floor(pub.length / 66) + 1; // 66 = 64 + \r\n - ppk += 'Public-Lines: ' + length + '\r\n'; - ppk += pub; - - // private key into a buffer - var privbuffer = forge.util.createBuffer(); - _addBigIntegerToBuffer(privbuffer, privateKey.d); - _addBigIntegerToBuffer(privbuffer, privateKey.p); - _addBigIntegerToBuffer(privbuffer, privateKey.q); - _addBigIntegerToBuffer(privbuffer, privateKey.qInv); - - // optionally encrypt the private key - var priv; - if(!passphrase) { - // use the unencrypted buffer - priv = forge.util.encode64(privbuffer.bytes(), 64); - } else { - // encrypt RSA key using passphrase - var encLen = privbuffer.length() + 16 - 1; - encLen -= encLen % 16; - - // pad private key with sha1-d data -- needs to be a multiple of 16 - var padding = _sha1(privbuffer.bytes()); - - padding.truncate(padding.length() - encLen + privbuffer.length()); - privbuffer.putBuffer(padding); - - var aeskey = forge.util.createBuffer(); - aeskey.putBuffer(_sha1('\x00\x00\x00\x00', passphrase)); - aeskey.putBuffer(_sha1('\x00\x00\x00\x01', passphrase)); - - // encrypt some bytes using CBC mode - // key is 40 bytes, so truncate *by* 8 bytes - var cipher = forge.aes.createEncryptionCipher(aeskey.truncate(8), 'CBC'); - cipher.start(forge.util.createBuffer().fillWithByte(0, 16)); - cipher.update(privbuffer.copy()); - cipher.finish(); - var encrypted = cipher.output; - - // Note: this appears to differ from Putty -- is forge wrong, or putty? - // due to padding we finish as an exact multiple of 16 - encrypted.truncate(16); // all padding - - priv = forge.util.encode64(encrypted.bytes(), 64); - } - - // output private key - length = Math.floor(priv.length / 66) + 1; // 64 + \r\n - ppk += '\r\nPrivate-Lines: ' + length + '\r\n'; - ppk += priv; - - // MAC - var mackey = _sha1('putty-private-key-file-mac-key', passphrase); - - var macbuffer = forge.util.createBuffer(); - _addStringToBuffer(macbuffer, algorithm); - _addStringToBuffer(macbuffer, encryptionAlgorithm); - _addStringToBuffer(macbuffer, comment); - macbuffer.putInt32(pubbuffer.length()); - macbuffer.putBuffer(pubbuffer); - macbuffer.putInt32(privbuffer.length()); - macbuffer.putBuffer(privbuffer); - - var hmac = forge.hmac.create(); - hmac.start('sha1', mackey); - hmac.update(macbuffer.bytes()); - - ppk += '\r\nPrivate-MAC: ' + hmac.digest().toHex() + '\r\n'; - - return ppk; -}; - -/** - * Encodes a public RSA key as an OpenSSH file. - * - * @param key the key. - * @param comment a comment. - * - * @return the public key in OpenSSH format. - */ -ssh.publicKeyToOpenSSH = function(key, comment) { - var type = 'ssh-rsa'; - comment = comment || ''; - - var buffer = forge.util.createBuffer(); - _addStringToBuffer(buffer, type); - _addBigIntegerToBuffer(buffer, key.e); - _addBigIntegerToBuffer(buffer, key.n); - - return type + ' ' + forge.util.encode64(buffer.bytes()) + ' ' + comment; -}; - -/** - * Encodes a private RSA key as an OpenSSH file. - * - * @param key the key. - * @param passphrase a passphrase to protect the key (falsy for no encryption). - * - * @return the public key in OpenSSH format. - */ -ssh.privateKeyToOpenSSH = function(privateKey, passphrase) { - if(!passphrase) { - return forge.pki.privateKeyToPem(privateKey); - } - // OpenSSH private key is just a legacy format, it seems - return forge.pki.encryptRsaPrivateKey(privateKey, passphrase, - {legacy: true, algorithm: 'aes128'}); -}; - -/** - * Gets the SSH fingerprint for the given public key. - * - * @param options the options to use. - * [md] the message digest object to use (defaults to forge.md.md5). - * [encoding] an alternative output encoding, such as 'hex' - * (defaults to none, outputs a byte buffer). - * [delimiter] the delimiter to use between bytes for 'hex' encoded - * output, eg: ':' (defaults to none). - * - * @return the fingerprint as a byte buffer or other encoding based on options. - */ -ssh.getPublicKeyFingerprint = function(key, options) { - options = options || {}; - var md = options.md || forge.md.md5.create(); - - var type = 'ssh-rsa'; - var buffer = forge.util.createBuffer(); - _addStringToBuffer(buffer, type); - _addBigIntegerToBuffer(buffer, key.e); - _addBigIntegerToBuffer(buffer, key.n); - - // hash public key bytes - md.start(); - md.update(buffer.getBytes()); - var digest = md.digest(); - if(options.encoding === 'hex') { - var hex = digest.toHex(); - if(options.delimiter) { - return hex.match(/.{2}/g).join(options.delimiter); - } - return hex; - } else if(options.encoding === 'binary') { - return digest.getBytes(); - } else if(options.encoding) { - throw new Error('Unknown encoding "' + options.encoding + '".'); - } - return digest; -}; - -/** - * Adds len(val) then val to a buffer. - * - * @param buffer the buffer to add to. - * @param val a big integer. - */ -function _addBigIntegerToBuffer(buffer, val) { - var hexVal = val.toString(16); - // ensure 2s complement +ve - if(hexVal[0] >= '8') { - hexVal = '00' + hexVal; - } - var bytes = forge.util.hexToBytes(hexVal); - buffer.putInt32(bytes.length); - buffer.putBytes(bytes); -} - -/** - * Adds len(val) then val to a buffer. - * - * @param buffer the buffer to add to. - * @param val a string. - */ -function _addStringToBuffer(buffer, val) { - buffer.putInt32(val.length); - buffer.putString(val); -} - -/** - * Hashes the arguments into one value using SHA-1. - * - * @return the sha1 hash of the provided arguments. - */ -function _sha1() { - var sha = forge.md.sha1.create(); - var num = arguments.length; - for (var i = 0; i < num; ++i) { - sha.update(arguments[i]); - } - return sha.digest(); -} - -} // end module implementation - -/* ########## Begin module wrapper ########## */ -var name = 'ssh'; -if(typeof define !== 'function') { - // NodeJS -> AMD - if(typeof module === 'object' && module.exports) { - var nodeJS = true; - define = function(ids, factory) { - factory(require, module); - }; - } else { - // <script> - if(typeof forge === 'undefined') { - forge = {}; - } - return initModule(forge); - } -} -// AMD -var deps; -var defineFunc = function(require, module) { - module.exports = function(forge) { - var mods = deps.map(function(dep) { - return require(dep); - }).concat(initModule); - // handle circular dependencies - forge = forge || {}; - forge.defined = forge.defined || {}; - if(forge.defined[name]) { - return forge[name]; - } - forge.defined[name] = true; - for(var i = 0; i < mods.length; ++i) { - mods[i](forge); - } - return forge[name]; - }; -}; -var tmpDefine = define; -define = function(ids, factory) { - deps = (typeof ids === 'string') ? factory.slice(2) : ids.slice(2); - if(nodeJS) { - delete define; - return tmpDefine.apply(null, Array.prototype.slice.call(arguments, 0)); - } - define = tmpDefine; - return define.apply(null, Array.prototype.slice.call(arguments, 0)); -}; -define([ - 'require', - 'module', - './aes', - './hmac', - './md5', - './sha1', - './util' -], function() { - defineFunc.apply(null, Array.prototype.slice.call(arguments, 0)); -}); -})(); diff --git a/alarm/node_modules/node-forge/js/task.js b/alarm/node_modules/node-forge/js/task.js deleted file mode 100644 index f49bbf7..0000000 --- a/alarm/node_modules/node-forge/js/task.js +++ /dev/null @@ -1,778 +0,0 @@ -/** - * Support for concurrent task management and synchronization in web - * applications. - * - * @author Dave Longley - * @author David I. Lehn <dlehn@digitalbazaar.com> - * - * Copyright (c) 2009-2013 Digital Bazaar, Inc. - */ -(function() { -/* ########## Begin module implementation ########## */ -function initModule(forge) { - -// logging category -var cat = 'forge.task'; - -// verbose level -// 0: off, 1: a little, 2: a whole lot -// Verbose debug logging is surrounded by a level check to avoid the -// performance issues with even calling the logging code regardless if it -// is actually logged. For performance reasons this should not be set to 2 -// for production use. -// ex: if(sVL >= 2) forge.log.verbose(....) -var sVL = 0; - -// track tasks for debugging -var sTasks = {}; -var sNextTaskId = 0; -// debug access -forge.debug.set(cat, 'tasks', sTasks); - -// a map of task type to task queue -var sTaskQueues = {}; -// debug access -forge.debug.set(cat, 'queues', sTaskQueues); - -// name for unnamed tasks -var sNoTaskName = '?'; - -// maximum number of doNext() recursions before a context swap occurs -// FIXME: might need to tweak this based on the browser -var sMaxRecursions = 30; - -// time slice for doing tasks before a context swap occurs -// FIXME: might need to tweak this based on the browser -var sTimeSlice = 20; - -/** - * Task states. - * - * READY: ready to start processing - * RUNNING: task or a subtask is running - * BLOCKED: task is waiting to acquire N permits to continue - * SLEEPING: task is sleeping for a period of time - * DONE: task is done - * ERROR: task has an error - */ -var READY = 'ready'; -var RUNNING = 'running'; -var BLOCKED = 'blocked'; -var SLEEPING = 'sleeping'; -var DONE = 'done'; -var ERROR = 'error'; - -/** - * Task actions. Used to control state transitions. - * - * STOP: stop processing - * START: start processing tasks - * BLOCK: block task from continuing until 1 or more permits are released - * UNBLOCK: release one or more permits - * SLEEP: sleep for a period of time - * WAKEUP: wakeup early from SLEEPING state - * CANCEL: cancel further tasks - * FAIL: a failure occured - */ -var STOP = 'stop'; -var START = 'start'; -var BLOCK = 'block'; -var UNBLOCK = 'unblock'; -var SLEEP = 'sleep'; -var WAKEUP = 'wakeup'; -var CANCEL = 'cancel'; -var FAIL = 'fail'; - -/** - * State transition table. - * - * nextState = sStateTable[currentState][action] - */ -var sStateTable = {}; - -sStateTable[READY] = {}; -sStateTable[READY][STOP] = READY; -sStateTable[READY][START] = RUNNING; -sStateTable[READY][CANCEL] = DONE; -sStateTable[READY][FAIL] = ERROR; - -sStateTable[RUNNING] = {}; -sStateTable[RUNNING][STOP] = READY; -sStateTable[RUNNING][START] = RUNNING; -sStateTable[RUNNING][BLOCK] = BLOCKED; -sStateTable[RUNNING][UNBLOCK] = RUNNING; -sStateTable[RUNNING][SLEEP] = SLEEPING; -sStateTable[RUNNING][WAKEUP] = RUNNING; -sStateTable[RUNNING][CANCEL] = DONE; -sStateTable[RUNNING][FAIL] = ERROR; - -sStateTable[BLOCKED] = {}; -sStateTable[BLOCKED][STOP] = BLOCKED; -sStateTable[BLOCKED][START] = BLOCKED; -sStateTable[BLOCKED][BLOCK] = BLOCKED; -sStateTable[BLOCKED][UNBLOCK] = BLOCKED; -sStateTable[BLOCKED][SLEEP] = BLOCKED; -sStateTable[BLOCKED][WAKEUP] = BLOCKED; -sStateTable[BLOCKED][CANCEL] = DONE; -sStateTable[BLOCKED][FAIL] = ERROR; - -sStateTable[SLEEPING] = {}; -sStateTable[SLEEPING][STOP] = SLEEPING; -sStateTable[SLEEPING][START] = SLEEPING; -sStateTable[SLEEPING][BLOCK] = SLEEPING; -sStateTable[SLEEPING][UNBLOCK] = SLEEPING; -sStateTable[SLEEPING][SLEEP] = SLEEPING; -sStateTable[SLEEPING][WAKEUP] = SLEEPING; -sStateTable[SLEEPING][CANCEL] = DONE; -sStateTable[SLEEPING][FAIL] = ERROR; - -sStateTable[DONE] = {}; -sStateTable[DONE][STOP] = DONE; -sStateTable[DONE][START] = DONE; -sStateTable[DONE][BLOCK] = DONE; -sStateTable[DONE][UNBLOCK] = DONE; -sStateTable[DONE][SLEEP] = DONE; -sStateTable[DONE][WAKEUP] = DONE; -sStateTable[DONE][CANCEL] = DONE; -sStateTable[DONE][FAIL] = ERROR; - -sStateTable[ERROR] = {}; -sStateTable[ERROR][STOP] = ERROR; -sStateTable[ERROR][START] = ERROR; -sStateTable[ERROR][BLOCK] = ERROR; -sStateTable[ERROR][UNBLOCK] = ERROR; -sStateTable[ERROR][SLEEP] = ERROR; -sStateTable[ERROR][WAKEUP] = ERROR; -sStateTable[ERROR][CANCEL] = ERROR; -sStateTable[ERROR][FAIL] = ERROR; - -/** - * Creates a new task. - * - * @param options options for this task - * run: the run function for the task (required) - * name: the run function for the task (optional) - * parent: parent of this task (optional) - * - * @return the empty task. - */ -var Task = function(options) { - // task id - this.id = -1; - - // task name - this.name = options.name || sNoTaskName; - - // task has no parent - this.parent = options.parent || null; - - // save run function - this.run = options.run; - - // create a queue of subtasks to run - this.subtasks = []; - - // error flag - this.error = false; - - // state of the task - this.state = READY; - - // number of times the task has been blocked (also the number - // of permits needed to be released to continue running) - this.blocks = 0; - - // timeout id when sleeping - this.timeoutId = null; - - // no swap time yet - this.swapTime = null; - - // no user data - this.userData = null; - - // initialize task - // FIXME: deal with overflow - this.id = sNextTaskId++; - sTasks[this.id] = this; - if(sVL >= 1) { - forge.log.verbose(cat, '[%s][%s] init', this.id, this.name, this); - } -}; - -/** - * Logs debug information on this task and the system state. - */ -Task.prototype.debug = function(msg) { - msg = msg || ''; - forge.log.debug(cat, msg, - '[%s][%s] task:', this.id, this.name, this, - 'subtasks:', this.subtasks.length, - 'queue:', sTaskQueues); -}; - -/** - * Adds a subtask to run after task.doNext() or task.fail() is called. - * - * @param name human readable name for this task (optional). - * @param subrun a function to run that takes the current task as - * its first parameter. - * - * @return the current task (useful for chaining next() calls). - */ -Task.prototype.next = function(name, subrun) { - // juggle parameters if it looks like no name is given - if(typeof(name) === 'function') { - subrun = name; - - // inherit parent's name - name = this.name; - } - // create subtask, set parent to this task, propagate callbacks - var subtask = new Task({ - run: subrun, - name: name, - parent: this - }); - // start subtasks running - subtask.state = RUNNING; - subtask.type = this.type; - subtask.successCallback = this.successCallback || null; - subtask.failureCallback = this.failureCallback || null; - - // queue a new subtask - this.subtasks.push(subtask); - - return this; -}; - -/** - * Adds subtasks to run in parallel after task.doNext() or task.fail() - * is called. - * - * @param name human readable name for this task (optional). - * @param subrun functions to run that take the current task as - * their first parameter. - * - * @return the current task (useful for chaining next() calls). - */ -Task.prototype.parallel = function(name, subrun) { - // juggle parameters if it looks like no name is given - if(forge.util.isArray(name)) { - subrun = name; - - // inherit parent's name - name = this.name; - } - // Wrap parallel tasks in a regular task so they are started at the - // proper time. - return this.next(name, function(task) { - // block waiting for subtasks - var ptask = task; - ptask.block(subrun.length); - - // we pass the iterator from the loop below as a parameter - // to a function because it is otherwise included in the - // closure and changes as the loop changes -- causing i - // to always be set to its highest value - var startParallelTask = function(pname, pi) { - forge.task.start({ - type: pname, - run: function(task) { - subrun[pi](task); - }, - success: function(task) { - ptask.unblock(); - }, - failure: function(task) { - ptask.unblock(); - } - }); - }; - - for(var i = 0; i < subrun.length; i++) { - // Type must be unique so task starts in parallel: - // name + private string + task id + sub-task index - // start tasks in parallel and unblock when the finish - var pname = name + '__parallel-' + task.id + '-' + i; - var pi = i; - startParallelTask(pname, pi); - } - }); -}; - -/** - * Stops a running task. - */ -Task.prototype.stop = function() { - this.state = sStateTable[this.state][STOP]; -}; - -/** - * Starts running a task. - */ -Task.prototype.start = function() { - this.error = false; - this.state = sStateTable[this.state][START]; - - // try to restart - if(this.state === RUNNING) { - this.start = new Date(); - this.run(this); - runNext(this, 0); - } -}; - -/** - * Blocks a task until it one or more permits have been released. The - * task will not resume until the requested number of permits have - * been released with call(s) to unblock(). - * - * @param n number of permits to wait for(default: 1). - */ -Task.prototype.block = function(n) { - n = typeof(n) === 'undefined' ? 1 : n; - this.blocks += n; - if(this.blocks > 0) { - this.state = sStateTable[this.state][BLOCK]; - } -}; - -/** - * Releases a permit to unblock a task. If a task was blocked by - * requesting N permits via block(), then it will only continue - * running once enough permits have been released via unblock() calls. - * - * If multiple processes need to synchronize with a single task then - * use a condition variable (see forge.task.createCondition). It is - * an error to unblock a task more times than it has been blocked. - * - * @param n number of permits to release (default: 1). - * - * @return the current block count (task is unblocked when count is 0) - */ -Task.prototype.unblock = function(n) { - n = typeof(n) === 'undefined' ? 1 : n; - this.blocks -= n; - if(this.blocks === 0 && this.state !== DONE) { - this.state = RUNNING; - runNext(this, 0); - } - return this.blocks; -}; - -/** - * Sleep for a period of time before resuming tasks. - * - * @param n number of milliseconds to sleep (default: 0). - */ -Task.prototype.sleep = function(n) { - n = typeof(n) === 'undefined' ? 0 : n; - this.state = sStateTable[this.state][SLEEP]; - var self = this; - this.timeoutId = setTimeout(function() { - self.timeoutId = null; - self.state = RUNNING; - runNext(self, 0); - }, n); -}; - -/** - * Waits on a condition variable until notified. The next task will - * not be scheduled until notification. A condition variable can be - * created with forge.task.createCondition(). - * - * Once cond.notify() is called, the task will continue. - * - * @param cond the condition variable to wait on. - */ -Task.prototype.wait = function(cond) { - cond.wait(this); -}; - -/** - * If sleeping, wakeup and continue running tasks. - */ -Task.prototype.wakeup = function() { - if(this.state === SLEEPING) { - cancelTimeout(this.timeoutId); - this.timeoutId = null; - this.state = RUNNING; - runNext(this, 0); - } -}; - -/** - * Cancel all remaining subtasks of this task. - */ -Task.prototype.cancel = function() { - this.state = sStateTable[this.state][CANCEL]; - // remove permits needed - this.permitsNeeded = 0; - // cancel timeouts - if(this.timeoutId !== null) { - cancelTimeout(this.timeoutId); - this.timeoutId = null; - } - // remove subtasks - this.subtasks = []; -}; - -/** - * Finishes this task with failure and sets error flag. The entire - * task will be aborted unless the next task that should execute - * is passed as a parameter. This allows levels of subtasks to be - * skipped. For instance, to abort only this tasks's subtasks, then - * call fail(task.parent). To abort this task's subtasks and its - * parent's subtasks, call fail(task.parent.parent). To abort - * all tasks and simply call the task callback, call fail() or - * fail(null). - * - * The task callback (success or failure) will always, eventually, be - * called. - * - * @param next the task to continue at, or null to abort entirely. - */ -Task.prototype.fail = function(next) { - // set error flag - this.error = true; - - // finish task - finish(this, true); - - if(next) { - // propagate task info - next.error = this.error; - next.swapTime = this.swapTime; - next.userData = this.userData; - - // do next task as specified - runNext(next, 0); - } else { - if(this.parent !== null) { - // finish root task (ensures it is removed from task queue) - var parent = this.parent; - while(parent.parent !== null) { - // propagate task info - parent.error = this.error; - parent.swapTime = this.swapTime; - parent.userData = this.userData; - parent = parent.parent; - } - finish(parent, true); - } - - // call failure callback if one exists - if(this.failureCallback) { - this.failureCallback(this); - } - } -}; - -/** - * Asynchronously start a task. - * - * @param task the task to start. - */ -var start = function(task) { - task.error = false; - task.state = sStateTable[task.state][START]; - setTimeout(function() { - if(task.state === RUNNING) { - task.swapTime = +new Date(); - task.run(task); - runNext(task, 0); - } - }, 0); -}; - -/** - * Run the next subtask or finish this task. - * - * @param task the task to process. - * @param recurse the recursion count. - */ -var runNext = function(task, recurse) { - // get time since last context swap (ms), if enough time has passed set - // swap to true to indicate that doNext was performed asynchronously - // also, if recurse is too high do asynchronously - var swap = - (recurse > sMaxRecursions) || - (+new Date() - task.swapTime) > sTimeSlice; - - var doNext = function(recurse) { - recurse++; - if(task.state === RUNNING) { - if(swap) { - // update swap time - task.swapTime = +new Date(); - } - - if(task.subtasks.length > 0) { - // run next subtask - var subtask = task.subtasks.shift(); - subtask.error = task.error; - subtask.swapTime = task.swapTime; - subtask.userData = task.userData; - subtask.run(subtask); - if(!subtask.error) { - runNext(subtask, recurse); - } - } else { - finish(task); - - if(!task.error) { - // chain back up and run parent - if(task.parent !== null) { - // propagate task info - task.parent.error = task.error; - task.parent.swapTime = task.swapTime; - task.parent.userData = task.userData; - - // no subtasks left, call run next subtask on parent - runNext(task.parent, recurse); - } - } - } - } - }; - - if(swap) { - // we're swapping, so run asynchronously - setTimeout(doNext, 0); - } else { - // not swapping, so run synchronously - doNext(recurse); - } -}; - -/** - * Finishes a task and looks for the next task in the queue to start. - * - * @param task the task to finish. - * @param suppressCallbacks true to suppress callbacks. - */ -var finish = function(task, suppressCallbacks) { - // subtask is now done - task.state = DONE; - - delete sTasks[task.id]; - if(sVL >= 1) { - forge.log.verbose(cat, '[%s][%s] finish', - task.id, task.name, task); - } - - // only do queue processing for root tasks - if(task.parent === null) { - // report error if queue is missing - if(!(task.type in sTaskQueues)) { - forge.log.error(cat, - '[%s][%s] task queue missing [%s]', - task.id, task.name, task.type); - } else if(sTaskQueues[task.type].length === 0) { - // report error if queue is empty - forge.log.error(cat, - '[%s][%s] task queue empty [%s]', - task.id, task.name, task.type); - } else if(sTaskQueues[task.type][0] !== task) { - // report error if this task isn't the first in the queue - forge.log.error(cat, - '[%s][%s] task not first in queue [%s]', - task.id, task.name, task.type); - } else { - // remove ourselves from the queue - sTaskQueues[task.type].shift(); - // clean up queue if it is empty - if(sTaskQueues[task.type].length === 0) { - if(sVL >= 1) { - forge.log.verbose(cat, '[%s][%s] delete queue [%s]', - task.id, task.name, task.type); - } - /* Note: Only a task can delete a queue of its own type. This - is used as a way to synchronize tasks. If a queue for a certain - task type exists, then a task of that type is running. - */ - delete sTaskQueues[task.type]; - } else { - // dequeue the next task and start it - if(sVL >= 1) { - forge.log.verbose(cat, - '[%s][%s] queue start next [%s] remain:%s', - task.id, task.name, task.type, - sTaskQueues[task.type].length); - } - sTaskQueues[task.type][0].start(); - } - } - - if(!suppressCallbacks) { - // call final callback if one exists - if(task.error && task.failureCallback) { - task.failureCallback(task); - } else if(!task.error && task.successCallback) { - task.successCallback(task); - } - } - } -}; - -/* Tasks API */ -forge.task = forge.task || {}; - -/** - * Starts a new task that will run the passed function asynchronously. - * - * In order to finish the task, either task.doNext() or task.fail() - * *must* be called. - * - * The task must have a type (a string identifier) that can be used to - * synchronize it with other tasks of the same type. That type can also - * be used to cancel tasks that haven't started yet. - * - * To start a task, the following object must be provided as a parameter - * (each function takes a task object as its first parameter): - * - * { - * type: the type of task. - * run: the function to run to execute the task. - * success: a callback to call when the task succeeds (optional). - * failure: a callback to call when the task fails (optional). - * } - * - * @param options the object as described above. - */ -forge.task.start = function(options) { - // create a new task - var task = new Task({ - run: options.run, - name: options.name || sNoTaskName - }); - task.type = options.type; - task.successCallback = options.success || null; - task.failureCallback = options.failure || null; - - // append the task onto the appropriate queue - if(!(task.type in sTaskQueues)) { - if(sVL >= 1) { - forge.log.verbose(cat, '[%s][%s] create queue [%s]', - task.id, task.name, task.type); - } - // create the queue with the new task - sTaskQueues[task.type] = [task]; - start(task); - } else { - // push the task onto the queue, it will be run after a task - // with the same type completes - sTaskQueues[options.type].push(task); - } -}; - -/** - * Cancels all tasks of the given type that haven't started yet. - * - * @param type the type of task to cancel. - */ -forge.task.cancel = function(type) { - // find the task queue - if(type in sTaskQueues) { - // empty all but the current task from the queue - sTaskQueues[type] = [sTaskQueues[type][0]]; - } -}; - -/** - * Creates a condition variable to synchronize tasks. To make a task wait - * on the condition variable, call task.wait(condition). To notify all - * tasks that are waiting, call condition.notify(). - * - * @return the condition variable. - */ -forge.task.createCondition = function() { - var cond = { - // all tasks that are blocked - tasks: {} - }; - - /** - * Causes the given task to block until notify is called. If the task - * is already waiting on this condition then this is a no-op. - * - * @param task the task to cause to wait. - */ - cond.wait = function(task) { - // only block once - if(!(task.id in cond.tasks)) { - task.block(); - cond.tasks[task.id] = task; - } - }; - - /** - * Notifies all waiting tasks to wake up. - */ - cond.notify = function() { - // since unblock() will run the next task from here, make sure to - // clear the condition's blocked task list before unblocking - var tmp = cond.tasks; - cond.tasks = {}; - for(var id in tmp) { - tmp[id].unblock(); - } - }; - - return cond; -}; - -} // end module implementation - -/* ########## Begin module wrapper ########## */ -var name = 'task'; -if(typeof define !== 'function') { - // NodeJS -> AMD - if(typeof module === 'object' && module.exports) { - var nodeJS = true; - define = function(ids, factory) { - factory(require, module); - }; - } else { - // <script> - if(typeof forge === 'undefined') { - forge = {}; - } - return initModule(forge); - } -} -// AMD -var deps; -var defineFunc = function(require, module) { - module.exports = function(forge) { - var mods = deps.map(function(dep) { - return require(dep); - }).concat(initModule); - // handle circular dependencies - forge = forge || {}; - forge.defined = forge.defined || {}; - if(forge.defined[name]) { - return forge[name]; - } - forge.defined[name] = true; - for(var i = 0; i < mods.length; ++i) { - mods[i](forge); - } - return forge[name]; - }; -}; -var tmpDefine = define; -define = function(ids, factory) { - deps = (typeof ids === 'string') ? factory.slice(2) : ids.slice(2); - if(nodeJS) { - delete define; - return tmpDefine.apply(null, Array.prototype.slice.call(arguments, 0)); - } - define = tmpDefine; - return define.apply(null, Array.prototype.slice.call(arguments, 0)); -}; -define(['require', 'module', './debug', './log', './util'], function() { - defineFunc.apply(null, Array.prototype.slice.call(arguments, 0)); -}); -})(); diff --git a/alarm/node_modules/node-forge/js/tls.js b/alarm/node_modules/node-forge/js/tls.js deleted file mode 100644 index b3bb2e8..0000000 --- a/alarm/node_modules/node-forge/js/tls.js +++ /dev/null @@ -1,4316 +0,0 @@ -/** - * A Javascript implementation of Transport Layer Security (TLS). - * - * @author Dave Longley - * - * Copyright (c) 2009-2014 Digital Bazaar, Inc. - * - * The TLS Handshake Protocol involves the following steps: - * - * - Exchange hello messages to agree on algorithms, exchange random values, - * and check for session resumption. - * - * - Exchange the necessary cryptographic parameters to allow the client and - * server to agree on a premaster secret. - * - * - Exchange certificates and cryptographic information to allow the client - * and server to authenticate themselves. - * - * - Generate a master secret from the premaster secret and exchanged random - * values. - * - * - Provide security parameters to the record layer. - * - * - Allow the client and server to verify that their peer has calculated the - * same security parameters and that the handshake occurred without tampering - * by an attacker. - * - * Up to 4 different messages may be sent during a key exchange. The server - * certificate, the server key exchange, the client certificate, and the - * client key exchange. - * - * A typical handshake (from the client's perspective). - * - * 1. Client sends ClientHello. - * 2. Client receives ServerHello. - * 3. Client receives optional Certificate. - * 4. Client receives optional ServerKeyExchange. - * 5. Client receives ServerHelloDone. - * 6. Client sends optional Certificate. - * 7. Client sends ClientKeyExchange. - * 8. Client sends optional CertificateVerify. - * 9. Client sends ChangeCipherSpec. - * 10. Client sends Finished. - * 11. Client receives ChangeCipherSpec. - * 12. Client receives Finished. - * 13. Client sends/receives application data. - * - * To reuse an existing session: - * - * 1. Client sends ClientHello with session ID for reuse. - * 2. Client receives ServerHello with same session ID if reusing. - * 3. Client receives ChangeCipherSpec message if reusing. - * 4. Client receives Finished. - * 5. Client sends ChangeCipherSpec. - * 6. Client sends Finished. - * - * Note: Client ignores HelloRequest if in the middle of a handshake. - * - * Record Layer: - * - * The record layer fragments information blocks into TLSPlaintext records - * carrying data in chunks of 2^14 bytes or less. Client message boundaries are - * not preserved in the record layer (i.e., multiple client messages of the - * same ContentType MAY be coalesced into a single TLSPlaintext record, or a - * single message MAY be fragmented across several records). - * - * struct { - * uint8 major; - * uint8 minor; - * } ProtocolVersion; - * - * struct { - * ContentType type; - * ProtocolVersion version; - * uint16 length; - * opaque fragment[TLSPlaintext.length]; - * } TLSPlaintext; - * - * type: - * The higher-level protocol used to process the enclosed fragment. - * - * version: - * The version of the protocol being employed. TLS Version 1.2 uses version - * {3, 3}. TLS Version 1.0 uses version {3, 1}. Note that a client that - * supports multiple versions of TLS may not know what version will be - * employed before it receives the ServerHello. - * - * length: - * The length (in bytes) of the following TLSPlaintext.fragment. The length - * MUST NOT exceed 2^14 = 16384 bytes. - * - * fragment: - * The application data. This data is transparent and treated as an - * independent block to be dealt with by the higher-level protocol specified - * by the type field. - * - * Implementations MUST NOT send zero-length fragments of Handshake, Alert, or - * ChangeCipherSpec content types. Zero-length fragments of Application data - * MAY be sent as they are potentially useful as a traffic analysis - * countermeasure. - * - * Note: Data of different TLS record layer content types MAY be interleaved. - * Application data is generally of lower precedence for transmission than - * other content types. However, records MUST be delivered to the network in - * the same order as they are protected by the record layer. Recipients MUST - * receive and process interleaved application layer traffic during handshakes - * subsequent to the first one on a connection. - * - * struct { - * ContentType type; // same as TLSPlaintext.type - * ProtocolVersion version;// same as TLSPlaintext.version - * uint16 length; - * opaque fragment[TLSCompressed.length]; - * } TLSCompressed; - * - * length: - * The length (in bytes) of the following TLSCompressed.fragment. - * The length MUST NOT exceed 2^14 + 1024. - * - * fragment: - * The compressed form of TLSPlaintext.fragment. - * - * Note: A CompressionMethod.null operation is an identity operation; no fields - * are altered. In this implementation, since no compression is supported, - * uncompressed records are always the same as compressed records. - * - * Encryption Information: - * - * The encryption and MAC functions translate a TLSCompressed structure into a - * TLSCiphertext. The decryption functions reverse the process. The MAC of the - * record also includes a sequence number so that missing, extra, or repeated - * messages are detectable. - * - * struct { - * ContentType type; - * ProtocolVersion version; - * uint16 length; - * select (SecurityParameters.cipher_type) { - * case stream: GenericStreamCipher; - * case block: GenericBlockCipher; - * case aead: GenericAEADCipher; - * } fragment; - * } TLSCiphertext; - * - * type: - * The type field is identical to TLSCompressed.type. - * - * version: - * The version field is identical to TLSCompressed.version. - * - * length: - * The length (in bytes) of the following TLSCiphertext.fragment. - * The length MUST NOT exceed 2^14 + 2048. - * - * fragment: - * The encrypted form of TLSCompressed.fragment, with the MAC. - * - * Note: Only CBC Block Ciphers are supported by this implementation. - * - * The TLSCompressed.fragment structures are converted to/from block - * TLSCiphertext.fragment structures. - * - * struct { - * opaque IV[SecurityParameters.record_iv_length]; - * block-ciphered struct { - * opaque content[TLSCompressed.length]; - * opaque MAC[SecurityParameters.mac_length]; - * uint8 padding[GenericBlockCipher.padding_length]; - * uint8 padding_length; - * }; - * } GenericBlockCipher; - * - * The MAC is generated as described in Section 6.2.3.1. - * - * IV: - * The Initialization Vector (IV) SHOULD be chosen at random, and MUST be - * unpredictable. Note that in versions of TLS prior to 1.1, there was no - * IV field, and the last ciphertext block of the previous record (the "CBC - * residue") was used as the IV. This was changed to prevent the attacks - * described in [CBCATT]. For block ciphers, the IV length is of length - * SecurityParameters.record_iv_length, which is equal to the - * SecurityParameters.block_size. - * - * padding: - * Padding that is added to force the length of the plaintext to be an - * integral multiple of the block cipher's block length. The padding MAY be - * any length up to 255 bytes, as long as it results in the - * TLSCiphertext.length being an integral multiple of the block length. - * Lengths longer than necessary might be desirable to frustrate attacks on - * a protocol that are based on analysis of the lengths of exchanged - * messages. Each uint8 in the padding data vector MUST be filled with the - * padding length value. The receiver MUST check this padding and MUST use - * the bad_record_mac alert to indicate padding errors. - * - * padding_length: - * The padding length MUST be such that the total size of the - * GenericBlockCipher structure is a multiple of the cipher's block length. - * Legal values range from zero to 255, inclusive. This length specifies the - * length of the padding field exclusive of the padding_length field itself. - * - * The encrypted data length (TLSCiphertext.length) is one more than the sum of - * SecurityParameters.block_length, TLSCompressed.length, - * SecurityParameters.mac_length, and padding_length. - * - * Example: If the block length is 8 bytes, the content length - * (TLSCompressed.length) is 61 bytes, and the MAC length is 20 bytes, then the - * length before padding is 82 bytes (this does not include the IV. Thus, the - * padding length modulo 8 must be equal to 6 in order to make the total length - * an even multiple of 8 bytes (the block length). The padding length can be - * 6, 14, 22, and so on, through 254. If the padding length were the minimum - * necessary, 6, the padding would be 6 bytes, each containing the value 6. - * Thus, the last 8 octets of the GenericBlockCipher before block encryption - * would be xx 06 06 06 06 06 06 06, where xx is the last octet of the MAC. - * - * Note: With block ciphers in CBC mode (Cipher Block Chaining), it is critical - * that the entire plaintext of the record be known before any ciphertext is - * transmitted. Otherwise, it is possible for the attacker to mount the attack - * described in [CBCATT]. - * - * Implementation note: Canvel et al. [CBCTIME] have demonstrated a timing - * attack on CBC padding based on the time required to compute the MAC. In - * order to defend against this attack, implementations MUST ensure that - * record processing time is essentially the same whether or not the padding - * is correct. In general, the best way to do this is to compute the MAC even - * if the padding is incorrect, and only then reject the packet. For instance, - * if the pad appears to be incorrect, the implementation might assume a - * zero-length pad and then compute the MAC. This leaves a small timing - * channel, since MAC performance depends, to some extent, on the size of the - * data fragment, but it is not believed to be large enough to be exploitable, - * due to the large block size of existing MACs and the small size of the - * timing signal. - */ -(function() { -/* ########## Begin module implementation ########## */ -function initModule(forge) { - -/** - * Generates pseudo random bytes by mixing the result of two hash functions, - * MD5 and SHA-1. - * - * prf_TLS1(secret, label, seed) = - * P_MD5(S1, label + seed) XOR P_SHA-1(S2, label + seed); - * - * Each P_hash function functions as follows: - * - * P_hash(secret, seed) = HMAC_hash(secret, A(1) + seed) + - * HMAC_hash(secret, A(2) + seed) + - * HMAC_hash(secret, A(3) + seed) + ... - * A() is defined as: - * A(0) = seed - * A(i) = HMAC_hash(secret, A(i-1)) - * - * The '+' operator denotes concatenation. - * - * As many iterations A(N) as are needed are performed to generate enough - * pseudo random byte output. If an iteration creates more data than is - * necessary, then it is truncated. - * - * Therefore: - * A(1) = HMAC_hash(secret, A(0)) - * = HMAC_hash(secret, seed) - * A(2) = HMAC_hash(secret, A(1)) - * = HMAC_hash(secret, HMAC_hash(secret, seed)) - * - * Therefore: - * P_hash(secret, seed) = - * HMAC_hash(secret, HMAC_hash(secret, A(0)) + seed) + - * HMAC_hash(secret, HMAC_hash(secret, A(1)) + seed) + - * ... - * - * Therefore: - * P_hash(secret, seed) = - * HMAC_hash(secret, HMAC_hash(secret, seed) + seed) + - * HMAC_hash(secret, HMAC_hash(secret, HMAC_hash(secret, seed)) + seed) + - * ... - * - * @param secret the secret to use. - * @param label the label to use. - * @param seed the seed value to use. - * @param length the number of bytes to generate. - * - * @return the pseudo random bytes in a byte buffer. - */ -var prf_TLS1 = function(secret, label, seed, length) { - var rval = forge.util.createBuffer(); - - /* For TLS 1.0, the secret is split in half, into two secrets of equal - length. If the secret has an odd length then the last byte of the first - half will be the same as the first byte of the second. The length of the - two secrets is half of the secret rounded up. */ - var idx = (secret.length >> 1); - var slen = idx + (secret.length & 1); - var s1 = secret.substr(0, slen); - var s2 = secret.substr(idx, slen); - var ai = forge.util.createBuffer(); - var hmac = forge.hmac.create(); - seed = label + seed; - - // determine the number of iterations that must be performed to generate - // enough output bytes, md5 creates 16 byte hashes, sha1 creates 20 - var md5itr = Math.ceil(length / 16); - var sha1itr = Math.ceil(length / 20); - - // do md5 iterations - hmac.start('MD5', s1); - var md5bytes = forge.util.createBuffer(); - ai.putBytes(seed); - for(var i = 0; i < md5itr; ++i) { - // HMAC_hash(secret, A(i-1)) - hmac.start(null, null); - hmac.update(ai.getBytes()); - ai.putBuffer(hmac.digest()); - - // HMAC_hash(secret, A(i) + seed) - hmac.start(null, null); - hmac.update(ai.bytes() + seed); - md5bytes.putBuffer(hmac.digest()); - } - - // do sha1 iterations - hmac.start('SHA1', s2); - var sha1bytes = forge.util.createBuffer(); - ai.clear(); - ai.putBytes(seed); - for(var i = 0; i < sha1itr; ++i) { - // HMAC_hash(secret, A(i-1)) - hmac.start(null, null); - hmac.update(ai.getBytes()); - ai.putBuffer(hmac.digest()); - - // HMAC_hash(secret, A(i) + seed) - hmac.start(null, null); - hmac.update(ai.bytes() + seed); - sha1bytes.putBuffer(hmac.digest()); - } - - // XOR the md5 bytes with the sha1 bytes - rval.putBytes(forge.util.xorBytes( - md5bytes.getBytes(), sha1bytes.getBytes(), length)); - - return rval; -}; - -/** - * Generates pseudo random bytes using a SHA256 algorithm. For TLS 1.2. - * - * @param secret the secret to use. - * @param label the label to use. - * @param seed the seed value to use. - * @param length the number of bytes to generate. - * - * @return the pseudo random bytes in a byte buffer. - */ -var prf_sha256 = function(secret, label, seed, length) { - // FIXME: implement me for TLS 1.2 -}; - -/** - * Gets a MAC for a record using the SHA-1 hash algorithm. - * - * @param key the mac key. - * @param state the sequence number (array of two 32-bit integers). - * @param record the record. - * - * @return the sha-1 hash (20 bytes) for the given record. - */ -var hmac_sha1 = function(key, seqNum, record) { - /* MAC is computed like so: - HMAC_hash( - key, seqNum + - TLSCompressed.type + - TLSCompressed.version + - TLSCompressed.length + - TLSCompressed.fragment) - */ - var hmac = forge.hmac.create(); - hmac.start('SHA1', key); - var b = forge.util.createBuffer(); - b.putInt32(seqNum[0]); - b.putInt32(seqNum[1]); - b.putByte(record.type); - b.putByte(record.version.major); - b.putByte(record.version.minor); - b.putInt16(record.length); - b.putBytes(record.fragment.bytes()); - hmac.update(b.getBytes()); - return hmac.digest().getBytes(); -}; - -/** - * Compresses the TLSPlaintext record into a TLSCompressed record using the - * deflate algorithm. - * - * @param c the TLS connection. - * @param record the TLSPlaintext record to compress. - * @param s the ConnectionState to use. - * - * @return true on success, false on failure. - */ -var deflate = function(c, record, s) { - var rval = false; - - try { - var bytes = c.deflate(record.fragment.getBytes()); - record.fragment = forge.util.createBuffer(bytes); - record.length = bytes.length; - rval = true; - } catch(ex) { - // deflate error, fail out - } - - return rval; -}; - -/** - * Decompresses the TLSCompressed record into a TLSPlaintext record using the - * deflate algorithm. - * - * @param c the TLS connection. - * @param record the TLSCompressed record to decompress. - * @param s the ConnectionState to use. - * - * @return true on success, false on failure. - */ -var inflate = function(c, record, s) { - var rval = false; - - try { - var bytes = c.inflate(record.fragment.getBytes()); - record.fragment = forge.util.createBuffer(bytes); - record.length = bytes.length; - rval = true; - } catch(ex) { - // inflate error, fail out - } - - return rval; -}; - -/** - * Reads a TLS variable-length vector from a byte buffer. - * - * Variable-length vectors are defined by specifying a subrange of legal - * lengths, inclusively, using the notation <floor..ceiling>. When these are - * encoded, the actual length precedes the vector's contents in the byte - * stream. The length will be in the form of a number consuming as many bytes - * as required to hold the vector's specified maximum (ceiling) length. A - * variable-length vector with an actual length field of zero is referred to - * as an empty vector. - * - * @param b the byte buffer. - * @param lenBytes the number of bytes required to store the length. - * - * @return the resulting byte buffer. - */ -var readVector = function(b, lenBytes) { - var len = 0; - switch(lenBytes) { - case 1: - len = b.getByte(); - break; - case 2: - len = b.getInt16(); - break; - case 3: - len = b.getInt24(); - break; - case 4: - len = b.getInt32(); - break; - } - - // read vector bytes into a new buffer - return forge.util.createBuffer(b.getBytes(len)); -}; - -/** - * Writes a TLS variable-length vector to a byte buffer. - * - * @param b the byte buffer. - * @param lenBytes the number of bytes required to store the length. - * @param v the byte buffer vector. - */ -var writeVector = function(b, lenBytes, v) { - // encode length at the start of the vector, where the number of bytes for - // the length is the maximum number of bytes it would take to encode the - // vector's ceiling - b.putInt(v.length(), lenBytes << 3); - b.putBuffer(v); -}; - -/** - * The tls implementation. - */ -var tls = {}; - -/** - * Version: TLS 1.2 = 3.3, TLS 1.1 = 3.2, TLS 1.0 = 3.1. Both TLS 1.1 and - * TLS 1.2 were still too new (ie: openSSL didn't implement them) at the time - * of this implementation so TLS 1.0 was implemented instead. - */ -tls.Versions = { - TLS_1_0: {major: 3, minor: 1}, - TLS_1_1: {major: 3, minor: 2}, - TLS_1_2: {major: 3, minor: 3} -}; -tls.SupportedVersions = [ - tls.Versions.TLS_1_1, - tls.Versions.TLS_1_0 -]; -tls.Version = tls.SupportedVersions[0]; - -/** - * Maximum fragment size. True maximum is 16384, but we fragment before that - * to allow for unusual small increases during compression. - */ -tls.MaxFragment = 16384 - 1024; - -/** - * Whether this entity is considered the "client" or "server". - * enum { server, client } ConnectionEnd; - */ -tls.ConnectionEnd = { - server: 0, - client: 1 -}; - -/** - * Pseudo-random function algorithm used to generate keys from the master - * secret. - * enum { tls_prf_sha256 } PRFAlgorithm; - */ -tls.PRFAlgorithm = { - tls_prf_sha256: 0 -}; - -/** - * Bulk encryption algorithms. - * enum { null, rc4, des3, aes } BulkCipherAlgorithm; - */ -tls.BulkCipherAlgorithm = { - none: null, - rc4: 0, - des3: 1, - aes: 2 -}; - -/** - * Cipher types. - * enum { stream, block, aead } CipherType; - */ -tls.CipherType = { - stream: 0, - block: 1, - aead: 2 -}; - -/** - * MAC (Message Authentication Code) algorithms. - * enum { null, hmac_md5, hmac_sha1, hmac_sha256, - * hmac_sha384, hmac_sha512} MACAlgorithm; - */ -tls.MACAlgorithm = { - none: null, - hmac_md5: 0, - hmac_sha1: 1, - hmac_sha256: 2, - hmac_sha384: 3, - hmac_sha512: 4 -}; - -/** - * Compression algorithms. - * enum { null(0), deflate(1), (255) } CompressionMethod; - */ -tls.CompressionMethod = { - none: 0, - deflate: 1 -}; - -/** - * TLS record content types. - * enum { - * change_cipher_spec(20), alert(21), handshake(22), - * application_data(23), (255) - * } ContentType; - */ -tls.ContentType = { - change_cipher_spec: 20, - alert: 21, - handshake: 22, - application_data: 23, - heartbeat: 24 -}; - -/** - * TLS handshake types. - * enum { - * hello_request(0), client_hello(1), server_hello(2), - * certificate(11), server_key_exchange (12), - * certificate_request(13), server_hello_done(14), - * certificate_verify(15), client_key_exchange(16), - * finished(20), (255) - * } HandshakeType; - */ -tls.HandshakeType = { - hello_request: 0, - client_hello: 1, - server_hello: 2, - certificate: 11, - server_key_exchange: 12, - certificate_request: 13, - server_hello_done: 14, - certificate_verify: 15, - client_key_exchange: 16, - finished: 20 -}; - -/** - * TLS Alert Protocol. - * - * enum { warning(1), fatal(2), (255) } AlertLevel; - * - * enum { - * close_notify(0), - * unexpected_message(10), - * bad_record_mac(20), - * decryption_failed(21), - * record_overflow(22), - * decompression_failure(30), - * handshake_failure(40), - * bad_certificate(42), - * unsupported_certificate(43), - * certificate_revoked(44), - * certificate_expired(45), - * certificate_unknown(46), - * illegal_parameter(47), - * unknown_ca(48), - * access_denied(49), - * decode_error(50), - * decrypt_error(51), - * export_restriction(60), - * protocol_version(70), - * insufficient_security(71), - * internal_error(80), - * user_canceled(90), - * no_renegotiation(100), - * (255) - * } AlertDescription; - * - * struct { - * AlertLevel level; - * AlertDescription description; - * } Alert; - */ -tls.Alert = {}; -tls.Alert.Level = { - warning: 1, - fatal: 2 -}; -tls.Alert.Description = { - close_notify: 0, - unexpected_message: 10, - bad_record_mac: 20, - decryption_failed: 21, - record_overflow: 22, - decompression_failure: 30, - handshake_failure: 40, - bad_certificate: 42, - unsupported_certificate: 43, - certificate_revoked: 44, - certificate_expired: 45, - certificate_unknown: 46, - illegal_parameter: 47, - unknown_ca: 48, - access_denied: 49, - decode_error: 50, - decrypt_error: 51, - export_restriction: 60, - protocol_version: 70, - insufficient_security: 71, - internal_error: 80, - user_canceled: 90, - no_renegotiation: 100 -}; - -/** - * TLS Heartbeat Message types. - * enum { - * heartbeat_request(1), - * heartbeat_response(2), - * (255) - * } HeartbeatMessageType; - */ -tls.HeartbeatMessageType = { - heartbeat_request: 1, - heartbeat_response: 2 -}; - -/** - * Supported cipher suites. - */ -tls.CipherSuites = {}; - -/** - * Gets a supported cipher suite from its 2 byte ID. - * - * @param twoBytes two bytes in a string. - * - * @return the matching supported cipher suite or null. - */ -tls.getCipherSuite = function(twoBytes) { - var rval = null; - for(var key in tls.CipherSuites) { - var cs = tls.CipherSuites[key]; - if(cs.id[0] === twoBytes.charCodeAt(0) && - cs.id[1] === twoBytes.charCodeAt(1)) { - rval = cs; - break; - } - } - return rval; -}; - -/** - * Called when an unexpected record is encountered. - * - * @param c the connection. - * @param record the record. - */ -tls.handleUnexpected = function(c, record) { - // if connection is client and closed, ignore unexpected messages - var ignore = (!c.open && c.entity === tls.ConnectionEnd.client); - if(!ignore) { - c.error(c, { - message: 'Unexpected message. Received TLS record out of order.', - send: true, - alert: { - level: tls.Alert.Level.fatal, - description: tls.Alert.Description.unexpected_message - } - }); - } -}; - -/** - * Called when a client receives a HelloRequest record. - * - * @param c the connection. - * @param record the record. - * @param length the length of the handshake message. - */ -tls.handleHelloRequest = function(c, record, length) { - // ignore renegotiation requests from the server during a handshake, but - // if handshaking, send a warning alert that renegotation is denied - if(!c.handshaking && c.handshakes > 0) { - // send alert warning - tls.queue(c, tls.createAlert(c, { - level: tls.Alert.Level.warning, - description: tls.Alert.Description.no_renegotiation - })); - tls.flush(c); - } - - // continue - c.process(); -}; - -/** - * Parses a hello message from a ClientHello or ServerHello record. - * - * @param record the record to parse. - * - * @return the parsed message. - */ -tls.parseHelloMessage = function(c, record, length) { - var msg = null; - - var client = (c.entity === tls.ConnectionEnd.client); - - // minimum of 38 bytes in message - if(length < 38) { - c.error(c, { - message: client ? - 'Invalid ServerHello message. Message too short.' : - 'Invalid ClientHello message. Message too short.', - send: true, - alert: { - level: tls.Alert.Level.fatal, - description: tls.Alert.Description.illegal_parameter - } - }); - } else { - // use 'remaining' to calculate # of remaining bytes in the message - var b = record.fragment; - var remaining = b.length(); - msg = { - version: { - major: b.getByte(), - minor: b.getByte() - }, - random: forge.util.createBuffer(b.getBytes(32)), - session_id: readVector(b, 1), - extensions: [] - }; - if(client) { - msg.cipher_suite = b.getBytes(2); - msg.compression_method = b.getByte(); - } else { - msg.cipher_suites = readVector(b, 2); - msg.compression_methods = readVector(b, 1); - } - - // read extensions if there are any bytes left in the message - remaining = length - (remaining - b.length()); - if(remaining > 0) { - // parse extensions - var exts = readVector(b, 2); - while(exts.length() > 0) { - msg.extensions.push({ - type: [exts.getByte(), exts.getByte()], - data: readVector(exts, 2) - }); - } - - // TODO: make extension support modular - if(!client) { - for(var i = 0; i < msg.extensions.length; ++i) { - var ext = msg.extensions[i]; - - // support SNI extension - if(ext.type[0] === 0x00 && ext.type[1] === 0x00) { - // get server name list - var snl = readVector(ext.data, 2); - while(snl.length() > 0) { - // read server name type - var snType = snl.getByte(); - - // only HostName type (0x00) is known, break out if - // another type is detected - if(snType !== 0x00) { - break; - } - - // add host name to server name list - c.session.extensions.server_name.serverNameList.push( - readVector(snl, 2).getBytes()); - } - } - } - } - } - - // version already set, do not allow version change - if(c.session.version) { - if(msg.version.major !== c.session.version.major || - msg.version.minor !== c.session.version.minor) { - return c.error(c, { - message: 'TLS version change is disallowed during renegotiation.', - send: true, - alert: { - level: tls.Alert.Level.fatal, - description: tls.Alert.Description.protocol_version - } - }); - } - } - - // get the chosen (ServerHello) cipher suite - if(client) { - // FIXME: should be checking configured acceptable cipher suites - c.session.cipherSuite = tls.getCipherSuite(msg.cipher_suite); - } else { - // get a supported preferred (ClientHello) cipher suite - // choose the first supported cipher suite - var tmp = forge.util.createBuffer(msg.cipher_suites.bytes()); - while(tmp.length() > 0) { - // FIXME: should be checking configured acceptable suites - // cipher suites take up 2 bytes - c.session.cipherSuite = tls.getCipherSuite(tmp.getBytes(2)); - if(c.session.cipherSuite !== null) { - break; - } - } - } - - // cipher suite not supported - if(c.session.cipherSuite === null) { - return c.error(c, { - message: 'No cipher suites in common.', - send: true, - alert: { - level: tls.Alert.Level.fatal, - description: tls.Alert.Description.handshake_failure - }, - cipherSuite: forge.util.bytesToHex(msg.cipher_suite) - }); - } - - // TODO: handle compression methods - if(client) { - c.session.compressionMethod = msg.compression_method; - } else { - // no compression - c.session.compressionMethod = tls.CompressionMethod.none; - } - } - - return msg; -}; - -/** - * Creates security parameters for the given connection based on the given - * hello message. - * - * @param c the TLS connection. - * @param msg the hello message. - */ -tls.createSecurityParameters = function(c, msg) { - /* Note: security params are from TLS 1.2, some values like prf_algorithm - are ignored for TLS 1.0/1.1 and the builtin as specified in the spec is - used. */ - - // TODO: handle other options from server when more supported - - // get client and server randoms - var client = (c.entity === tls.ConnectionEnd.client); - var msgRandom = msg.random.bytes(); - var cRandom = client ? c.session.sp.client_random : msgRandom; - var sRandom = client ? msgRandom : tls.createRandom().getBytes(); - - // create new security parameters - c.session.sp = { - entity: c.entity, - prf_algorithm: tls.PRFAlgorithm.tls_prf_sha256, - bulk_cipher_algorithm: null, - cipher_type: null, - enc_key_length: null, - block_length: null, - fixed_iv_length: null, - record_iv_length: null, - mac_algorithm: null, - mac_length: null, - mac_key_length: null, - compression_algorithm: c.session.compressionMethod, - pre_master_secret: null, - master_secret: null, - client_random: cRandom, - server_random: sRandom - }; -}; - -/** - * Called when a client receives a ServerHello record. - * - * When a ServerHello message will be sent: - * The server will send this message in response to a client hello message - * when it was able to find an acceptable set of algorithms. If it cannot - * find such a match, it will respond with a handshake failure alert. - * - * uint24 length; - * struct { - * ProtocolVersion server_version; - * Random random; - * SessionID session_id; - * CipherSuite cipher_suite; - * CompressionMethod compression_method; - * select(extensions_present) { - * case false: - * struct {}; - * case true: - * Extension extensions<0..2^16-1>; - * }; - * } ServerHello; - * - * @param c the connection. - * @param record the record. - * @param length the length of the handshake message. - */ -tls.handleServerHello = function(c, record, length) { - var msg = tls.parseHelloMessage(c, record, length); - if(c.fail) { - return; - } - - // ensure server version is compatible - if(msg.version.minor <= c.version.minor) { - c.version.minor = msg.version.minor; - } else { - return c.error(c, { - message: 'Incompatible TLS version.', - send: true, - alert: { - level: tls.Alert.Level.fatal, - description: tls.Alert.Description.protocol_version - } - }); - } - - // indicate session version has been set - c.session.version = c.version; - - // get the session ID from the message - var sessionId = msg.session_id.bytes(); - - // if the session ID is not blank and matches the cached one, resume - // the session - if(sessionId.length > 0 && sessionId === c.session.id) { - // resuming session, expect a ChangeCipherSpec next - c.expect = SCC; - c.session.resuming = true; - - // get new server random - c.session.sp.server_random = msg.random.bytes(); - } else { - // not resuming, expect a server Certificate message next - c.expect = SCE; - c.session.resuming = false; - - // create new security parameters - tls.createSecurityParameters(c, msg); - } - - // set new session ID - c.session.id = sessionId; - - // continue - c.process(); -}; - -/** - * Called when a server receives a ClientHello record. - * - * When a ClientHello message will be sent: - * When a client first connects to a server it is required to send the - * client hello as its first message. The client can also send a client - * hello in response to a hello request or on its own initiative in order - * to renegotiate the security parameters in an existing connection. - * - * @param c the connection. - * @param record the record. - * @param length the length of the handshake message. - */ -tls.handleClientHello = function(c, record, length) { - var msg = tls.parseHelloMessage(c, record, length); - if(c.fail) { - return; - } - - // get the session ID from the message - var sessionId = msg.session_id.bytes(); - - // see if the given session ID is in the cache - var session = null; - if(c.sessionCache) { - session = c.sessionCache.getSession(sessionId); - if(session === null) { - // session ID not found - sessionId = ''; - } else if(session.version.major !== msg.version.major || - session.version.minor > msg.version.minor) { - // if session version is incompatible with client version, do not resume - session = null; - sessionId = ''; - } - } - - // no session found to resume, generate a new session ID - if(sessionId.length === 0) { - sessionId = forge.random.getBytes(32); - } - - // update session - c.session.id = sessionId; - c.session.clientHelloVersion = msg.version; - c.session.sp = {}; - if(session) { - // use version and security parameters from resumed session - c.version = c.session.version = session.version; - c.session.sp = session.sp; - } else { - // use highest compatible minor version - var version; - for(var i = 1; i < tls.SupportedVersions.length; ++i) { - version = tls.SupportedVersions[i]; - if(version.minor <= msg.version.minor) { - break; - } - } - c.version = {major: version.major, minor: version.minor}; - c.session.version = c.version; - } - - // if a session is set, resume it - if(session !== null) { - // resuming session, expect a ChangeCipherSpec next - c.expect = CCC; - c.session.resuming = true; - - // get new client random - c.session.sp.client_random = msg.random.bytes(); - } else { - // not resuming, expect a Certificate or ClientKeyExchange - c.expect = (c.verifyClient !== false) ? CCE : CKE; - c.session.resuming = false; - - // create new security parameters - tls.createSecurityParameters(c, msg); - } - - // connection now open - c.open = true; - - // queue server hello - tls.queue(c, tls.createRecord(c, { - type: tls.ContentType.handshake, - data: tls.createServerHello(c) - })); - - if(c.session.resuming) { - // queue change cipher spec message - tls.queue(c, tls.createRecord(c, { - type: tls.ContentType.change_cipher_spec, - data: tls.createChangeCipherSpec() - })); - - // create pending state - c.state.pending = tls.createConnectionState(c); - - // change current write state to pending write state - c.state.current.write = c.state.pending.write; - - // queue finished - tls.queue(c, tls.createRecord(c, { - type: tls.ContentType.handshake, - data: tls.createFinished(c) - })); - } else { - // queue server certificate - tls.queue(c, tls.createRecord(c, { - type: tls.ContentType.handshake, - data: tls.createCertificate(c) - })); - - if(!c.fail) { - // queue server key exchange - tls.queue(c, tls.createRecord(c, { - type: tls.ContentType.handshake, - data: tls.createServerKeyExchange(c) - })); - - // request client certificate if set - if(c.verifyClient !== false) { - // queue certificate request - tls.queue(c, tls.createRecord(c, { - type: tls.ContentType.handshake, - data: tls.createCertificateRequest(c) - })); - } - - // queue server hello done - tls.queue(c, tls.createRecord(c, { - type: tls.ContentType.handshake, - data: tls.createServerHelloDone(c) - })); - } - } - - // send records - tls.flush(c); - - // continue - c.process(); -}; - -/** - * Called when a client receives a Certificate record. - * - * When this message will be sent: - * The server must send a certificate whenever the agreed-upon key exchange - * method is not an anonymous one. This message will always immediately - * follow the server hello message. - * - * Meaning of this message: - * The certificate type must be appropriate for the selected cipher suite's - * key exchange algorithm, and is generally an X.509v3 certificate. It must - * contain a key which matches the key exchange method, as follows. Unless - * otherwise specified, the signing algorithm for the certificate must be - * the same as the algorithm for the certificate key. Unless otherwise - * specified, the public key may be of any length. - * - * opaque ASN.1Cert<1..2^24-1>; - * struct { - * ASN.1Cert certificate_list<1..2^24-1>; - * } Certificate; - * - * @param c the connection. - * @param record the record. - * @param length the length of the handshake message. - */ -tls.handleCertificate = function(c, record, length) { - // minimum of 3 bytes in message - if(length < 3) { - return c.error(c, { - message: 'Invalid Certificate message. Message too short.', - send: true, - alert: { - level: tls.Alert.Level.fatal, - description: tls.Alert.Description.illegal_parameter - } - }); - } - - var b = record.fragment; - var msg = { - certificate_list: readVector(b, 3) - }; - - /* The sender's certificate will be first in the list (chain), each - subsequent one that follows will certify the previous one, but root - certificates (self-signed) that specify the certificate authority may - be omitted under the assumption that clients must already possess it. */ - var cert, asn1; - var certs = []; - try { - while(msg.certificate_list.length() > 0) { - // each entry in msg.certificate_list is a vector with 3 len bytes - cert = readVector(msg.certificate_list, 3); - asn1 = forge.asn1.fromDer(cert); - cert = forge.pki.certificateFromAsn1(asn1, true); - certs.push(cert); - } - } catch(ex) { - return c.error(c, { - message: 'Could not parse certificate list.', - cause: ex, - send: true, - alert: { - level: tls.Alert.Level.fatal, - description: tls.Alert.Description.bad_certificate - } - }); - } - - // ensure at least 1 certificate was provided if in client-mode - // or if verifyClient was set to true to require a certificate - // (as opposed to 'optional') - var client = (c.entity === tls.ConnectionEnd.client); - if((client || c.verifyClient === true) && certs.length === 0) { - // error, no certificate - c.error(c, { - message: client ? - 'No server certificate provided.' : - 'No client certificate provided.', - send: true, - alert: { - level: tls.Alert.Level.fatal, - description: tls.Alert.Description.illegal_parameter - } - }); - } else if(certs.length === 0) { - // no certs to verify - // expect a ServerKeyExchange or ClientKeyExchange message next - c.expect = client ? SKE : CKE; - } else { - // save certificate in session - if(client) { - c.session.serverCertificate = certs[0]; - } else { - c.session.clientCertificate = certs[0]; - } - - if(tls.verifyCertificateChain(c, certs)) { - // expect a ServerKeyExchange or ClientKeyExchange message next - c.expect = client ? SKE : CKE; - } - } - - // continue - c.process(); -}; - -/** - * Called when a client receives a ServerKeyExchange record. - * - * When this message will be sent: - * This message will be sent immediately after the server certificate - * message (or the server hello message, if this is an anonymous - * negotiation). - * - * The server key exchange message is sent by the server only when the - * server certificate message (if sent) does not contain enough data to - * allow the client to exchange a premaster secret. - * - * Meaning of this message: - * This message conveys cryptographic information to allow the client to - * communicate the premaster secret: either an RSA public key to encrypt - * the premaster secret with, or a Diffie-Hellman public key with which the - * client can complete a key exchange (with the result being the premaster - * secret.) - * - * enum { - * dhe_dss, dhe_rsa, dh_anon, rsa, dh_dss, dh_rsa - * } KeyExchangeAlgorithm; - * - * struct { - * opaque dh_p<1..2^16-1>; - * opaque dh_g<1..2^16-1>; - * opaque dh_Ys<1..2^16-1>; - * } ServerDHParams; - * - * struct { - * select(KeyExchangeAlgorithm) { - * case dh_anon: - * ServerDHParams params; - * case dhe_dss: - * case dhe_rsa: - * ServerDHParams params; - * digitally-signed struct { - * opaque client_random[32]; - * opaque server_random[32]; - * ServerDHParams params; - * } signed_params; - * case rsa: - * case dh_dss: - * case dh_rsa: - * struct {}; - * }; - * } ServerKeyExchange; - * - * @param c the connection. - * @param record the record. - * @param length the length of the handshake message. - */ -tls.handleServerKeyExchange = function(c, record, length) { - // this implementation only supports RSA, no Diffie-Hellman support - // so any length > 0 is invalid - if(length > 0) { - return c.error(c, { - message: 'Invalid key parameters. Only RSA is supported.', - send: true, - alert: { - level: tls.Alert.Level.fatal, - description: tls.Alert.Description.unsupported_certificate - } - }); - } - - // expect an optional CertificateRequest message next - c.expect = SCR; - - // continue - c.process(); -}; - -/** - * Called when a client receives a ClientKeyExchange record. - * - * @param c the connection. - * @param record the record. - * @param length the length of the handshake message. - */ -tls.handleClientKeyExchange = function(c, record, length) { - // this implementation only supports RSA, no Diffie-Hellman support - // so any length < 48 is invalid - if(length < 48) { - return c.error(c, { - message: 'Invalid key parameters. Only RSA is supported.', - send: true, - alert: { - level: tls.Alert.Level.fatal, - description: tls.Alert.Description.unsupported_certificate - } - }); - } - - var b = record.fragment; - var msg = { - enc_pre_master_secret: readVector(b, 2).getBytes() - }; - - // do rsa decryption - var privateKey = null; - if(c.getPrivateKey) { - try { - privateKey = c.getPrivateKey(c, c.session.serverCertificate); - privateKey = forge.pki.privateKeyFromPem(privateKey); - } catch(ex) { - c.error(c, { - message: 'Could not get private key.', - cause: ex, - send: true, - alert: { - level: tls.Alert.Level.fatal, - description: tls.Alert.Description.internal_error - } - }); - } - } - - if(privateKey === null) { - return c.error(c, { - message: 'No private key set.', - send: true, - alert: { - level: tls.Alert.Level.fatal, - description: tls.Alert.Description.internal_error - } - }); - } - - try { - // decrypt 48-byte pre-master secret - var sp = c.session.sp; - sp.pre_master_secret = privateKey.decrypt(msg.enc_pre_master_secret); - - // ensure client hello version matches first 2 bytes - var version = c.session.clientHelloVersion; - if(version.major !== sp.pre_master_secret.charCodeAt(0) || - version.minor !== sp.pre_master_secret.charCodeAt(1)) { - // error, do not send alert (see BLEI attack below) - throw new Error('TLS version rollback attack detected.'); - } - } catch(ex) { - /* Note: Daniel Bleichenbacher [BLEI] can be used to attack a - TLS server which is using PKCS#1 encoded RSA, so instead of - failing here, we generate 48 random bytes and use that as - the pre-master secret. */ - sp.pre_master_secret = forge.random.getBytes(48); - } - - // expect a CertificateVerify message if a Certificate was received that - // does not have fixed Diffie-Hellman params, otherwise expect - // ChangeCipherSpec - c.expect = CCC; - if(c.session.clientCertificate !== null) { - // only RSA support, so expect CertificateVerify - // TODO: support Diffie-Hellman - c.expect = CCV; - } - - // continue - c.process(); -}; - -/** - * Called when a client receives a CertificateRequest record. - * - * When this message will be sent: - * A non-anonymous server can optionally request a certificate from the - * client, if appropriate for the selected cipher suite. This message, if - * sent, will immediately follow the Server Key Exchange message (if it is - * sent; otherwise, the Server Certificate message). - * - * enum { - * rsa_sign(1), dss_sign(2), rsa_fixed_dh(3), dss_fixed_dh(4), - * rsa_ephemeral_dh_RESERVED(5), dss_ephemeral_dh_RESERVED(6), - * fortezza_dms_RESERVED(20), (255) - * } ClientCertificateType; - * - * opaque DistinguishedName<1..2^16-1>; - * - * struct { - * ClientCertificateType certificate_types<1..2^8-1>; - * SignatureAndHashAlgorithm supported_signature_algorithms<2^16-1>; - * DistinguishedName certificate_authorities<0..2^16-1>; - * } CertificateRequest; - * - * @param c the connection. - * @param record the record. - * @param length the length of the handshake message. - */ -tls.handleCertificateRequest = function(c, record, length) { - // minimum of 3 bytes in message - if(length < 3) { - return c.error(c, { - message: 'Invalid CertificateRequest. Message too short.', - send: true, - alert: { - level: tls.Alert.Level.fatal, - description: tls.Alert.Description.illegal_parameter - } - }); - } - - // TODO: TLS 1.2+ has different format including - // SignatureAndHashAlgorithm after cert types - var b = record.fragment; - var msg = { - certificate_types: readVector(b, 1), - certificate_authorities: readVector(b, 2) - }; - - // save certificate request in session - c.session.certificateRequest = msg; - - // expect a ServerHelloDone message next - c.expect = SHD; - - // continue - c.process(); -}; - -/** - * Called when a server receives a CertificateVerify record. - * - * @param c the connection. - * @param record the record. - * @param length the length of the handshake message. - */ -tls.handleCertificateVerify = function(c, record, length) { - if(length < 2) { - return c.error(c, { - message: 'Invalid CertificateVerify. Message too short.', - send: true, - alert: { - level: tls.Alert.Level.fatal, - description: tls.Alert.Description.illegal_parameter - } - }); - } - - // rewind to get full bytes for message so it can be manually - // digested below (special case for CertificateVerify messages because - // they must be digested *after* handling as opposed to all others) - var b = record.fragment; - b.read -= 4; - var msgBytes = b.bytes(); - b.read += 4; - - var msg = { - signature: readVector(b, 2).getBytes() - }; - - // TODO: add support for DSA - - // generate data to verify - var verify = forge.util.createBuffer(); - verify.putBuffer(c.session.md5.digest()); - verify.putBuffer(c.session.sha1.digest()); - verify = verify.getBytes(); - - try { - var cert = c.session.clientCertificate; - /*b = forge.pki.rsa.decrypt( - msg.signature, cert.publicKey, true, verify.length); - if(b !== verify) {*/ - if(!cert.publicKey.verify(verify, msg.signature, 'NONE')) { - throw new Error('CertificateVerify signature does not match.'); - } - - // digest message now that it has been handled - c.session.md5.update(msgBytes); - c.session.sha1.update(msgBytes); - } catch(ex) { - return c.error(c, { - message: 'Bad signature in CertificateVerify.', - send: true, - alert: { - level: tls.Alert.Level.fatal, - description: tls.Alert.Description.handshake_failure - } - }); - } - - // expect ChangeCipherSpec - c.expect = CCC; - - // continue - c.process(); -}; - -/** - * Called when a client receives a ServerHelloDone record. - * - * When this message will be sent: - * The server hello done message is sent by the server to indicate the end - * of the server hello and associated messages. After sending this message - * the server will wait for a client response. - * - * Meaning of this message: - * This message means that the server is done sending messages to support - * the key exchange, and the client can proceed with its phase of the key - * exchange. - * - * Upon receipt of the server hello done message the client should verify - * that the server provided a valid certificate if required and check that - * the server hello parameters are acceptable. - * - * struct {} ServerHelloDone; - * - * @param c the connection. - * @param record the record. - * @param length the length of the handshake message. - */ -tls.handleServerHelloDone = function(c, record, length) { - // len must be 0 bytes - if(length > 0) { - return c.error(c, { - message: 'Invalid ServerHelloDone message. Invalid length.', - send: true, - alert: { - level: tls.Alert.Level.fatal, - description: tls.Alert.Description.record_overflow - } - }); - } - - if(c.serverCertificate === null) { - // no server certificate was provided - var error = { - message: 'No server certificate provided. Not enough security.', - send: true, - alert: { - level: tls.Alert.Level.fatal, - description: tls.Alert.Description.insufficient_security - } - }; - - // call application callback - var depth = 0; - var ret = c.verify(c, error.alert.description, depth, []); - if(ret !== true) { - // check for custom alert info - if(ret || ret === 0) { - // set custom message and alert description - if(typeof ret === 'object' && !forge.util.isArray(ret)) { - if(ret.message) { - error.message = ret.message; - } - if(ret.alert) { - error.alert.description = ret.alert; - } - } else if(typeof ret === 'number') { - // set custom alert description - error.alert.description = ret; - } - } - - // send error - return c.error(c, error); - } - } - - // create client certificate message if requested - if(c.session.certificateRequest !== null) { - record = tls.createRecord(c, { - type: tls.ContentType.handshake, - data: tls.createCertificate(c) - }); - tls.queue(c, record); - } - - // create client key exchange message - record = tls.createRecord(c, { - type: tls.ContentType.handshake, - data: tls.createClientKeyExchange(c) - }); - tls.queue(c, record); - - // expect no messages until the following callback has been called - c.expect = SER; - - // create callback to handle client signature (for client-certs) - var callback = function(c, signature) { - if(c.session.certificateRequest !== null && - c.session.clientCertificate !== null) { - // create certificate verify message - tls.queue(c, tls.createRecord(c, { - type: tls.ContentType.handshake, - data: tls.createCertificateVerify(c, signature) - })); - } - - // create change cipher spec message - tls.queue(c, tls.createRecord(c, { - type: tls.ContentType.change_cipher_spec, - data: tls.createChangeCipherSpec() - })); - - // create pending state - c.state.pending = tls.createConnectionState(c); - - // change current write state to pending write state - c.state.current.write = c.state.pending.write; - - // create finished message - tls.queue(c, tls.createRecord(c, { - type: tls.ContentType.handshake, - data: tls.createFinished(c) - })); - - // expect a server ChangeCipherSpec message next - c.expect = SCC; - - // send records - tls.flush(c); - - // continue - c.process(); - }; - - // if there is no certificate request or no client certificate, do - // callback immediately - if(c.session.certificateRequest === null || - c.session.clientCertificate === null) { - return callback(c, null); - } - - // otherwise get the client signature - tls.getClientSignature(c, callback); -}; - -/** - * Called when a ChangeCipherSpec record is received. - * - * @param c the connection. - * @param record the record. - */ -tls.handleChangeCipherSpec = function(c, record) { - if(record.fragment.getByte() !== 0x01) { - return c.error(c, { - message: 'Invalid ChangeCipherSpec message received.', - send: true, - alert: { - level: tls.Alert.Level.fatal, - description: tls.Alert.Description.illegal_parameter - } - }); - } - - // create pending state if: - // 1. Resuming session in client mode OR - // 2. NOT resuming session in server mode - var client = (c.entity === tls.ConnectionEnd.client); - if((c.session.resuming && client) || (!c.session.resuming && !client)) { - c.state.pending = tls.createConnectionState(c); - } - - // change current read state to pending read state - c.state.current.read = c.state.pending.read; - - // clear pending state if: - // 1. NOT resuming session in client mode OR - // 2. resuming a session in server mode - if((!c.session.resuming && client) || (c.session.resuming && !client)) { - c.state.pending = null; - } - - // expect a Finished record next - c.expect = client ? SFI : CFI; - - // continue - c.process(); -}; - -/** - * Called when a Finished record is received. - * - * When this message will be sent: - * A finished message is always sent immediately after a change - * cipher spec message to verify that the key exchange and - * authentication processes were successful. It is essential that a - * change cipher spec message be received between the other - * handshake messages and the Finished message. - * - * Meaning of this message: - * The finished message is the first protected with the just- - * negotiated algorithms, keys, and secrets. Recipients of finished - * messages must verify that the contents are correct. Once a side - * has sent its Finished message and received and validated the - * Finished message from its peer, it may begin to send and receive - * application data over the connection. - * - * struct { - * opaque verify_data[verify_data_length]; - * } Finished; - * - * verify_data - * PRF(master_secret, finished_label, Hash(handshake_messages)) - * [0..verify_data_length-1]; - * - * finished_label - * For Finished messages sent by the client, the string - * "client finished". For Finished messages sent by the server, the - * string "server finished". - * - * verify_data_length depends on the cipher suite. If it is not specified - * by the cipher suite, then it is 12. Versions of TLS < 1.2 always used - * 12 bytes. - * - * @param c the connection. - * @param record the record. - * @param length the length of the handshake message. - */ -tls.handleFinished = function(c, record, length) { - // rewind to get full bytes for message so it can be manually - // digested below (special case for Finished messages because they - // must be digested *after* handling as opposed to all others) - var b = record.fragment; - b.read -= 4; - var msgBytes = b.bytes(); - b.read += 4; - - // message contains only verify_data - var vd = record.fragment.getBytes(); - - // ensure verify data is correct - b = forge.util.createBuffer(); - b.putBuffer(c.session.md5.digest()); - b.putBuffer(c.session.sha1.digest()); - - // set label based on entity type - var client = (c.entity === tls.ConnectionEnd.client); - var label = client ? 'server finished' : 'client finished'; - - // TODO: determine prf function and verify length for TLS 1.2 - var sp = c.session.sp; - var vdl = 12; - var prf = prf_TLS1; - b = prf(sp.master_secret, label, b.getBytes(), vdl); - if(b.getBytes() !== vd) { - return c.error(c, { - message: 'Invalid verify_data in Finished message.', - send: true, - alert: { - level: tls.Alert.Level.fatal, - description: tls.Alert.Description.decrypt_error - } - }); - } - - // digest finished message now that it has been handled - c.session.md5.update(msgBytes); - c.session.sha1.update(msgBytes); - - // resuming session as client or NOT resuming session as server - if((c.session.resuming && client) || (!c.session.resuming && !client)) { - // create change cipher spec message - tls.queue(c, tls.createRecord(c, { - type: tls.ContentType.change_cipher_spec, - data: tls.createChangeCipherSpec() - })); - - // change current write state to pending write state, clear pending - c.state.current.write = c.state.pending.write; - c.state.pending = null; - - // create finished message - tls.queue(c, tls.createRecord(c, { - type: tls.ContentType.handshake, - data: tls.createFinished(c) - })); - } - - // expect application data next - c.expect = client ? SAD : CAD; - - // handshake complete - c.handshaking = false; - ++c.handshakes; - - // save access to peer certificate - c.peerCertificate = client ? - c.session.serverCertificate : c.session.clientCertificate; - - // send records - tls.flush(c); - - // now connected - c.isConnected = true; - c.connected(c); - - // continue - c.process(); -}; - -/** - * Called when an Alert record is received. - * - * @param c the connection. - * @param record the record. - */ -tls.handleAlert = function(c, record) { - // read alert - var b = record.fragment; - var alert = { - level: b.getByte(), - description: b.getByte() - }; - - // TODO: consider using a table? - // get appropriate message - var msg; - switch(alert.description) { - case tls.Alert.Description.close_notify: - msg = 'Connection closed.'; - break; - case tls.Alert.Description.unexpected_message: - msg = 'Unexpected message.'; - break; - case tls.Alert.Description.bad_record_mac: - msg = 'Bad record MAC.'; - break; - case tls.Alert.Description.decryption_failed: - msg = 'Decryption failed.'; - break; - case tls.Alert.Description.record_overflow: - msg = 'Record overflow.'; - break; - case tls.Alert.Description.decompression_failure: - msg = 'Decompression failed.'; - break; - case tls.Alert.Description.handshake_failure: - msg = 'Handshake failure.'; - break; - case tls.Alert.Description.bad_certificate: - msg = 'Bad certificate.'; - break; - case tls.Alert.Description.unsupported_certificate: - msg = 'Unsupported certificate.'; - break; - case tls.Alert.Description.certificate_revoked: - msg = 'Certificate revoked.'; - break; - case tls.Alert.Description.certificate_expired: - msg = 'Certificate expired.'; - break; - case tls.Alert.Description.certificate_unknown: - msg = 'Certificate unknown.'; - break; - case tls.Alert.Description.illegal_parameter: - msg = 'Illegal parameter.'; - break; - case tls.Alert.Description.unknown_ca: - msg = 'Unknown certificate authority.'; - break; - case tls.Alert.Description.access_denied: - msg = 'Access denied.'; - break; - case tls.Alert.Description.decode_error: - msg = 'Decode error.'; - break; - case tls.Alert.Description.decrypt_error: - msg = 'Decrypt error.'; - break; - case tls.Alert.Description.export_restriction: - msg = 'Export restriction.'; - break; - case tls.Alert.Description.protocol_version: - msg = 'Unsupported protocol version.'; - break; - case tls.Alert.Description.insufficient_security: - msg = 'Insufficient security.'; - break; - case tls.Alert.Description.internal_error: - msg = 'Internal error.'; - break; - case tls.Alert.Description.user_canceled: - msg = 'User canceled.'; - break; - case tls.Alert.Description.no_renegotiation: - msg = 'Renegotiation not supported.'; - break; - default: - msg = 'Unknown error.'; - break; - } - - // close connection on close_notify, not an error - if(alert.description === tls.Alert.Description.close_notify) { - return c.close(); - } - - // call error handler - c.error(c, { - message: msg, - send: false, - // origin is the opposite end - origin: (c.entity === tls.ConnectionEnd.client) ? 'server' : 'client', - alert: alert - }); - - // continue - c.process(); -}; - -/** - * Called when a Handshake record is received. - * - * @param c the connection. - * @param record the record. - */ -tls.handleHandshake = function(c, record) { - // get the handshake type and message length - var b = record.fragment; - var type = b.getByte(); - var length = b.getInt24(); - - // see if the record fragment doesn't yet contain the full message - if(length > b.length()) { - // cache the record, clear its fragment, and reset the buffer read - // pointer before the type and length were read - c.fragmented = record; - record.fragment = forge.util.createBuffer(); - b.read -= 4; - - // continue - return c.process(); - } - - // full message now available, clear cache, reset read pointer to - // before type and length - c.fragmented = null; - b.read -= 4; - - // save the handshake bytes for digestion after handler is found - // (include type and length of handshake msg) - var bytes = b.bytes(length + 4); - - // restore read pointer - b.read += 4; - - // handle expected message - if(type in hsTable[c.entity][c.expect]) { - // initialize server session - if(c.entity === tls.ConnectionEnd.server && !c.open && !c.fail) { - c.handshaking = true; - c.session = { - version: null, - extensions: { - server_name: { - serverNameList: [] - } - }, - cipherSuite: null, - compressionMethod: null, - serverCertificate: null, - clientCertificate: null, - md5: forge.md.md5.create(), - sha1: forge.md.sha1.create() - }; - } - - /* Update handshake messages digest. Finished and CertificateVerify - messages are not digested here. They can't be digested as part of - the verify_data that they contain. These messages are manually - digested in their handlers. HelloRequest messages are simply never - included in the handshake message digest according to spec. */ - if(type !== tls.HandshakeType.hello_request && - type !== tls.HandshakeType.certificate_verify && - type !== tls.HandshakeType.finished) { - c.session.md5.update(bytes); - c.session.sha1.update(bytes); - } - - // handle specific handshake type record - hsTable[c.entity][c.expect][type](c, record, length); - } else { - // unexpected record - tls.handleUnexpected(c, record); - } -}; - -/** - * Called when an ApplicationData record is received. - * - * @param c the connection. - * @param record the record. - */ -tls.handleApplicationData = function(c, record) { - // buffer data, notify that its ready - c.data.putBuffer(record.fragment); - c.dataReady(c); - - // continue - c.process(); -}; - -/** - * Called when a Heartbeat record is received. - * - * @param c the connection. - * @param record the record. - */ -tls.handleHeartbeat = function(c, record) { - // get the heartbeat type and payload - var b = record.fragment; - var type = b.getByte(); - var length = b.getInt16(); - var payload = b.getBytes(length); - - if(type === tls.HeartbeatMessageType.heartbeat_request) { - // discard request during handshake or if length is too large - if(c.handshaking || length > payload.length) { - // continue - return c.process(); - } - // retransmit payload - tls.queue(c, tls.createRecord(c, { - type: tls.ContentType.heartbeat, - data: tls.createHeartbeat( - tls.HeartbeatMessageType.heartbeat_response, payload) - })); - tls.flush(c); - } else if(type === tls.HeartbeatMessageType.heartbeat_response) { - // check payload against expected payload, discard heartbeat if no match - if(payload !== c.expectedHeartbeatPayload) { - // continue - return c.process(); - } - - // notify that a valid heartbeat was received - if(c.heartbeatReceived) { - c.heartbeatReceived(c, forge.util.createBuffer(payload)); - } - } - - // continue - c.process(); -}; - -/** - * The transistional state tables for receiving TLS records. It maps the - * current TLS engine state and a received record to a function to handle the - * record and update the state. - * - * For instance, if the current state is SHE, then the TLS engine is expecting - * a ServerHello record. Once a record is received, the handler function is - * looked up using the state SHE and the record's content type. - * - * The resulting function will either be an error handler or a record handler. - * The function will take whatever action is appropriate and update the state - * for the next record. - * - * The states are all based on possible server record types. Note that the - * client will never specifically expect to receive a HelloRequest or an alert - * from the server so there is no state that reflects this. These messages may - * occur at any time. - * - * There are two tables for mapping states because there is a second tier of - * types for handshake messages. Once a record with a content type of handshake - * is received, the handshake record handler will look up the handshake type in - * the secondary map to get its appropriate handler. - * - * Valid message orders are as follows: - * - * =======================FULL HANDSHAKE====================== - * Client Server - * - * ClientHello --------> - * ServerHello - * Certificate* - * ServerKeyExchange* - * CertificateRequest* - * <-------- ServerHelloDone - * Certificate* - * ClientKeyExchange - * CertificateVerify* - * [ChangeCipherSpec] - * Finished --------> - * [ChangeCipherSpec] - * <-------- Finished - * Application Data <-------> Application Data - * - * =====================SESSION RESUMPTION===================== - * Client Server - * - * ClientHello --------> - * ServerHello - * [ChangeCipherSpec] - * <-------- Finished - * [ChangeCipherSpec] - * Finished --------> - * Application Data <-------> Application Data - */ -// client expect states (indicate which records are expected to be received) -var SHE = 0; // rcv server hello -var SCE = 1; // rcv server certificate -var SKE = 2; // rcv server key exchange -var SCR = 3; // rcv certificate request -var SHD = 4; // rcv server hello done -var SCC = 5; // rcv change cipher spec -var SFI = 6; // rcv finished -var SAD = 7; // rcv application data -var SER = 8; // not expecting any messages at this point - -// server expect states -var CHE = 0; // rcv client hello -var CCE = 1; // rcv client certificate -var CKE = 2; // rcv client key exchange -var CCV = 3; // rcv certificate verify -var CCC = 4; // rcv change cipher spec -var CFI = 5; // rcv finished -var CAD = 6; // rcv application data -var CER = 7; // not expecting any messages at this point - -// map client current expect state and content type to function -var __ = tls.handleUnexpected; -var R0 = tls.handleChangeCipherSpec; -var R1 = tls.handleAlert; -var R2 = tls.handleHandshake; -var R3 = tls.handleApplicationData; -var R4 = tls.handleHeartbeat; -var ctTable = []; -ctTable[tls.ConnectionEnd.client] = [ -// CC,AL,HS,AD,HB -/*SHE*/[__,R1,R2,__,R4], -/*SCE*/[__,R1,R2,__,R4], -/*SKE*/[__,R1,R2,__,R4], -/*SCR*/[__,R1,R2,__,R4], -/*SHD*/[__,R1,R2,__,R4], -/*SCC*/[R0,R1,__,__,R4], -/*SFI*/[__,R1,R2,__,R4], -/*SAD*/[__,R1,R2,R3,R4], -/*SER*/[__,R1,R2,__,R4] -]; - -// map server current expect state and content type to function -ctTable[tls.ConnectionEnd.server] = [ -// CC,AL,HS,AD -/*CHE*/[__,R1,R2,__,R4], -/*CCE*/[__,R1,R2,__,R4], -/*CKE*/[__,R1,R2,__,R4], -/*CCV*/[__,R1,R2,__,R4], -/*CCC*/[R0,R1,__,__,R4], -/*CFI*/[__,R1,R2,__,R4], -/*CAD*/[__,R1,R2,R3,R4], -/*CER*/[__,R1,R2,__,R4] -]; - -// map client current expect state and handshake type to function -var H0 = tls.handleHelloRequest; -var H1 = tls.handleServerHello; -var H2 = tls.handleCertificate; -var H3 = tls.handleServerKeyExchange; -var H4 = tls.handleCertificateRequest; -var H5 = tls.handleServerHelloDone; -var H6 = tls.handleFinished; -var hsTable = []; -hsTable[tls.ConnectionEnd.client] = [ -// HR,01,SH,03,04,05,06,07,08,09,10,SC,SK,CR,HD,15,CK,17,18,19,FI -/*SHE*/[__,__,H1,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__], -/*SCE*/[H0,__,__,__,__,__,__,__,__,__,__,H2,H3,H4,H5,__,__,__,__,__,__], -/*SKE*/[H0,__,__,__,__,__,__,__,__,__,__,__,H3,H4,H5,__,__,__,__,__,__], -/*SCR*/[H0,__,__,__,__,__,__,__,__,__,__,__,__,H4,H5,__,__,__,__,__,__], -/*SHD*/[H0,__,__,__,__,__,__,__,__,__,__,__,__,__,H5,__,__,__,__,__,__], -/*SCC*/[H0,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__], -/*SFI*/[H0,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,H6], -/*SAD*/[H0,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__], -/*SER*/[H0,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__] -]; - -// map server current expect state and handshake type to function -// Note: CAD[CH] does not map to FB because renegotation is prohibited -var H7 = tls.handleClientHello; -var H8 = tls.handleClientKeyExchange; -var H9 = tls.handleCertificateVerify; -hsTable[tls.ConnectionEnd.server] = [ -// 01,CH,02,03,04,05,06,07,08,09,10,CC,12,13,14,CV,CK,17,18,19,FI -/*CHE*/[__,H7,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__], -/*CCE*/[__,__,__,__,__,__,__,__,__,__,__,H2,__,__,__,__,__,__,__,__,__], -/*CKE*/[__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,H8,__,__,__,__], -/*CCV*/[__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,H9,__,__,__,__,__], -/*CCC*/[__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__], -/*CFI*/[__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,H6], -/*CAD*/[__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__], -/*CER*/[__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__] -]; - -/** - * Generates the master_secret and keys using the given security parameters. - * - * The security parameters for a TLS connection state are defined as such: - * - * struct { - * ConnectionEnd entity; - * PRFAlgorithm prf_algorithm; - * BulkCipherAlgorithm bulk_cipher_algorithm; - * CipherType cipher_type; - * uint8 enc_key_length; - * uint8 block_length; - * uint8 fixed_iv_length; - * uint8 record_iv_length; - * MACAlgorithm mac_algorithm; - * uint8 mac_length; - * uint8 mac_key_length; - * CompressionMethod compression_algorithm; - * opaque master_secret[48]; - * opaque client_random[32]; - * opaque server_random[32]; - * } SecurityParameters; - * - * Note that this definition is from TLS 1.2. In TLS 1.0 some of these - * parameters are ignored because, for instance, the PRFAlgorithm is a - * builtin-fixed algorithm combining iterations of MD5 and SHA-1 in TLS 1.0. - * - * The Record Protocol requires an algorithm to generate keys required by the - * current connection state. - * - * The master secret is expanded into a sequence of secure bytes, which is then - * split to a client write MAC key, a server write MAC key, a client write - * encryption key, and a server write encryption key. In TLS 1.0 a client write - * IV and server write IV are also generated. Each of these is generated from - * the byte sequence in that order. Unused values are empty. In TLS 1.2, some - * AEAD ciphers may additionally require a client write IV and a server write - * IV (see Section 6.2.3.3). - * - * When keys, MAC keys, and IVs are generated, the master secret is used as an - * entropy source. - * - * To generate the key material, compute: - * - * master_secret = PRF(pre_master_secret, "master secret", - * ClientHello.random + ServerHello.random) - * - * key_block = PRF(SecurityParameters.master_secret, - * "key expansion", - * SecurityParameters.server_random + - * SecurityParameters.client_random); - * - * until enough output has been generated. Then, the key_block is - * partitioned as follows: - * - * client_write_MAC_key[SecurityParameters.mac_key_length] - * server_write_MAC_key[SecurityParameters.mac_key_length] - * client_write_key[SecurityParameters.enc_key_length] - * server_write_key[SecurityParameters.enc_key_length] - * client_write_IV[SecurityParameters.fixed_iv_length] - * server_write_IV[SecurityParameters.fixed_iv_length] - * - * In TLS 1.2, the client_write_IV and server_write_IV are only generated for - * implicit nonce techniques as described in Section 3.2.1 of [AEAD]. This - * implementation uses TLS 1.0 so IVs are generated. - * - * Implementation note: The currently defined cipher suite which requires the - * most material is AES_256_CBC_SHA256. It requires 2 x 32 byte keys and 2 x 32 - * byte MAC keys, for a total 128 bytes of key material. In TLS 1.0 it also - * requires 2 x 16 byte IVs, so it actually takes 160 bytes of key material. - * - * @param c the connection. - * @param sp the security parameters to use. - * - * @return the security keys. - */ -tls.generateKeys = function(c, sp) { - // TLS_RSA_WITH_AES_128_CBC_SHA (required to be compliant with TLS 1.2) & - // TLS_RSA_WITH_AES_256_CBC_SHA are the only cipher suites implemented - // at present - - // TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA is required to be compliant with - // TLS 1.0 but we don't care right now because AES is better and we have - // an implementation for it - - // TODO: TLS 1.2 implementation - /* - // determine the PRF - var prf; - switch(sp.prf_algorithm) { - case tls.PRFAlgorithm.tls_prf_sha256: - prf = prf_sha256; - break; - default: - // should never happen - throw new Error('Invalid PRF'); - } - */ - - // TLS 1.0/1.1 implementation - var prf = prf_TLS1; - - // concatenate server and client random - var random = sp.client_random + sp.server_random; - - // only create master secret if session is new - if(!c.session.resuming) { - // create master secret, clean up pre-master secret - sp.master_secret = prf( - sp.pre_master_secret, 'master secret', random, 48).bytes(); - sp.pre_master_secret = null; - } - - // generate the amount of key material needed - random = sp.server_random + sp.client_random; - var length = 2 * sp.mac_key_length + 2 * sp.enc_key_length; - - // include IV for TLS/1.0 - var tls10 = (c.version.major === tls.Versions.TLS_1_0.major && - c.version.minor === tls.Versions.TLS_1_0.minor); - if(tls10) { - length += 2 * sp.fixed_iv_length; - } - var km = prf(sp.master_secret, 'key expansion', random, length); - - // split the key material into the MAC and encryption keys - var rval = { - client_write_MAC_key: km.getBytes(sp.mac_key_length), - server_write_MAC_key: km.getBytes(sp.mac_key_length), - client_write_key: km.getBytes(sp.enc_key_length), - server_write_key: km.getBytes(sp.enc_key_length) - }; - - // include TLS 1.0 IVs - if(tls10) { - rval.client_write_IV = km.getBytes(sp.fixed_iv_length); - rval.server_write_IV = km.getBytes(sp.fixed_iv_length); - } - - return rval; -}; - -/** - * Creates a new initialized TLS connection state. A connection state has - * a read mode and a write mode. - * - * compression state: - * The current state of the compression algorithm. - * - * cipher state: - * The current state of the encryption algorithm. This will consist of the - * scheduled key for that connection. For stream ciphers, this will also - * contain whatever state information is necessary to allow the stream to - * continue to encrypt or decrypt data. - * - * MAC key: - * The MAC key for the connection. - * - * sequence number: - * Each connection state contains a sequence number, which is maintained - * separately for read and write states. The sequence number MUST be set to - * zero whenever a connection state is made the active state. Sequence - * numbers are of type uint64 and may not exceed 2^64-1. Sequence numbers do - * not wrap. If a TLS implementation would need to wrap a sequence number, - * it must renegotiate instead. A sequence number is incremented after each - * record: specifically, the first record transmitted under a particular - * connection state MUST use sequence number 0. - * - * @param c the connection. - * - * @return the new initialized TLS connection state. - */ -tls.createConnectionState = function(c) { - var client = (c.entity === tls.ConnectionEnd.client); - - var createMode = function() { - var mode = { - // two 32-bit numbers, first is most significant - sequenceNumber: [0, 0], - macKey: null, - macLength: 0, - macFunction: null, - cipherState: null, - cipherFunction: function(record) {return true;}, - compressionState: null, - compressFunction: function(record) {return true;}, - updateSequenceNumber: function() { - if(mode.sequenceNumber[1] === 0xFFFFFFFF) { - mode.sequenceNumber[1] = 0; - ++mode.sequenceNumber[0]; - } else { - ++mode.sequenceNumber[1]; - } - } - }; - return mode; - }; - var state = { - read: createMode(), - write: createMode() - }; - - // update function in read mode will decrypt then decompress a record - state.read.update = function(c, record) { - if(!state.read.cipherFunction(record, state.read)) { - c.error(c, { - message: 'Could not decrypt record or bad MAC.', - send: true, - alert: { - level: tls.Alert.Level.fatal, - // doesn't matter if decryption failed or MAC was - // invalid, return the same error so as not to reveal - // which one occurred - description: tls.Alert.Description.bad_record_mac - } - }); - } else if(!state.read.compressFunction(c, record, state.read)) { - c.error(c, { - message: 'Could not decompress record.', - send: true, - alert: { - level: tls.Alert.Level.fatal, - description: tls.Alert.Description.decompression_failure - } - }); - } - return !c.fail; - }; - - // update function in write mode will compress then encrypt a record - state.write.update = function(c, record) { - if(!state.write.compressFunction(c, record, state.write)) { - // error, but do not send alert since it would require - // compression as well - c.error(c, { - message: 'Could not compress record.', - send: false, - alert: { - level: tls.Alert.Level.fatal, - description: tls.Alert.Description.internal_error - } - }); - } else if(!state.write.cipherFunction(record, state.write)) { - // error, but do not send alert since it would require - // encryption as well - c.error(c, { - message: 'Could not encrypt record.', - send: false, - alert: { - level: tls.Alert.Level.fatal, - description: tls.Alert.Description.internal_error - } - }); - } - return !c.fail; - }; - - // handle security parameters - if(c.session) { - var sp = c.session.sp; - c.session.cipherSuite.initSecurityParameters(sp); - - // generate keys - sp.keys = tls.generateKeys(c, sp); - state.read.macKey = client ? - sp.keys.server_write_MAC_key : sp.keys.client_write_MAC_key; - state.write.macKey = client ? - sp.keys.client_write_MAC_key : sp.keys.server_write_MAC_key; - - // cipher suite setup - c.session.cipherSuite.initConnectionState(state, c, sp); - - // compression setup - switch(sp.compression_algorithm) { - case tls.CompressionMethod.none: - break; - case tls.CompressionMethod.deflate: - state.read.compressFunction = inflate; - state.write.compressFunction = deflate; - break; - default: - throw new Error('Unsupported compression algorithm.'); - } - } - - return state; -}; - -/** - * Creates a Random structure. - * - * struct { - * uint32 gmt_unix_time; - * opaque random_bytes[28]; - * } Random; - * - * gmt_unix_time: - * The current time and date in standard UNIX 32-bit format (seconds since - * the midnight starting Jan 1, 1970, UTC, ignoring leap seconds) according - * to the sender's internal clock. Clocks are not required to be set - * correctly by the basic TLS protocol; higher-level or application - * protocols may define additional requirements. Note that, for historical - * reasons, the data element is named using GMT, the predecessor of the - * current worldwide time base, UTC. - * random_bytes: - * 28 bytes generated by a secure random number generator. - * - * @return the Random structure as a byte array. - */ -tls.createRandom = function() { - // get UTC milliseconds - var d = new Date(); - var utc = +d + d.getTimezoneOffset() * 60000; - var rval = forge.util.createBuffer(); - rval.putInt32(utc); - rval.putBytes(forge.random.getBytes(28)); - return rval; -}; - -/** - * Creates a TLS record with the given type and data. - * - * @param c the connection. - * @param options: - * type: the record type. - * data: the plain text data in a byte buffer. - * - * @return the created record. - */ -tls.createRecord = function(c, options) { - if(!options.data) { - return null; - } - var record = { - type: options.type, - version: { - major: c.version.major, - minor: c.version.minor - }, - length: options.data.length(), - fragment: options.data - }; - return record; -}; - -/** - * Creates a TLS alert record. - * - * @param c the connection. - * @param alert: - * level: the TLS alert level. - * description: the TLS alert description. - * - * @return the created alert record. - */ -tls.createAlert = function(c, alert) { - var b = forge.util.createBuffer(); - b.putByte(alert.level); - b.putByte(alert.description); - return tls.createRecord(c, { - type: tls.ContentType.alert, - data: b - }); -}; - -/* The structure of a TLS handshake message. - * - * struct { - * HandshakeType msg_type; // handshake type - * uint24 length; // bytes in message - * select(HandshakeType) { - * case hello_request: HelloRequest; - * case client_hello: ClientHello; - * case server_hello: ServerHello; - * case certificate: Certificate; - * case server_key_exchange: ServerKeyExchange; - * case certificate_request: CertificateRequest; - * case server_hello_done: ServerHelloDone; - * case certificate_verify: CertificateVerify; - * case client_key_exchange: ClientKeyExchange; - * case finished: Finished; - * } body; - * } Handshake; - */ - -/** - * Creates a ClientHello message. - * - * opaque SessionID<0..32>; - * enum { null(0), deflate(1), (255) } CompressionMethod; - * uint8 CipherSuite[2]; - * - * struct { - * ProtocolVersion client_version; - * Random random; - * SessionID session_id; - * CipherSuite cipher_suites<2..2^16-2>; - * CompressionMethod compression_methods<1..2^8-1>; - * select(extensions_present) { - * case false: - * struct {}; - * case true: - * Extension extensions<0..2^16-1>; - * }; - * } ClientHello; - * - * The extension format for extended client hellos and server hellos is: - * - * struct { - * ExtensionType extension_type; - * opaque extension_data<0..2^16-1>; - * } Extension; - * - * Here: - * - * - "extension_type" identifies the particular extension type. - * - "extension_data" contains information specific to the particular - * extension type. - * - * The extension types defined in this document are: - * - * enum { - * server_name(0), max_fragment_length(1), - * client_certificate_url(2), trusted_ca_keys(3), - * truncated_hmac(4), status_request(5), (65535) - * } ExtensionType; - * - * @param c the connection. - * - * @return the ClientHello byte buffer. - */ -tls.createClientHello = function(c) { - // save hello version - c.session.clientHelloVersion = { - major: c.version.major, - minor: c.version.minor - }; - - // create supported cipher suites - var cipherSuites = forge.util.createBuffer(); - for(var i = 0; i < c.cipherSuites.length; ++i) { - var cs = c.cipherSuites[i]; - cipherSuites.putByte(cs.id[0]); - cipherSuites.putByte(cs.id[1]); - } - var cSuites = cipherSuites.length(); - - // create supported compression methods, null always supported, but - // also support deflate if connection has inflate and deflate methods - var compressionMethods = forge.util.createBuffer(); - compressionMethods.putByte(tls.CompressionMethod.none); - // FIXME: deflate support disabled until issues with raw deflate data - // without zlib headers are resolved - /* - if(c.inflate !== null && c.deflate !== null) { - compressionMethods.putByte(tls.CompressionMethod.deflate); - } - */ - var cMethods = compressionMethods.length(); - - // create TLS SNI (server name indication) extension if virtual host - // has been specified, see RFC 3546 - var extensions = forge.util.createBuffer(); - if(c.virtualHost) { - // create extension struct - var ext = forge.util.createBuffer(); - ext.putByte(0x00); // type server_name (ExtensionType is 2 bytes) - ext.putByte(0x00); - - /* In order to provide the server name, clients MAY include an - * extension of type "server_name" in the (extended) client hello. - * The "extension_data" field of this extension SHALL contain - * "ServerNameList" where: - * - * struct { - * NameType name_type; - * select(name_type) { - * case host_name: HostName; - * } name; - * } ServerName; - * - * enum { - * host_name(0), (255) - * } NameType; - * - * opaque HostName<1..2^16-1>; - * - * struct { - * ServerName server_name_list<1..2^16-1> - * } ServerNameList; - */ - var serverName = forge.util.createBuffer(); - serverName.putByte(0x00); // type host_name - writeVector(serverName, 2, forge.util.createBuffer(c.virtualHost)); - - // ServerNameList is in extension_data - var snList = forge.util.createBuffer(); - writeVector(snList, 2, serverName); - writeVector(ext, 2, snList); - extensions.putBuffer(ext); - } - var extLength = extensions.length(); - if(extLength > 0) { - // add extension vector length - extLength += 2; - } - - // determine length of the handshake message - // cipher suites and compression methods size will need to be - // updated if more get added to the list - var sessionId = c.session.id; - var length = - sessionId.length + 1 + // session ID vector - 2 + // version (major + minor) - 4 + 28 + // random time and random bytes - 2 + cSuites + // cipher suites vector - 1 + cMethods + // compression methods vector - extLength; // extensions vector - - // build record fragment - var rval = forge.util.createBuffer(); - rval.putByte(tls.HandshakeType.client_hello); - rval.putInt24(length); // handshake length - rval.putByte(c.version.major); // major version - rval.putByte(c.version.minor); // minor version - rval.putBytes(c.session.sp.client_random); // random time + bytes - writeVector(rval, 1, forge.util.createBuffer(sessionId)); - writeVector(rval, 2, cipherSuites); - writeVector(rval, 1, compressionMethods); - if(extLength > 0) { - writeVector(rval, 2, extensions); - } - return rval; -}; - -/** - * Creates a ServerHello message. - * - * @param c the connection. - * - * @return the ServerHello byte buffer. - */ -tls.createServerHello = function(c) { - // determine length of the handshake message - var sessionId = c.session.id; - var length = - sessionId.length + 1 + // session ID vector - 2 + // version (major + minor) - 4 + 28 + // random time and random bytes - 2 + // chosen cipher suite - 1; // chosen compression method - - // build record fragment - var rval = forge.util.createBuffer(); - rval.putByte(tls.HandshakeType.server_hello); - rval.putInt24(length); // handshake length - rval.putByte(c.version.major); // major version - rval.putByte(c.version.minor); // minor version - rval.putBytes(c.session.sp.server_random); // random time + bytes - writeVector(rval, 1, forge.util.createBuffer(sessionId)); - rval.putByte(c.session.cipherSuite.id[0]); - rval.putByte(c.session.cipherSuite.id[1]); - rval.putByte(c.session.compressionMethod); - return rval; -}; - -/** - * Creates a Certificate message. - * - * When this message will be sent: - * This is the first message the client can send after receiving a server - * hello done message and the first message the server can send after - * sending a ServerHello. This client message is only sent if the server - * requests a certificate. If no suitable certificate is available, the - * client should send a certificate message containing no certificates. If - * client authentication is required by the server for the handshake to - * continue, it may respond with a fatal handshake failure alert. - * - * opaque ASN.1Cert<1..2^24-1>; - * - * struct { - * ASN.1Cert certificate_list<0..2^24-1>; - * } Certificate; - * - * @param c the connection. - * - * @return the Certificate byte buffer. - */ -tls.createCertificate = function(c) { - // TODO: check certificate request to ensure types are supported - - // get a certificate (a certificate as a PEM string) - var client = (c.entity === tls.ConnectionEnd.client); - var cert = null; - if(c.getCertificate) { - var hint; - if(client) { - hint = c.session.certificateRequest; - } else { - hint = c.session.extensions.server_name.serverNameList; - } - cert = c.getCertificate(c, hint); - } - - // buffer to hold certificate list - var certList = forge.util.createBuffer(); - if(cert !== null) { - try { - // normalize cert to a chain of certificates - if(!forge.util.isArray(cert)) { - cert = [cert]; - } - var asn1 = null; - for(var i = 0; i < cert.length; ++i) { - var msg = forge.pem.decode(cert[i])[0]; - if(msg.type !== 'CERTIFICATE' && - msg.type !== 'X509 CERTIFICATE' && - msg.type !== 'TRUSTED CERTIFICATE') { - var error = new Error('Could not convert certificate from PEM; PEM ' + - 'header type is not "CERTIFICATE", "X509 CERTIFICATE", or ' + - '"TRUSTED CERTIFICATE".'); - error.headerType = msg.type; - throw error; - } - if(msg.procType && msg.procType.type === 'ENCRYPTED') { - throw new Error('Could not convert certificate from PEM; PEM is encrypted.'); - } - - var der = forge.util.createBuffer(msg.body); - if(asn1 === null) { - asn1 = forge.asn1.fromDer(der.bytes(), false); - } - - // certificate entry is itself a vector with 3 length bytes - var certBuffer = forge.util.createBuffer(); - writeVector(certBuffer, 3, der); - - // add cert vector to cert list vector - certList.putBuffer(certBuffer); - } - - // save certificate - cert = forge.pki.certificateFromAsn1(asn1); - if(client) { - c.session.clientCertificate = cert; - } else { - c.session.serverCertificate = cert; - } - } catch(ex) { - return c.error(c, { - message: 'Could not send certificate list.', - cause: ex, - send: true, - alert: { - level: tls.Alert.Level.fatal, - description: tls.Alert.Description.bad_certificate - } - }); - } - } - - // determine length of the handshake message - var length = 3 + certList.length(); // cert list vector - - // build record fragment - var rval = forge.util.createBuffer(); - rval.putByte(tls.HandshakeType.certificate); - rval.putInt24(length); - writeVector(rval, 3, certList); - return rval; -}; - -/** - * Creates a ClientKeyExchange message. - * - * When this message will be sent: - * This message is always sent by the client. It will immediately follow the - * client certificate message, if it is sent. Otherwise it will be the first - * message sent by the client after it receives the server hello done - * message. - * - * Meaning of this message: - * With this message, the premaster secret is set, either though direct - * transmission of the RSA-encrypted secret, or by the transmission of - * Diffie-Hellman parameters which will allow each side to agree upon the - * same premaster secret. When the key exchange method is DH_RSA or DH_DSS, - * client certification has been requested, and the client was able to - * respond with a certificate which contained a Diffie-Hellman public key - * whose parameters (group and generator) matched those specified by the - * server in its certificate, this message will not contain any data. - * - * Meaning of this message: - * If RSA is being used for key agreement and authentication, the client - * generates a 48-byte premaster secret, encrypts it using the public key - * from the server's certificate or the temporary RSA key provided in a - * server key exchange message, and sends the result in an encrypted - * premaster secret message. This structure is a variant of the client - * key exchange message, not a message in itself. - * - * struct { - * select(KeyExchangeAlgorithm) { - * case rsa: EncryptedPreMasterSecret; - * case diffie_hellman: ClientDiffieHellmanPublic; - * } exchange_keys; - * } ClientKeyExchange; - * - * struct { - * ProtocolVersion client_version; - * opaque random[46]; - * } PreMasterSecret; - * - * struct { - * public-key-encrypted PreMasterSecret pre_master_secret; - * } EncryptedPreMasterSecret; - * - * A public-key-encrypted element is encoded as a vector <0..2^16-1>. - * - * @param c the connection. - * - * @return the ClientKeyExchange byte buffer. - */ -tls.createClientKeyExchange = function(c) { - // create buffer to encrypt - var b = forge.util.createBuffer(); - - // add highest client-supported protocol to help server avoid version - // rollback attacks - b.putByte(c.session.clientHelloVersion.major); - b.putByte(c.session.clientHelloVersion.minor); - - // generate and add 46 random bytes - b.putBytes(forge.random.getBytes(46)); - - // save pre-master secret - var sp = c.session.sp; - sp.pre_master_secret = b.getBytes(); - - // RSA-encrypt the pre-master secret - var key = c.session.serverCertificate.publicKey; - b = key.encrypt(sp.pre_master_secret); - - /* Note: The encrypted pre-master secret will be stored in a - public-key-encrypted opaque vector that has the length prefixed using - 2 bytes, so include those 2 bytes in the handshake message length. This - is done as a minor optimization instead of calling writeVector(). */ - - // determine length of the handshake message - var length = b.length + 2; - - // build record fragment - var rval = forge.util.createBuffer(); - rval.putByte(tls.HandshakeType.client_key_exchange); - rval.putInt24(length); - // add vector length bytes - rval.putInt16(b.length); - rval.putBytes(b); - return rval; -}; - -/** - * Creates a ServerKeyExchange message. - * - * @param c the connection. - * - * @return the ServerKeyExchange byte buffer. - */ -tls.createServerKeyExchange = function(c) { - // this implementation only supports RSA, no Diffie-Hellman support, - // so this record is empty - - // determine length of the handshake message - var length = 0; - - // build record fragment - var rval = forge.util.createBuffer(); - if(length > 0) { - rval.putByte(tls.HandshakeType.server_key_exchange); - rval.putInt24(length); - } - return rval; -}; - -/** - * Gets the signed data used to verify a client-side certificate. See - * tls.createCertificateVerify() for details. - * - * @param c the connection. - * @param callback the callback to call once the signed data is ready. - */ -tls.getClientSignature = function(c, callback) { - // generate data to RSA encrypt - var b = forge.util.createBuffer(); - b.putBuffer(c.session.md5.digest()); - b.putBuffer(c.session.sha1.digest()); - b = b.getBytes(); - - // create default signing function as necessary - c.getSignature = c.getSignature || function(c, b, callback) { - // do rsa encryption, call callback - var privateKey = null; - if(c.getPrivateKey) { - try { - privateKey = c.getPrivateKey(c, c.session.clientCertificate); - privateKey = forge.pki.privateKeyFromPem(privateKey); - } catch(ex) { - c.error(c, { - message: 'Could not get private key.', - cause: ex, - send: true, - alert: { - level: tls.Alert.Level.fatal, - description: tls.Alert.Description.internal_error - } - }); - } - } - if(privateKey === null) { - c.error(c, { - message: 'No private key set.', - send: true, - alert: { - level: tls.Alert.Level.fatal, - description: tls.Alert.Description.internal_error - } - }); - } else { - b = privateKey.sign(b, null); - } - callback(c, b); - }; - - // get client signature - c.getSignature(c, b, callback); -}; - -/** - * Creates a CertificateVerify message. - * - * Meaning of this message: - * This structure conveys the client's Diffie-Hellman public value - * (Yc) if it was not already included in the client's certificate. - * The encoding used for Yc is determined by the enumerated - * PublicValueEncoding. This structure is a variant of the client - * key exchange message, not a message in itself. - * - * When this message will be sent: - * This message is used to provide explicit verification of a client - * certificate. This message is only sent following a client - * certificate that has signing capability (i.e. all certificates - * except those containing fixed Diffie-Hellman parameters). When - * sent, it will immediately follow the client key exchange message. - * - * struct { - * Signature signature; - * } CertificateVerify; - * - * CertificateVerify.signature.md5_hash - * MD5(handshake_messages); - * - * Certificate.signature.sha_hash - * SHA(handshake_messages); - * - * Here handshake_messages refers to all handshake messages sent or - * received starting at client hello up to but not including this - * message, including the type and length fields of the handshake - * messages. - * - * select(SignatureAlgorithm) { - * case anonymous: struct { }; - * case rsa: - * digitally-signed struct { - * opaque md5_hash[16]; - * opaque sha_hash[20]; - * }; - * case dsa: - * digitally-signed struct { - * opaque sha_hash[20]; - * }; - * } Signature; - * - * In digital signing, one-way hash functions are used as input for a - * signing algorithm. A digitally-signed element is encoded as an opaque - * vector <0..2^16-1>, where the length is specified by the signing - * algorithm and key. - * - * In RSA signing, a 36-byte structure of two hashes (one SHA and one - * MD5) is signed (encrypted with the private key). It is encoded with - * PKCS #1 block type 0 or type 1 as described in [PKCS1]. - * - * In DSS, the 20 bytes of the SHA hash are run directly through the - * Digital Signing Algorithm with no additional hashing. - * - * @param c the connection. - * @param signature the signature to include in the message. - * - * @return the CertificateVerify byte buffer. - */ -tls.createCertificateVerify = function(c, signature) { - /* Note: The signature will be stored in a "digitally-signed" opaque - vector that has the length prefixed using 2 bytes, so include those - 2 bytes in the handshake message length. This is done as a minor - optimization instead of calling writeVector(). */ - - // determine length of the handshake message - var length = signature.length + 2; - - // build record fragment - var rval = forge.util.createBuffer(); - rval.putByte(tls.HandshakeType.certificate_verify); - rval.putInt24(length); - // add vector length bytes - rval.putInt16(signature.length); - rval.putBytes(signature); - return rval; -}; - -/** - * Creates a CertificateRequest message. - * - * @param c the connection. - * - * @return the CertificateRequest byte buffer. - */ -tls.createCertificateRequest = function(c) { - // TODO: support other certificate types - var certTypes = forge.util.createBuffer(); - - // common RSA certificate type - certTypes.putByte(0x01); - - // TODO: verify that this data format is correct - // add distinguished names from CA store - var cAs = forge.util.createBuffer(); - for(var key in c.caStore.certs) { - var cert = c.caStore.certs[key]; - var dn = forge.pki.distinguishedNameToAsn1(cert.subject); - cAs.putBuffer(forge.asn1.toDer(dn)); - } - - // TODO: TLS 1.2+ has a different format - - // determine length of the handshake message - var length = - 1 + certTypes.length() + - 2 + cAs.length(); - - // build record fragment - var rval = forge.util.createBuffer(); - rval.putByte(tls.HandshakeType.certificate_request); - rval.putInt24(length); - writeVector(rval, 1, certTypes); - writeVector(rval, 2, cAs); - return rval; -}; - -/** - * Creates a ServerHelloDone message. - * - * @param c the connection. - * - * @return the ServerHelloDone byte buffer. - */ -tls.createServerHelloDone = function(c) { - // build record fragment - var rval = forge.util.createBuffer(); - rval.putByte(tls.HandshakeType.server_hello_done); - rval.putInt24(0); - return rval; -}; - -/** - * Creates a ChangeCipherSpec message. - * - * The change cipher spec protocol exists to signal transitions in - * ciphering strategies. The protocol consists of a single message, - * which is encrypted and compressed under the current (not the pending) - * connection state. The message consists of a single byte of value 1. - * - * struct { - * enum { change_cipher_spec(1), (255) } type; - * } ChangeCipherSpec; - * - * @return the ChangeCipherSpec byte buffer. - */ -tls.createChangeCipherSpec = function() { - var rval = forge.util.createBuffer(); - rval.putByte(0x01); - return rval; -}; - -/** - * Creates a Finished message. - * - * struct { - * opaque verify_data[12]; - * } Finished; - * - * verify_data - * PRF(master_secret, finished_label, MD5(handshake_messages) + - * SHA-1(handshake_messages)) [0..11]; - * - * finished_label - * For Finished messages sent by the client, the string "client - * finished". For Finished messages sent by the server, the - * string "server finished". - * - * handshake_messages - * All of the data from all handshake messages up to but not - * including this message. This is only data visible at the - * handshake layer and does not include record layer headers. - * This is the concatenation of all the Handshake structures as - * defined in 7.4 exchanged thus far. - * - * @param c the connection. - * - * @return the Finished byte buffer. - */ -tls.createFinished = function(c) { - // generate verify_data - var b = forge.util.createBuffer(); - b.putBuffer(c.session.md5.digest()); - b.putBuffer(c.session.sha1.digest()); - - // TODO: determine prf function and verify length for TLS 1.2 - var client = (c.entity === tls.ConnectionEnd.client); - var sp = c.session.sp; - var vdl = 12; - var prf = prf_TLS1; - var label = client ? 'client finished' : 'server finished'; - b = prf(sp.master_secret, label, b.getBytes(), vdl); - - // build record fragment - var rval = forge.util.createBuffer(); - rval.putByte(tls.HandshakeType.finished); - rval.putInt24(b.length()); - rval.putBuffer(b); - return rval; -}; - -/** - * Creates a HeartbeatMessage (See RFC 6520). - * - * struct { - * HeartbeatMessageType type; - * uint16 payload_length; - * opaque payload[HeartbeatMessage.payload_length]; - * opaque padding[padding_length]; - * } HeartbeatMessage; - * - * The total length of a HeartbeatMessage MUST NOT exceed 2^14 or - * max_fragment_length when negotiated as defined in [RFC6066]. - * - * type: The message type, either heartbeat_request or heartbeat_response. - * - * payload_length: The length of the payload. - * - * payload: The payload consists of arbitrary content. - * - * padding: The padding is random content that MUST be ignored by the - * receiver. The length of a HeartbeatMessage is TLSPlaintext.length - * for TLS and DTLSPlaintext.length for DTLS. Furthermore, the - * length of the type field is 1 byte, and the length of the - * payload_length is 2. Therefore, the padding_length is - * TLSPlaintext.length - payload_length - 3 for TLS and - * DTLSPlaintext.length - payload_length - 3 for DTLS. The - * padding_length MUST be at least 16. - * - * The sender of a HeartbeatMessage MUST use a random padding of at - * least 16 bytes. The padding of a received HeartbeatMessage message - * MUST be ignored. - * - * If the payload_length of a received HeartbeatMessage is too large, - * the received HeartbeatMessage MUST be discarded silently. - * - * @param c the connection. - * @param type the tls.HeartbeatMessageType. - * @param payload the heartbeat data to send as the payload. - * @param [payloadLength] the payload length to use, defaults to the - * actual payload length. - * - * @return the HeartbeatRequest byte buffer. - */ -tls.createHeartbeat = function(type, payload, payloadLength) { - if(typeof payloadLength === 'undefined') { - payloadLength = payload.length; - } - // build record fragment - var rval = forge.util.createBuffer(); - rval.putByte(type); // heartbeat message type - rval.putInt16(payloadLength); // payload length - rval.putBytes(payload); // payload - // padding - var plaintextLength = rval.length(); - var paddingLength = Math.max(16, plaintextLength - payloadLength - 3); - rval.putBytes(forge.random.getBytes(paddingLength)); - return rval; -}; - -/** - * Fragments, compresses, encrypts, and queues a record for delivery. - * - * @param c the connection. - * @param record the record to queue. - */ -tls.queue = function(c, record) { - // error during record creation - if(!record) { - return; - } - - // if the record is a handshake record, update handshake hashes - if(record.type === tls.ContentType.handshake) { - var bytes = record.fragment.bytes(); - c.session.md5.update(bytes); - c.session.sha1.update(bytes); - bytes = null; - } - - // handle record fragmentation - var records; - if(record.fragment.length() <= tls.MaxFragment) { - records = [record]; - } else { - // fragment data as long as it is too long - records = []; - var data = record.fragment.bytes(); - while(data.length > tls.MaxFragment) { - records.push(tls.createRecord(c, { - type: record.type, - data: forge.util.createBuffer(data.slice(0, tls.MaxFragment)) - })); - data = data.slice(tls.MaxFragment); - } - // add last record - if(data.length > 0) { - records.push(tls.createRecord(c, { - type: record.type, - data: forge.util.createBuffer(data) - })); - } - } - - // compress and encrypt all fragmented records - for(var i = 0; i < records.length && !c.fail; ++i) { - // update the record using current write state - var rec = records[i]; - var s = c.state.current.write; - if(s.update(c, rec)) { - // store record - c.records.push(rec); - } - } -}; - -/** - * Flushes all queued records to the output buffer and calls the - * tlsDataReady() handler on the given connection. - * - * @param c the connection. - * - * @return true on success, false on failure. - */ -tls.flush = function(c) { - for(var i = 0; i < c.records.length; ++i) { - var record = c.records[i]; - - // add record header and fragment - c.tlsData.putByte(record.type); - c.tlsData.putByte(record.version.major); - c.tlsData.putByte(record.version.minor); - c.tlsData.putInt16(record.fragment.length()); - c.tlsData.putBuffer(c.records[i].fragment); - } - c.records = []; - return c.tlsDataReady(c); -}; - -/** - * Maps a pki.certificateError to a tls.Alert.Description. - * - * @param error the error to map. - * - * @return the alert description. - */ -var _certErrorToAlertDesc = function(error) { - switch(error) { - case true: - return true; - case forge.pki.certificateError.bad_certificate: - return tls.Alert.Description.bad_certificate; - case forge.pki.certificateError.unsupported_certificate: - return tls.Alert.Description.unsupported_certificate; - case forge.pki.certificateError.certificate_revoked: - return tls.Alert.Description.certificate_revoked; - case forge.pki.certificateError.certificate_expired: - return tls.Alert.Description.certificate_expired; - case forge.pki.certificateError.certificate_unknown: - return tls.Alert.Description.certificate_unknown; - case forge.pki.certificateError.unknown_ca: - return tls.Alert.Description.unknown_ca; - default: - return tls.Alert.Description.bad_certificate; - } -}; - -/** - * Maps a tls.Alert.Description to a pki.certificateError. - * - * @param desc the alert description. - * - * @return the certificate error. - */ -var _alertDescToCertError = function(desc) { - switch(desc) { - case true: - return true; - case tls.Alert.Description.bad_certificate: - return forge.pki.certificateError.bad_certificate; - case tls.Alert.Description.unsupported_certificate: - return forge.pki.certificateError.unsupported_certificate; - case tls.Alert.Description.certificate_revoked: - return forge.pki.certificateError.certificate_revoked; - case tls.Alert.Description.certificate_expired: - return forge.pki.certificateError.certificate_expired; - case tls.Alert.Description.certificate_unknown: - return forge.pki.certificateError.certificate_unknown; - case tls.Alert.Description.unknown_ca: - return forge.pki.certificateError.unknown_ca; - default: - return forge.pki.certificateError.bad_certificate; - } -}; - -/** - * Verifies a certificate chain against the given connection's - * Certificate Authority store. - * - * @param c the TLS connection. - * @param chain the certificate chain to verify, with the root or highest - * authority at the end. - * - * @return true if successful, false if not. - */ -tls.verifyCertificateChain = function(c, chain) { - try { - // verify chain - forge.pki.verifyCertificateChain(c.caStore, chain, - function verify(vfd, depth, chain) { - // convert pki.certificateError to tls alert description - var desc = _certErrorToAlertDesc(vfd); - - // call application callback - var ret = c.verify(c, vfd, depth, chain); - if(ret !== true) { - if(typeof ret === 'object' && !forge.util.isArray(ret)) { - // throw custom error - var error = new Error('The application rejected the certificate.'); - error.send = true; - error.alert = { - level: tls.Alert.Level.fatal, - description: tls.Alert.Description.bad_certificate - }; - if(ret.message) { - error.message = ret.message; - } - if(ret.alert) { - error.alert.description = ret.alert; - } - throw error; - } - - // convert tls alert description to pki.certificateError - if(ret !== vfd) { - ret = _alertDescToCertError(ret); - } - } - - return ret; - }); - } catch(ex) { - // build tls error if not already customized - var err = ex; - if(typeof err !== 'object' || forge.util.isArray(err)) { - err = { - send: true, - alert: { - level: tls.Alert.Level.fatal, - description: _certErrorToAlertDesc(ex) - } - }; - } - if(!('send' in err)) { - err.send = true; - } - if(!('alert' in err)) { - err.alert = { - level: tls.Alert.Level.fatal, - description: _certErrorToAlertDesc(err.error) - }; - } - - // send error - c.error(c, err); - } - - return !c.fail; -}; - -/** - * Creates a new TLS session cache. - * - * @param cache optional map of session ID to cached session. - * @param capacity the maximum size for the cache (default: 100). - * - * @return the new TLS session cache. - */ -tls.createSessionCache = function(cache, capacity) { - var rval = null; - - // assume input is already a session cache object - if(cache && cache.getSession && cache.setSession && cache.order) { - rval = cache; - } else { - // create cache - rval = {}; - rval.cache = cache || {}; - rval.capacity = Math.max(capacity || 100, 1); - rval.order = []; - - // store order for sessions, delete session overflow - for(var key in cache) { - if(rval.order.length <= capacity) { - rval.order.push(key); - } else { - delete cache[key]; - } - } - - // get a session from a session ID (or get any session) - rval.getSession = function(sessionId) { - var session = null; - var key = null; - - // if session ID provided, use it - if(sessionId) { - key = forge.util.bytesToHex(sessionId); - } else if(rval.order.length > 0) { - // get first session from cache - key = rval.order[0]; - } - - if(key !== null && key in rval.cache) { - // get cached session and remove from cache - session = rval.cache[key]; - delete rval.cache[key]; - for(var i in rval.order) { - if(rval.order[i] === key) { - rval.order.splice(i, 1); - break; - } - } - } - - return session; - }; - - // set a session in the cache - rval.setSession = function(sessionId, session) { - // remove session from cache if at capacity - if(rval.order.length === rval.capacity) { - var key = rval.order.shift(); - delete rval.cache[key]; - } - // add session to cache - var key = forge.util.bytesToHex(sessionId); - rval.order.push(key); - rval.cache[key] = session; - }; - } - - return rval; -}; - -/** - * Creates a new TLS connection. - * - * See public createConnection() docs for more details. - * - * @param options the options for this connection. - * - * @return the new TLS connection. - */ -tls.createConnection = function(options) { - var caStore = null; - if(options.caStore) { - // if CA store is an array, convert it to a CA store object - if(forge.util.isArray(options.caStore)) { - caStore = forge.pki.createCaStore(options.caStore); - } else { - caStore = options.caStore; - } - } else { - // create empty CA store - caStore = forge.pki.createCaStore(); - } - - // setup default cipher suites - var cipherSuites = options.cipherSuites || null; - if(cipherSuites === null) { - cipherSuites = []; - for(var key in tls.CipherSuites) { - cipherSuites.push(tls.CipherSuites[key]); - } - } - - // set default entity - var entity = (options.server || false) ? - tls.ConnectionEnd.server : tls.ConnectionEnd.client; - - // create session cache if requested - var sessionCache = options.sessionCache ? - tls.createSessionCache(options.sessionCache) : null; - - // create TLS connection - var c = { - version: {major: tls.Version.major, minor: tls.Version.minor}, - entity: entity, - sessionId: options.sessionId, - caStore: caStore, - sessionCache: sessionCache, - cipherSuites: cipherSuites, - connected: options.connected, - virtualHost: options.virtualHost || null, - verifyClient: options.verifyClient || false, - verify: options.verify || function(cn, vfd, dpth, cts) {return vfd;}, - getCertificate: options.getCertificate || null, - getPrivateKey: options.getPrivateKey || null, - getSignature: options.getSignature || null, - input: forge.util.createBuffer(), - tlsData: forge.util.createBuffer(), - data: forge.util.createBuffer(), - tlsDataReady: options.tlsDataReady, - dataReady: options.dataReady, - heartbeatReceived: options.heartbeatReceived, - closed: options.closed, - error: function(c, ex) { - // set origin if not set - ex.origin = ex.origin || - ((c.entity === tls.ConnectionEnd.client) ? 'client' : 'server'); - - // send TLS alert - if(ex.send) { - tls.queue(c, tls.createAlert(c, ex.alert)); - tls.flush(c); - } - - // error is fatal by default - var fatal = (ex.fatal !== false); - if(fatal) { - // set fail flag - c.fail = true; - } - - // call error handler first - options.error(c, ex); - - if(fatal) { - // fatal error, close connection, do not clear fail - c.close(false); - } - }, - deflate: options.deflate || null, - inflate: options.inflate || null - }; - - /** - * Resets a closed TLS connection for reuse. Called in c.close(). - * - * @param clearFail true to clear the fail flag (default: true). - */ - c.reset = function(clearFail) { - c.version = {major: tls.Version.major, minor: tls.Version.minor}; - c.record = null; - c.session = null; - c.peerCertificate = null; - c.state = { - pending: null, - current: null - }; - c.expect = (c.entity === tls.ConnectionEnd.client) ? SHE : CHE; - c.fragmented = null; - c.records = []; - c.open = false; - c.handshakes = 0; - c.handshaking = false; - c.isConnected = false; - c.fail = !(clearFail || typeof(clearFail) === 'undefined'); - c.input.clear(); - c.tlsData.clear(); - c.data.clear(); - c.state.current = tls.createConnectionState(c); - }; - - // do initial reset of connection - c.reset(); - - /** - * Updates the current TLS engine state based on the given record. - * - * @param c the TLS connection. - * @param record the TLS record to act on. - */ - var _update = function(c, record) { - // get record handler (align type in table by subtracting lowest) - var aligned = record.type - tls.ContentType.change_cipher_spec; - var handlers = ctTable[c.entity][c.expect]; - if(aligned in handlers) { - handlers[aligned](c, record); - } else { - // unexpected record - tls.handleUnexpected(c, record); - } - }; - - /** - * Reads the record header and initializes the next record on the given - * connection. - * - * @param c the TLS connection with the next record. - * - * @return 0 if the input data could be processed, otherwise the - * number of bytes required for data to be processed. - */ - var _readRecordHeader = function(c) { - var rval = 0; - - // get input buffer and its length - var b = c.input; - var len = b.length(); - - // need at least 5 bytes to initialize a record - if(len < 5) { - rval = 5 - len; - } else { - // enough bytes for header - // initialize record - c.record = { - type: b.getByte(), - version: { - major: b.getByte(), - minor: b.getByte() - }, - length: b.getInt16(), - fragment: forge.util.createBuffer(), - ready: false - }; - - // check record version - var compatibleVersion = (c.record.version.major === c.version.major); - if(compatibleVersion && c.session && c.session.version) { - // session version already set, require same minor version - compatibleVersion = (c.record.version.minor === c.version.minor); - } - if(!compatibleVersion) { - c.error(c, { - message: 'Incompatible TLS version.', - send: true, - alert: { - level: tls.Alert.Level.fatal, - description: tls.Alert.Description.protocol_version - } - }); - } - } - - return rval; - }; - - /** - * Reads the next record's contents and appends its message to any - * previously fragmented message. - * - * @param c the TLS connection with the next record. - * - * @return 0 if the input data could be processed, otherwise the - * number of bytes required for data to be processed. - */ - var _readRecord = function(c) { - var rval = 0; - - // ensure there is enough input data to get the entire record - var b = c.input; - var len = b.length(); - if(len < c.record.length) { - // not enough data yet, return how much is required - rval = c.record.length - len; - } else { - // there is enough data to parse the pending record - // fill record fragment and compact input buffer - c.record.fragment.putBytes(b.getBytes(c.record.length)); - b.compact(); - - // update record using current read state - var s = c.state.current.read; - if(s.update(c, c.record)) { - // see if there is a previously fragmented message that the - // new record's message fragment should be appended to - if(c.fragmented !== null) { - // if the record type matches a previously fragmented - // record, append the record fragment to it - if(c.fragmented.type === c.record.type) { - // concatenate record fragments - c.fragmented.fragment.putBuffer(c.record.fragment); - c.record = c.fragmented; - } else { - // error, invalid fragmented record - c.error(c, { - message: 'Invalid fragmented record.', - send: true, - alert: { - level: tls.Alert.Level.fatal, - description: - tls.Alert.Description.unexpected_message - } - }); - } - } - - // record is now ready - c.record.ready = true; - } - } - - return rval; - }; - - /** - * Performs a handshake using the TLS Handshake Protocol, as a client. - * - * This method should only be called if the connection is in client mode. - * - * @param sessionId the session ID to use, null to start a new one. - */ - c.handshake = function(sessionId) { - // error to call this in non-client mode - if(c.entity !== tls.ConnectionEnd.client) { - // not fatal error - c.error(c, { - message: 'Cannot initiate handshake as a server.', - fatal: false - }); - } else if(c.handshaking) { - // handshake is already in progress, fail but not fatal error - c.error(c, { - message: 'Handshake already in progress.', - fatal: false - }); - } else { - // clear fail flag on reuse - if(c.fail && !c.open && c.handshakes === 0) { - c.fail = false; - } - - // now handshaking - c.handshaking = true; - - // default to blank (new session) - sessionId = sessionId || ''; - - // if a session ID was specified, try to find it in the cache - var session = null; - if(sessionId.length > 0) { - if(c.sessionCache) { - session = c.sessionCache.getSession(sessionId); - } - - // matching session not found in cache, clear session ID - if(session === null) { - sessionId = ''; - } - } - - // no session given, grab a session from the cache, if available - if(sessionId.length === 0 && c.sessionCache) { - session = c.sessionCache.getSession(); - if(session !== null) { - sessionId = session.id; - } - } - - // set up session - c.session = { - id: sessionId, - version: null, - cipherSuite: null, - compressionMethod: null, - serverCertificate: null, - certificateRequest: null, - clientCertificate: null, - sp: {}, - md5: forge.md.md5.create(), - sha1: forge.md.sha1.create() - }; - - // use existing session information - if(session) { - // only update version on connection, session version not yet set - c.version = session.version; - c.session.sp = session.sp; - } - - // generate new client random - c.session.sp.client_random = tls.createRandom().getBytes(); - - // connection now open - c.open = true; - - // send hello - tls.queue(c, tls.createRecord(c, { - type: tls.ContentType.handshake, - data: tls.createClientHello(c) - })); - tls.flush(c); - } - }; - - /** - * Called when TLS protocol data has been received from somewhere and should - * be processed by the TLS engine. - * - * @param data the TLS protocol data, as a string, to process. - * - * @return 0 if the data could be processed, otherwise the number of bytes - * required for data to be processed. - */ - c.process = function(data) { - var rval = 0; - - // buffer input data - if(data) { - c.input.putBytes(data); - } - - // process next record if no failure, process will be called after - // each record is handled (since handling can be asynchronous) - if(!c.fail) { - // reset record if ready and now empty - if(c.record !== null && - c.record.ready && c.record.fragment.isEmpty()) { - c.record = null; - } - - // if there is no pending record, try to read record header - if(c.record === null) { - rval = _readRecordHeader(c); - } - - // read the next record (if record not yet ready) - if(!c.fail && c.record !== null && !c.record.ready) { - rval = _readRecord(c); - } - - // record ready to be handled, update engine state - if(!c.fail && c.record !== null && c.record.ready) { - _update(c, c.record); - } - } - - return rval; - }; - - /** - * Requests that application data be packaged into a TLS record. The - * tlsDataReady handler will be called when the TLS record(s) have been - * prepared. - * - * @param data the application data, as a raw 'binary' encoded string, to - * be sent; to send utf-16/utf-8 string data, use the return value - * of util.encodeUtf8(str). - * - * @return true on success, false on failure. - */ - c.prepare = function(data) { - tls.queue(c, tls.createRecord(c, { - type: tls.ContentType.application_data, - data: forge.util.createBuffer(data) - })); - return tls.flush(c); - }; - - /** - * Requests that a heartbeat request be packaged into a TLS record for - * transmission. The tlsDataReady handler will be called when TLS record(s) - * have been prepared. - * - * When a heartbeat response has been received, the heartbeatReceived - * handler will be called with the matching payload. This handler can - * be used to clear a retransmission timer, etc. - * - * @param payload the heartbeat data to send as the payload in the message. - * @param [payloadLength] the payload length to use, defaults to the - * actual payload length. - * - * @return true on success, false on failure. - */ - c.prepareHeartbeatRequest = function(payload, payloadLength) { - if(payload instanceof forge.util.ByteBuffer) { - payload = payload.bytes(); - } - if(typeof payloadLength === 'undefined') { - payloadLength = payload.length; - } - c.expectedHeartbeatPayload = payload; - tls.queue(c, tls.createRecord(c, { - type: tls.ContentType.heartbeat, - data: tls.createHeartbeat( - tls.HeartbeatMessageType.heartbeat_request, payload, payloadLength) - })); - return tls.flush(c); - }; - - /** - * Closes the connection (sends a close_notify alert). - * - * @param clearFail true to clear the fail flag (default: true). - */ - c.close = function(clearFail) { - // save session if connection didn't fail - if(!c.fail && c.sessionCache && c.session) { - // only need to preserve session ID, version, and security params - var session = { - id: c.session.id, - version: c.session.version, - sp: c.session.sp - }; - session.sp.keys = null; - c.sessionCache.setSession(session.id, session); - } - - if(c.open) { - // connection no longer open, clear input - c.open = false; - c.input.clear(); - - // if connected or handshaking, send an alert - if(c.isConnected || c.handshaking) { - c.isConnected = c.handshaking = false; - - // send close_notify alert - tls.queue(c, tls.createAlert(c, { - level: tls.Alert.Level.warning, - description: tls.Alert.Description.close_notify - })); - tls.flush(c); - } - - // call handler - c.closed(c); - } - - // reset TLS connection, do not clear fail flag - c.reset(clearFail); - }; - - return c; -}; - -/* TLS API */ -forge.tls = forge.tls || {}; - -// expose non-functions -for(var key in tls) { - if(typeof tls[key] !== 'function') { - forge.tls[key] = tls[key]; - } -} - -// expose prf_tls1 for testing -forge.tls.prf_tls1 = prf_TLS1; - -// expose sha1 hmac method -forge.tls.hmac_sha1 = hmac_sha1; - -// expose session cache creation -forge.tls.createSessionCache = tls.createSessionCache; - -/** - * Creates a new TLS connection. This does not make any assumptions about the - * transport layer that TLS is working on top of, ie: it does not assume there - * is a TCP/IP connection or establish one. A TLS connection is totally - * abstracted away from the layer is runs on top of, it merely establishes a - * secure channel between a client" and a "server". - * - * A TLS connection contains 4 connection states: pending read and write, and - * current read and write. - * - * At initialization, the current read and write states will be null. Only once - * the security parameters have been set and the keys have been generated can - * the pending states be converted into current states. Current states will be - * updated for each record processed. - * - * A custom certificate verify callback may be provided to check information - * like the common name on the server's certificate. It will be called for - * every certificate in the chain. It has the following signature: - * - * variable func(c, certs, index, preVerify) - * Where: - * c The TLS connection - * verified Set to true if certificate was verified, otherwise the alert - * tls.Alert.Description for why the certificate failed. - * depth The current index in the chain, where 0 is the server's cert. - * certs The certificate chain, *NOTE* if the server was anonymous then - * the chain will be empty. - * - * The function returns true on success and on failure either the appropriate - * tls.Alert.Description or an object with 'alert' set to the appropriate - * tls.Alert.Description and 'message' set to a custom error message. If true - * is not returned then the connection will abort using, in order of - * availability, first the returned alert description, second the preVerify - * alert description, and lastly the default 'bad_certificate'. - * - * There are three callbacks that can be used to make use of client-side - * certificates where each takes the TLS connection as the first parameter: - * - * getCertificate(conn, hint) - * The second parameter is a hint as to which certificate should be - * returned. If the connection entity is a client, then the hint will be - * the CertificateRequest message from the server that is part of the - * TLS protocol. If the connection entity is a server, then it will be - * the servername list provided via an SNI extension the ClientHello, if - * one was provided (empty array if not). The hint can be examined to - * determine which certificate to use (advanced). Most implementations - * will just return a certificate. The return value must be a - * PEM-formatted certificate or an array of PEM-formatted certificates - * that constitute a certificate chain, with the first in the array/chain - * being the client's certificate. - * getPrivateKey(conn, certificate) - * The second parameter is an forge.pki X.509 certificate object that - * is associated with the requested private key. The return value must - * be a PEM-formatted private key. - * getSignature(conn, bytes, callback) - * This callback can be used instead of getPrivateKey if the private key - * is not directly accessible in javascript or should not be. For - * instance, a secure external web service could provide the signature - * in exchange for appropriate credentials. The second parameter is a - * string of bytes to be signed that are part of the TLS protocol. These - * bytes are used to verify that the private key for the previously - * provided client-side certificate is accessible to the client. The - * callback is a function that takes 2 parameters, the TLS connection - * and the RSA encrypted (signed) bytes as a string. This callback must - * be called once the signature is ready. - * - * @param options the options for this connection: - * server: true if the connection is server-side, false for client. - * sessionId: a session ID to reuse, null for a new connection. - * caStore: an array of certificates to trust. - * sessionCache: a session cache to use. - * cipherSuites: an optional array of cipher suites to use, - * see tls.CipherSuites. - * connected: function(conn) called when the first handshake completes. - * virtualHost: the virtual server name to use in a TLS SNI extension. - * verifyClient: true to require a client certificate in server mode, - * 'optional' to request one, false not to (default: false). - * verify: a handler used to custom verify certificates in the chain. - * getCertificate: an optional callback used to get a certificate or - * a chain of certificates (as an array). - * getPrivateKey: an optional callback used to get a private key. - * getSignature: an optional callback used to get a signature. - * tlsDataReady: function(conn) called when TLS protocol data has been - * prepared and is ready to be used (typically sent over a socket - * connection to its destination), read from conn.tlsData buffer. - * dataReady: function(conn) called when application data has - * been parsed from a TLS record and should be consumed by the - * application, read from conn.data buffer. - * closed: function(conn) called when the connection has been closed. - * error: function(conn, error) called when there was an error. - * deflate: function(inBytes) if provided, will deflate TLS records using - * the deflate algorithm if the server supports it. - * inflate: function(inBytes) if provided, will inflate TLS records using - * the deflate algorithm if the server supports it. - * - * @return the new TLS connection. - */ -forge.tls.createConnection = tls.createConnection; - -} // end module implementation - -/* ########## Begin module wrapper ########## */ -var name = 'tls'; -if(typeof define !== 'function') { - // NodeJS -> AMD - if(typeof module === 'object' && module.exports) { - var nodeJS = true; - define = function(ids, factory) { - factory(require, module); - }; - } else { - // <script> - if(typeof forge === 'undefined') { - forge = {}; - } - return initModule(forge); - } -} -// AMD -var deps; -var defineFunc = function(require, module) { - module.exports = function(forge) { - var mods = deps.map(function(dep) { - return require(dep); - }).concat(initModule); - // handle circular dependencies - forge = forge || {}; - forge.defined = forge.defined || {}; - if(forge.defined[name]) { - return forge[name]; - } - forge.defined[name] = true; - for(var i = 0; i < mods.length; ++i) { - mods[i](forge); - } - return forge[name]; - }; -}; -var tmpDefine = define; -define = function(ids, factory) { - deps = (typeof ids === 'string') ? factory.slice(2) : ids.slice(2); - if(nodeJS) { - delete define; - return tmpDefine.apply(null, Array.prototype.slice.call(arguments, 0)); - } - define = tmpDefine; - return define.apply(null, Array.prototype.slice.call(arguments, 0)); -}; -define([ - 'require', - 'module', - './asn1', - './hmac', - './md', - './pem', - './pki', - './random', - './util'], function() { - defineFunc.apply(null, Array.prototype.slice.call(arguments, 0)); -}); -})(); diff --git a/alarm/node_modules/node-forge/js/tlssocket.js b/alarm/node_modules/node-forge/js/tlssocket.js deleted file mode 100644 index 9a00ea2..0000000 --- a/alarm/node_modules/node-forge/js/tlssocket.js +++ /dev/null @@ -1,304 +0,0 @@ -/** - * Socket wrapping functions for TLS. - * - * @author Dave Longley - * - * Copyright (c) 2009-2012 Digital Bazaar, Inc. - */ -(function() { -/* ########## Begin module implementation ########## */ -function initModule(forge) { - -/** - * Wraps a forge.net socket with a TLS layer. - * - * @param options: - * sessionId: a session ID to reuse, null for a new connection if no session - * cache is provided or it is empty. - * caStore: an array of certificates to trust. - * sessionCache: a session cache to use. - * cipherSuites: an optional array of cipher suites to use, see - * tls.CipherSuites. - * socket: the socket to wrap. - * virtualHost: the virtual server name to use in a TLS SNI extension. - * verify: a handler used to custom verify certificates in the chain. - * getCertificate: an optional callback used to get a certificate. - * getPrivateKey: an optional callback used to get a private key. - * getSignature: an optional callback used to get a signature. - * deflate: function(inBytes) if provided, will deflate TLS records using - * the deflate algorithm if the server supports it. - * inflate: function(inBytes) if provided, will inflate TLS records using - * the deflate algorithm if the server supports it. - * - * @return the TLS-wrapped socket. - */ -forge.tls.wrapSocket = function(options) { - // get raw socket - var socket = options.socket; - - // create TLS socket - var tlsSocket = { - id: socket.id, - // set handlers - connected: socket.connected || function(e){}, - closed: socket.closed || function(e){}, - data: socket.data || function(e){}, - error: socket.error || function(e){} - }; - - // create TLS connection - var c = forge.tls.createConnection({ - server: false, - sessionId: options.sessionId || null, - caStore: options.caStore || [], - sessionCache: options.sessionCache || null, - cipherSuites: options.cipherSuites || null, - virtualHost: options.virtualHost, - verify: options.verify, - getCertificate: options.getCertificate, - getPrivateKey: options.getPrivateKey, - getSignature: options.getSignature, - deflate: options.deflate, - inflate: options.inflate, - connected: function(c) { - // first handshake complete, call handler - if(c.handshakes === 1) { - tlsSocket.connected({ - id: socket.id, - type: 'connect', - bytesAvailable: c.data.length() - }); - } - }, - tlsDataReady: function(c) { - // send TLS data over socket - return socket.send(c.tlsData.getBytes()); - }, - dataReady: function(c) { - // indicate application data is ready - tlsSocket.data({ - id: socket.id, - type: 'socketData', - bytesAvailable: c.data.length() - }); - }, - closed: function(c) { - // close socket - socket.close(); - }, - error: function(c, e) { - // send error, close socket - tlsSocket.error({ - id: socket.id, - type: 'tlsError', - message: e.message, - bytesAvailable: 0, - error: e - }); - socket.close(); - } - }); - - // handle doing handshake after connecting - socket.connected = function(e) { - c.handshake(options.sessionId); - }; - - // handle closing TLS connection - socket.closed = function(e) { - if(c.open && c.handshaking) { - // error - tlsSocket.error({ - id: socket.id, - type: 'ioError', - message: 'Connection closed during handshake.', - bytesAvailable: 0 - }); - } - c.close(); - - // call socket handler - tlsSocket.closed({ - id: socket.id, - type: 'close', - bytesAvailable: 0 - }); - }; - - // handle error on socket - socket.error = function(e) { - // error - tlsSocket.error({ - id: socket.id, - type: e.type, - message: e.message, - bytesAvailable: 0 - }); - c.close(); - }; - - // handle receiving raw TLS data from socket - var _requiredBytes = 0; - socket.data = function(e) { - // drop data if connection not open - if(!c.open) { - socket.receive(e.bytesAvailable); - } else { - // only receive if there are enough bytes available to - // process a record - if(e.bytesAvailable >= _requiredBytes) { - var count = Math.max(e.bytesAvailable, _requiredBytes); - var data = socket.receive(count); - if(data !== null) { - _requiredBytes = c.process(data); - } - } - } - }; - - /** - * Destroys this socket. - */ - tlsSocket.destroy = function() { - socket.destroy(); - }; - - /** - * Sets this socket's TLS session cache. This should be called before - * the socket is connected or after it is closed. - * - * The cache is an object mapping session IDs to internal opaque state. - * An application might need to change the cache used by a particular - * tlsSocket between connections if it accesses multiple TLS hosts. - * - * @param cache the session cache to use. - */ - tlsSocket.setSessionCache = function(cache) { - c.sessionCache = tls.createSessionCache(cache); - }; - - /** - * Connects this socket. - * - * @param options: - * host: the host to connect to. - * port: the port to connect to. - * policyPort: the policy port to use (if non-default), 0 to - * use the flash default. - * policyUrl: the policy file URL to use (instead of port). - */ - tlsSocket.connect = function(options) { - socket.connect(options); - }; - - /** - * Closes this socket. - */ - tlsSocket.close = function() { - c.close(); - }; - - /** - * Determines if the socket is connected or not. - * - * @return true if connected, false if not. - */ - tlsSocket.isConnected = function() { - return c.isConnected && socket.isConnected(); - }; - - /** - * Writes bytes to this socket. - * - * @param bytes the bytes (as a string) to write. - * - * @return true on success, false on failure. - */ - tlsSocket.send = function(bytes) { - return c.prepare(bytes); - }; - - /** - * Reads bytes from this socket (non-blocking). Fewer than the number of - * bytes requested may be read if enough bytes are not available. - * - * This method should be called from the data handler if there are enough - * bytes available. To see how many bytes are available, check the - * 'bytesAvailable' property on the event in the data handler or call the - * bytesAvailable() function on the socket. If the browser is msie, then the - * bytesAvailable() function should be used to avoid race conditions. - * Otherwise, using the property on the data handler's event may be quicker. - * - * @param count the maximum number of bytes to read. - * - * @return the bytes read (as a string) or null on error. - */ - tlsSocket.receive = function(count) { - return c.data.getBytes(count); - }; - - /** - * Gets the number of bytes available for receiving on the socket. - * - * @return the number of bytes available for receiving. - */ - tlsSocket.bytesAvailable = function() { - return c.data.length(); - }; - - return tlsSocket; -}; - -} // end module implementation - -/* ########## Begin module wrapper ########## */ -var name = 'tlssocket'; -if(typeof define !== 'function') { - // NodeJS -> AMD - if(typeof module === 'object' && module.exports) { - var nodeJS = true; - define = function(ids, factory) { - factory(require, module); - }; - } else { - // <script> - if(typeof forge === 'undefined') { - forge = {}; - } - return initModule(forge); - } -} -// AMD -var deps; -var defineFunc = function(require, module) { - module.exports = function(forge) { - var mods = deps.map(function(dep) { - return require(dep); - }).concat(initModule); - // handle circular dependencies - forge = forge || {}; - forge.defined = forge.defined || {}; - if(forge.defined[name]) { - return forge[name]; - } - forge.defined[name] = true; - for(var i = 0; i < mods.length; ++i) { - mods[i](forge); - } - return forge[name]; - }; -}; -var tmpDefine = define; -define = function(ids, factory) { - deps = (typeof ids === 'string') ? factory.slice(2) : ids.slice(2); - if(nodeJS) { - delete define; - return tmpDefine.apply(null, Array.prototype.slice.call(arguments, 0)); - } - define = tmpDefine; - return define.apply(null, Array.prototype.slice.call(arguments, 0)); -}; -define(['require', 'module', './tls'], function() { - defineFunc.apply(null, Array.prototype.slice.call(arguments, 0)); -}); -})(); diff --git a/alarm/node_modules/node-forge/js/util.js b/alarm/node_modules/node-forge/js/util.js deleted file mode 100644 index 294c41b..0000000 --- a/alarm/node_modules/node-forge/js/util.js +++ /dev/null @@ -1,2988 +0,0 @@ -/** - * Utility functions for web applications. - * - * @author Dave Longley - * - * Copyright (c) 2010-2014 Digital Bazaar, Inc. - */ -(function() { -/* ########## Begin module implementation ########## */ -function initModule(forge) { - -/* Utilities API */ -var util = forge.util = forge.util || {}; - -// define setImmediate and nextTick -(function() { - // use native nextTick - if(typeof process !== 'undefined' && process.nextTick) { - util.nextTick = process.nextTick; - if(typeof setImmediate === 'function') { - util.setImmediate = setImmediate; - } else { - // polyfill setImmediate with nextTick, older versions of node - // (those w/o setImmediate) won't totally starve IO - util.setImmediate = util.nextTick; - } - return; - } - - // polyfill nextTick with native setImmediate - if(typeof setImmediate === 'function') { - util.setImmediate = setImmediate; - util.nextTick = function(callback) { - return setImmediate(callback); - }; - return; - } - - /* Note: A polyfill upgrade pattern is used here to allow combining - polyfills. For example, MutationObserver is fast, but blocks UI updates, - so it needs to allow UI updates periodically, so it falls back on - postMessage or setTimeout. */ - - // polyfill with setTimeout - util.setImmediate = function(callback) { - setTimeout(callback, 0); - }; - - // upgrade polyfill to use postMessage - if(typeof window !== 'undefined' && - typeof window.postMessage === 'function') { - var msg = 'forge.setImmediate'; - var callbacks = []; - util.setImmediate = function(callback) { - callbacks.push(callback); - // only send message when one hasn't been sent in - // the current turn of the event loop - if(callbacks.length === 1) { - window.postMessage(msg, '*'); - } - }; - function handler(event) { - if(event.source === window && event.data === msg) { - event.stopPropagation(); - var copy = callbacks.slice(); - callbacks.length = 0; - copy.forEach(function(callback) { - callback(); - }); - } - } - window.addEventListener('message', handler, true); - } - - // upgrade polyfill to use MutationObserver - if(typeof MutationObserver !== 'undefined') { - // polyfill with MutationObserver - var now = Date.now(); - var attr = true; - var div = document.createElement('div'); - var callbacks = []; - new MutationObserver(function() { - var copy = callbacks.slice(); - callbacks.length = 0; - copy.forEach(function(callback) { - callback(); - }); - }).observe(div, {attributes: true}); - var oldSetImmediate = util.setImmediate; - util.setImmediate = function(callback) { - if(Date.now() - now > 15) { - now = Date.now(); - oldSetImmediate(callback); - } else { - callbacks.push(callback); - // only trigger observer when it hasn't been triggered in - // the current turn of the event loop - if(callbacks.length === 1) { - div.setAttribute('a', attr = !attr); - } - } - }; - } - - util.nextTick = util.setImmediate; -})(); - -// define isArray -util.isArray = Array.isArray || function(x) { - return Object.prototype.toString.call(x) === '[object Array]'; -}; - -// define isArrayBuffer -util.isArrayBuffer = function(x) { - return typeof ArrayBuffer !== 'undefined' && x instanceof ArrayBuffer; -}; - -// define isArrayBufferView -util.isArrayBufferView = function(x) { - return x && util.isArrayBuffer(x.buffer) && x.byteLength !== undefined; -}; - -// TODO: set ByteBuffer to best available backing -util.ByteBuffer = ByteStringBuffer; - -/** Buffer w/BinaryString backing */ - -/** - * Constructor for a binary string backed byte buffer. - * - * @param [b] the bytes to wrap (either encoded as string, one byte per - * character, or as an ArrayBuffer or Typed Array). - */ -function ByteStringBuffer(b) { - // TODO: update to match DataBuffer API - - // the data in this buffer - this.data = ''; - // the pointer for reading from this buffer - this.read = 0; - - if(typeof b === 'string') { - this.data = b; - } else if(util.isArrayBuffer(b) || util.isArrayBufferView(b)) { - // convert native buffer to forge buffer - // FIXME: support native buffers internally instead - var arr = new Uint8Array(b); - try { - this.data = String.fromCharCode.apply(null, arr); - } catch(e) { - for(var i = 0; i < arr.length; ++i) { - this.putByte(arr[i]); - } - } - } else if(b instanceof ByteStringBuffer || - (typeof b === 'object' && typeof b.data === 'string' && - typeof b.read === 'number')) { - // copy existing buffer - this.data = b.data; - this.read = b.read; - } - - // used for v8 optimization - this._constructedStringLength = 0; -} -util.ByteStringBuffer = ByteStringBuffer; - -/* Note: This is an optimization for V8-based browsers. When V8 concatenates - a string, the strings are only joined logically using a "cons string" or - "constructed/concatenated string". These containers keep references to one - another and can result in very large memory usage. For example, if a 2MB - string is constructed by concatenating 4 bytes together at a time, the - memory usage will be ~44MB; so ~22x increase. The strings are only joined - together when an operation requiring their joining takes place, such as - substr(). This function is called when adding data to this buffer to ensure - these types of strings are periodically joined to reduce the memory - footprint. */ -var _MAX_CONSTRUCTED_STRING_LENGTH = 4096; -util.ByteStringBuffer.prototype._optimizeConstructedString = function(x) { - this._constructedStringLength += x; - if(this._constructedStringLength > _MAX_CONSTRUCTED_STRING_LENGTH) { - // this substr() should cause the constructed string to join - this.data.substr(0, 1); - this._constructedStringLength = 0; - } -}; - -/** - * Gets the number of bytes in this buffer. - * - * @return the number of bytes in this buffer. - */ -util.ByteStringBuffer.prototype.length = function() { - return this.data.length - this.read; -}; - -/** - * Gets whether or not this buffer is empty. - * - * @return true if this buffer is empty, false if not. - */ -util.ByteStringBuffer.prototype.isEmpty = function() { - return this.length() <= 0; -}; - -/** - * Puts a byte in this buffer. - * - * @param b the byte to put. - * - * @return this buffer. - */ -util.ByteStringBuffer.prototype.putByte = function(b) { - return this.putBytes(String.fromCharCode(b)); -}; - -/** - * Puts a byte in this buffer N times. - * - * @param b the byte to put. - * @param n the number of bytes of value b to put. - * - * @return this buffer. - */ -util.ByteStringBuffer.prototype.fillWithByte = function(b, n) { - b = String.fromCharCode(b); - var d = this.data; - while(n > 0) { - if(n & 1) { - d += b; - } - n >>>= 1; - if(n > 0) { - b += b; - } - } - this.data = d; - this._optimizeConstructedString(n); - return this; -}; - -/** - * Puts bytes in this buffer. - * - * @param bytes the bytes (as a UTF-8 encoded string) to put. - * - * @return this buffer. - */ -util.ByteStringBuffer.prototype.putBytes = function(bytes) { - this.data += bytes; - this._optimizeConstructedString(bytes.length); - return this; -}; - -/** - * Puts a UTF-16 encoded string into this buffer. - * - * @param str the string to put. - * - * @return this buffer. - */ -util.ByteStringBuffer.prototype.putString = function(str) { - return this.putBytes(util.encodeUtf8(str)); -}; - -/** - * Puts a 16-bit integer in this buffer in big-endian order. - * - * @param i the 16-bit integer. - * - * @return this buffer. - */ -util.ByteStringBuffer.prototype.putInt16 = function(i) { - return this.putBytes( - String.fromCharCode(i >> 8 & 0xFF) + - String.fromCharCode(i & 0xFF)); -}; - -/** - * Puts a 24-bit integer in this buffer in big-endian order. - * - * @param i the 24-bit integer. - * - * @return this buffer. - */ -util.ByteStringBuffer.prototype.putInt24 = function(i) { - return this.putBytes( - String.fromCharCode(i >> 16 & 0xFF) + - String.fromCharCode(i >> 8 & 0xFF) + - String.fromCharCode(i & 0xFF)); -}; - -/** - * Puts a 32-bit integer in this buffer in big-endian order. - * - * @param i the 32-bit integer. - * - * @return this buffer. - */ -util.ByteStringBuffer.prototype.putInt32 = function(i) { - return this.putBytes( - String.fromCharCode(i >> 24 & 0xFF) + - String.fromCharCode(i >> 16 & 0xFF) + - String.fromCharCode(i >> 8 & 0xFF) + - String.fromCharCode(i & 0xFF)); -}; - -/** - * Puts a 16-bit integer in this buffer in little-endian order. - * - * @param i the 16-bit integer. - * - * @return this buffer. - */ -util.ByteStringBuffer.prototype.putInt16Le = function(i) { - return this.putBytes( - String.fromCharCode(i & 0xFF) + - String.fromCharCode(i >> 8 & 0xFF)); -}; - -/** - * Puts a 24-bit integer in this buffer in little-endian order. - * - * @param i the 24-bit integer. - * - * @return this buffer. - */ -util.ByteStringBuffer.prototype.putInt24Le = function(i) { - return this.putBytes( - String.fromCharCode(i & 0xFF) + - String.fromCharCode(i >> 8 & 0xFF) + - String.fromCharCode(i >> 16 & 0xFF)); -}; - -/** - * Puts a 32-bit integer in this buffer in little-endian order. - * - * @param i the 32-bit integer. - * - * @return this buffer. - */ -util.ByteStringBuffer.prototype.putInt32Le = function(i) { - return this.putBytes( - String.fromCharCode(i & 0xFF) + - String.fromCharCode(i >> 8 & 0xFF) + - String.fromCharCode(i >> 16 & 0xFF) + - String.fromCharCode(i >> 24 & 0xFF)); -}; - -/** - * Puts an n-bit integer in this buffer in big-endian order. - * - * @param i the n-bit integer. - * @param n the number of bits in the integer. - * - * @return this buffer. - */ -util.ByteStringBuffer.prototype.putInt = function(i, n) { - var bytes = ''; - do { - n -= 8; - bytes += String.fromCharCode((i >> n) & 0xFF); - } while(n > 0); - return this.putBytes(bytes); -}; - -/** - * Puts a signed n-bit integer in this buffer in big-endian order. Two's - * complement representation is used. - * - * @param i the n-bit integer. - * @param n the number of bits in the integer. - * - * @return this buffer. - */ -util.ByteStringBuffer.prototype.putSignedInt = function(i, n) { - if(i < 0) { - i += 2 << (n - 1); - } - return this.putInt(i, n); -}; - -/** - * Puts the given buffer into this buffer. - * - * @param buffer the buffer to put into this one. - * - * @return this buffer. - */ -util.ByteStringBuffer.prototype.putBuffer = function(buffer) { - return this.putBytes(buffer.getBytes()); -}; - -/** - * Gets a byte from this buffer and advances the read pointer by 1. - * - * @return the byte. - */ -util.ByteStringBuffer.prototype.getByte = function() { - return this.data.charCodeAt(this.read++); -}; - -/** - * Gets a uint16 from this buffer in big-endian order and advances the read - * pointer by 2. - * - * @return the uint16. - */ -util.ByteStringBuffer.prototype.getInt16 = function() { - var rval = ( - this.data.charCodeAt(this.read) << 8 ^ - this.data.charCodeAt(this.read + 1)); - this.read += 2; - return rval; -}; - -/** - * Gets a uint24 from this buffer in big-endian order and advances the read - * pointer by 3. - * - * @return the uint24. - */ -util.ByteStringBuffer.prototype.getInt24 = function() { - var rval = ( - this.data.charCodeAt(this.read) << 16 ^ - this.data.charCodeAt(this.read + 1) << 8 ^ - this.data.charCodeAt(this.read + 2)); - this.read += 3; - return rval; -}; - -/** - * Gets a uint32 from this buffer in big-endian order and advances the read - * pointer by 4. - * - * @return the word. - */ -util.ByteStringBuffer.prototype.getInt32 = function() { - var rval = ( - this.data.charCodeAt(this.read) << 24 ^ - this.data.charCodeAt(this.read + 1) << 16 ^ - this.data.charCodeAt(this.read + 2) << 8 ^ - this.data.charCodeAt(this.read + 3)); - this.read += 4; - return rval; -}; - -/** - * Gets a uint16 from this buffer in little-endian order and advances the read - * pointer by 2. - * - * @return the uint16. - */ -util.ByteStringBuffer.prototype.getInt16Le = function() { - var rval = ( - this.data.charCodeAt(this.read) ^ - this.data.charCodeAt(this.read + 1) << 8); - this.read += 2; - return rval; -}; - -/** - * Gets a uint24 from this buffer in little-endian order and advances the read - * pointer by 3. - * - * @return the uint24. - */ -util.ByteStringBuffer.prototype.getInt24Le = function() { - var rval = ( - this.data.charCodeAt(this.read) ^ - this.data.charCodeAt(this.read + 1) << 8 ^ - this.data.charCodeAt(this.read + 2) << 16); - this.read += 3; - return rval; -}; - -/** - * Gets a uint32 from this buffer in little-endian order and advances the read - * pointer by 4. - * - * @return the word. - */ -util.ByteStringBuffer.prototype.getInt32Le = function() { - var rval = ( - this.data.charCodeAt(this.read) ^ - this.data.charCodeAt(this.read + 1) << 8 ^ - this.data.charCodeAt(this.read + 2) << 16 ^ - this.data.charCodeAt(this.read + 3) << 24); - this.read += 4; - return rval; -}; - -/** - * Gets an n-bit integer from this buffer in big-endian order and advances the - * read pointer by n/8. - * - * @param n the number of bits in the integer. - * - * @return the integer. - */ -util.ByteStringBuffer.prototype.getInt = function(n) { - var rval = 0; - do { - rval = (rval << 8) + this.data.charCodeAt(this.read++); - n -= 8; - } while(n > 0); - return rval; -}; - -/** - * Gets a signed n-bit integer from this buffer in big-endian order, using - * two's complement, and advances the read pointer by n/8. - * - * @param n the number of bits in the integer. - * - * @return the integer. - */ -util.ByteStringBuffer.prototype.getSignedInt = function(n) { - var x = this.getInt(n); - var max = 2 << (n - 2); - if(x >= max) { - x -= max << 1; - } - return x; -}; - -/** - * Reads bytes out into a UTF-8 string and clears them from the buffer. - * - * @param count the number of bytes to read, undefined or null for all. - * - * @return a UTF-8 string of bytes. - */ -util.ByteStringBuffer.prototype.getBytes = function(count) { - var rval; - if(count) { - // read count bytes - count = Math.min(this.length(), count); - rval = this.data.slice(this.read, this.read + count); - this.read += count; - } else if(count === 0) { - rval = ''; - } else { - // read all bytes, optimize to only copy when needed - rval = (this.read === 0) ? this.data : this.data.slice(this.read); - this.clear(); - } - return rval; -}; - -/** - * Gets a UTF-8 encoded string of the bytes from this buffer without modifying - * the read pointer. - * - * @param count the number of bytes to get, omit to get all. - * - * @return a string full of UTF-8 encoded characters. - */ -util.ByteStringBuffer.prototype.bytes = function(count) { - return (typeof(count) === 'undefined' ? - this.data.slice(this.read) : - this.data.slice(this.read, this.read + count)); -}; - -/** - * Gets a byte at the given index without modifying the read pointer. - * - * @param i the byte index. - * - * @return the byte. - */ -util.ByteStringBuffer.prototype.at = function(i) { - return this.data.charCodeAt(this.read + i); -}; - -/** - * Puts a byte at the given index without modifying the read pointer. - * - * @param i the byte index. - * @param b the byte to put. - * - * @return this buffer. - */ -util.ByteStringBuffer.prototype.setAt = function(i, b) { - this.data = this.data.substr(0, this.read + i) + - String.fromCharCode(b) + - this.data.substr(this.read + i + 1); - return this; -}; - -/** - * Gets the last byte without modifying the read pointer. - * - * @return the last byte. - */ -util.ByteStringBuffer.prototype.last = function() { - return this.data.charCodeAt(this.data.length - 1); -}; - -/** - * Creates a copy of this buffer. - * - * @return the copy. - */ -util.ByteStringBuffer.prototype.copy = function() { - var c = util.createBuffer(this.data); - c.read = this.read; - return c; -}; - -/** - * Compacts this buffer. - * - * @return this buffer. - */ -util.ByteStringBuffer.prototype.compact = function() { - if(this.read > 0) { - this.data = this.data.slice(this.read); - this.read = 0; - } - return this; -}; - -/** - * Clears this buffer. - * - * @return this buffer. - */ -util.ByteStringBuffer.prototype.clear = function() { - this.data = ''; - this.read = 0; - return this; -}; - -/** - * Shortens this buffer by triming bytes off of the end of this buffer. - * - * @param count the number of bytes to trim off. - * - * @return this buffer. - */ -util.ByteStringBuffer.prototype.truncate = function(count) { - var len = Math.max(0, this.length() - count); - this.data = this.data.substr(this.read, len); - this.read = 0; - return this; -}; - -/** - * Converts this buffer to a hexadecimal string. - * - * @return a hexadecimal string. - */ -util.ByteStringBuffer.prototype.toHex = function() { - var rval = ''; - for(var i = this.read; i < this.data.length; ++i) { - var b = this.data.charCodeAt(i); - if(b < 16) { - rval += '0'; - } - rval += b.toString(16); - } - return rval; -}; - -/** - * Converts this buffer to a UTF-16 string (standard JavaScript string). - * - * @return a UTF-16 string. - */ -util.ByteStringBuffer.prototype.toString = function() { - return util.decodeUtf8(this.bytes()); -}; - -/** End Buffer w/BinaryString backing */ - - -/** Buffer w/UInt8Array backing */ - -/** - * FIXME: Experimental. Do not use yet. - * - * Constructor for an ArrayBuffer-backed byte buffer. - * - * The buffer may be constructed from a string, an ArrayBuffer, DataView, or a - * TypedArray. - * - * If a string is given, its encoding should be provided as an option, - * otherwise it will default to 'binary'. A 'binary' string is encoded such - * that each character is one byte in length and size. - * - * If an ArrayBuffer, DataView, or TypedArray is given, it will be used - * *directly* without any copying. Note that, if a write to the buffer requires - * more space, the buffer will allocate a new backing ArrayBuffer to - * accommodate. The starting read and write offsets for the buffer may be - * given as options. - * - * @param [b] the initial bytes for this buffer. - * @param options the options to use: - * [readOffset] the starting read offset to use (default: 0). - * [writeOffset] the starting write offset to use (default: the - * length of the first parameter). - * [growSize] the minimum amount, in bytes, to grow the buffer by to - * accommodate writes (default: 1024). - * [encoding] the encoding ('binary', 'utf8', 'utf16', 'hex') for the - * first parameter, if it is a string (default: 'binary'). - */ -function DataBuffer(b, options) { - // default options - options = options || {}; - - // pointers for read from/write to buffer - this.read = options.readOffset || 0; - this.growSize = options.growSize || 1024; - - var isArrayBuffer = util.isArrayBuffer(b); - var isArrayBufferView = util.isArrayBufferView(b); - if(isArrayBuffer || isArrayBufferView) { - // use ArrayBuffer directly - if(isArrayBuffer) { - this.data = new DataView(b); - } else { - // TODO: adjust read/write offset based on the type of view - // or specify that this must be done in the options ... that the - // offsets are byte-based - this.data = new DataView(b.buffer, b.byteOffset, b.byteLength); - } - this.write = ('writeOffset' in options ? - options.writeOffset : this.data.byteLength); - return; - } - - // initialize to empty array buffer and add any given bytes using putBytes - this.data = new DataView(new ArrayBuffer(0)); - this.write = 0; - - if(b !== null && b !== undefined) { - this.putBytes(b); - } - - if('writeOffset' in options) { - this.write = options.writeOffset; - } -} -util.DataBuffer = DataBuffer; - -/** - * Gets the number of bytes in this buffer. - * - * @return the number of bytes in this buffer. - */ -util.DataBuffer.prototype.length = function() { - return this.write - this.read; -}; - -/** - * Gets whether or not this buffer is empty. - * - * @return true if this buffer is empty, false if not. - */ -util.DataBuffer.prototype.isEmpty = function() { - return this.length() <= 0; -}; - -/** - * Ensures this buffer has enough empty space to accommodate the given number - * of bytes. An optional parameter may be given that indicates a minimum - * amount to grow the buffer if necessary. If the parameter is not given, - * the buffer will be grown by some previously-specified default amount - * or heuristic. - * - * @param amount the number of bytes to accommodate. - * @param [growSize] the minimum amount, in bytes, to grow the buffer by if - * necessary. - */ -util.DataBuffer.prototype.accommodate = function(amount, growSize) { - if(this.length() >= amount) { - return this; - } - growSize = Math.max(growSize || this.growSize, amount); - - // grow buffer - var src = new Uint8Array( - this.data.buffer, this.data.byteOffset, this.data.byteLength); - var dst = new Uint8Array(this.length() + growSize); - dst.set(src); - this.data = new DataView(dst.buffer); - - return this; -}; - -/** - * Puts a byte in this buffer. - * - * @param b the byte to put. - * - * @return this buffer. - */ -util.DataBuffer.prototype.putByte = function(b) { - this.accommodate(1); - this.data.setUint8(this.write++, b); - return this; -}; - -/** - * Puts a byte in this buffer N times. - * - * @param b the byte to put. - * @param n the number of bytes of value b to put. - * - * @return this buffer. - */ -util.DataBuffer.prototype.fillWithByte = function(b, n) { - this.accommodate(n); - for(var i = 0; i < n; ++i) { - this.data.setUint8(b); - } - return this; -}; - -/** - * Puts bytes in this buffer. The bytes may be given as a string, an - * ArrayBuffer, a DataView, or a TypedArray. - * - * @param bytes the bytes to put. - * @param [encoding] the encoding for the first parameter ('binary', 'utf8', - * 'utf16', 'hex'), if it is a string (default: 'binary'). - * - * @return this buffer. - */ -util.DataBuffer.prototype.putBytes = function(bytes, encoding) { - if(util.isArrayBufferView(bytes)) { - var src = new Uint8Array(bytes.buffer, bytes.byteOffset, bytes.byteLength); - var len = src.byteLength - src.byteOffset; - this.accommodate(len); - var dst = new Uint8Array(this.data.buffer, this.write); - dst.set(src); - this.write += len; - return this; - } - - if(util.isArrayBuffer(bytes)) { - var src = new Uint8Array(bytes); - this.accommodate(src.byteLength); - var dst = new Uint8Array(this.data.buffer); - dst.set(src, this.write); - this.write += src.byteLength; - return this; - } - - // bytes is a util.DataBuffer or equivalent - if(bytes instanceof util.DataBuffer || - (typeof bytes === 'object' && - typeof bytes.read === 'number' && typeof bytes.write === 'number' && - util.isArrayBufferView(bytes.data))) { - var src = new Uint8Array(bytes.data.byteLength, bytes.read, bytes.length()); - this.accommodate(src.byteLength); - var dst = new Uint8Array(bytes.data.byteLength, this.write); - dst.set(src); - this.write += src.byteLength; - return this; - } - - if(bytes instanceof util.ByteStringBuffer) { - // copy binary string and process as the same as a string parameter below - bytes = bytes.data; - encoding = 'binary'; - } - - // string conversion - encoding = encoding || 'binary'; - if(typeof bytes === 'string') { - var view; - - // decode from string - if(encoding === 'hex') { - this.accommodate(Math.ceil(bytes.length / 2)); - view = new Uint8Array(this.data.buffer, this.write); - this.write += util.binary.hex.decode(bytes, view, this.write); - return this; - } - if(encoding === 'base64') { - this.accommodate(Math.ceil(bytes.length / 4) * 3); - view = new Uint8Array(this.data.buffer, this.write); - this.write += util.binary.base64.decode(bytes, view, this.write); - return this; - } - - // encode text as UTF-8 bytes - if(encoding === 'utf8') { - // encode as UTF-8 then decode string as raw binary - bytes = util.encodeUtf8(bytes); - encoding = 'binary'; - } - - // decode string as raw binary - if(encoding === 'binary' || encoding === 'raw') { - // one byte per character - this.accommodate(bytes.length); - view = new Uint8Array(this.data.buffer, this.write); - this.write += util.binary.raw.decode(view); - return this; - } - - // encode text as UTF-16 bytes - if(encoding === 'utf16') { - // two bytes per character - this.accommodate(bytes.length * 2); - view = new Uint16Array(this.data.buffer, this.write); - this.write += util.text.utf16.encode(view); - return this; - } - - throw new Error('Invalid encoding: ' + encoding); - } - - throw Error('Invalid parameter: ' + bytes); -}; - -/** - * Puts the given buffer into this buffer. - * - * @param buffer the buffer to put into this one. - * - * @return this buffer. - */ -util.DataBuffer.prototype.putBuffer = function(buffer) { - this.putBytes(buffer); - buffer.clear(); - return this; -}; - -/** - * Puts a string into this buffer. - * - * @param str the string to put. - * @param [encoding] the encoding for the string (default: 'utf16'). - * - * @return this buffer. - */ -util.DataBuffer.prototype.putString = function(str) { - return this.putBytes(str, 'utf16'); -}; - -/** - * Puts a 16-bit integer in this buffer in big-endian order. - * - * @param i the 16-bit integer. - * - * @return this buffer. - */ -util.DataBuffer.prototype.putInt16 = function(i) { - this.accommodate(2); - this.data.setInt16(this.write, i); - this.write += 2; - return this; -}; - -/** - * Puts a 24-bit integer in this buffer in big-endian order. - * - * @param i the 24-bit integer. - * - * @return this buffer. - */ -util.DataBuffer.prototype.putInt24 = function(i) { - this.accommodate(3); - this.data.setInt16(this.write, i >> 8 & 0xFFFF); - this.data.setInt8(this.write, i >> 16 & 0xFF); - this.write += 3; - return this; -}; - -/** - * Puts a 32-bit integer in this buffer in big-endian order. - * - * @param i the 32-bit integer. - * - * @return this buffer. - */ -util.DataBuffer.prototype.putInt32 = function(i) { - this.accommodate(4); - this.data.setInt32(this.write, i); - this.write += 4; - return this; -}; - -/** - * Puts a 16-bit integer in this buffer in little-endian order. - * - * @param i the 16-bit integer. - * - * @return this buffer. - */ -util.DataBuffer.prototype.putInt16Le = function(i) { - this.accommodate(2); - this.data.setInt16(this.write, i, true); - this.write += 2; - return this; -}; - -/** - * Puts a 24-bit integer in this buffer in little-endian order. - * - * @param i the 24-bit integer. - * - * @return this buffer. - */ -util.DataBuffer.prototype.putInt24Le = function(i) { - this.accommodate(3); - this.data.setInt8(this.write, i >> 16 & 0xFF); - this.data.setInt16(this.write, i >> 8 & 0xFFFF, true); - this.write += 3; - return this; -}; - -/** - * Puts a 32-bit integer in this buffer in little-endian order. - * - * @param i the 32-bit integer. - * - * @return this buffer. - */ -util.DataBuffer.prototype.putInt32Le = function(i) { - this.accommodate(4); - this.data.setInt32(this.write, i, true); - this.write += 4; - return this; -}; - -/** - * Puts an n-bit integer in this buffer in big-endian order. - * - * @param i the n-bit integer. - * @param n the number of bits in the integer. - * - * @return this buffer. - */ -util.DataBuffer.prototype.putInt = function(i, n) { - this.accommodate(n / 8); - do { - n -= 8; - this.data.setInt8(this.write++, (i >> n) & 0xFF); - } while(n > 0); - return this; -}; - -/** - * Puts a signed n-bit integer in this buffer in big-endian order. Two's - * complement representation is used. - * - * @param i the n-bit integer. - * @param n the number of bits in the integer. - * - * @return this buffer. - */ -util.DataBuffer.prototype.putSignedInt = function(i, n) { - this.accommodate(n / 8); - if(i < 0) { - i += 2 << (n - 1); - } - return this.putInt(i, n); -}; - -/** - * Gets a byte from this buffer and advances the read pointer by 1. - * - * @return the byte. - */ -util.DataBuffer.prototype.getByte = function() { - return this.data.getInt8(this.read++); -}; - -/** - * Gets a uint16 from this buffer in big-endian order and advances the read - * pointer by 2. - * - * @return the uint16. - */ -util.DataBuffer.prototype.getInt16 = function() { - var rval = this.data.getInt16(this.read); - this.read += 2; - return rval; -}; - -/** - * Gets a uint24 from this buffer in big-endian order and advances the read - * pointer by 3. - * - * @return the uint24. - */ -util.DataBuffer.prototype.getInt24 = function() { - var rval = ( - this.data.getInt16(this.read) << 8 ^ - this.data.getInt8(this.read + 2)); - this.read += 3; - return rval; -}; - -/** - * Gets a uint32 from this buffer in big-endian order and advances the read - * pointer by 4. - * - * @return the word. - */ -util.DataBuffer.prototype.getInt32 = function() { - var rval = this.data.getInt32(this.read); - this.read += 4; - return rval; -}; - -/** - * Gets a uint16 from this buffer in little-endian order and advances the read - * pointer by 2. - * - * @return the uint16. - */ -util.DataBuffer.prototype.getInt16Le = function() { - var rval = this.data.getInt16(this.read, true); - this.read += 2; - return rval; -}; - -/** - * Gets a uint24 from this buffer in little-endian order and advances the read - * pointer by 3. - * - * @return the uint24. - */ -util.DataBuffer.prototype.getInt24Le = function() { - var rval = ( - this.data.getInt8(this.read) ^ - this.data.getInt16(this.read + 1, true) << 8); - this.read += 3; - return rval; -}; - -/** - * Gets a uint32 from this buffer in little-endian order and advances the read - * pointer by 4. - * - * @return the word. - */ -util.DataBuffer.prototype.getInt32Le = function() { - var rval = this.data.getInt32(this.read, true); - this.read += 4; - return rval; -}; - -/** - * Gets an n-bit integer from this buffer in big-endian order and advances the - * read pointer by n/8. - * - * @param n the number of bits in the integer. - * - * @return the integer. - */ -util.DataBuffer.prototype.getInt = function(n) { - var rval = 0; - do { - rval = (rval << 8) + this.data.getInt8(this.read++); - n -= 8; - } while(n > 0); - return rval; -}; - -/** - * Gets a signed n-bit integer from this buffer in big-endian order, using - * two's complement, and advances the read pointer by n/8. - * - * @param n the number of bits in the integer. - * - * @return the integer. - */ -util.DataBuffer.prototype.getSignedInt = function(n) { - var x = this.getInt(n); - var max = 2 << (n - 2); - if(x >= max) { - x -= max << 1; - } - return x; -}; - -/** - * Reads bytes out into a UTF-8 string and clears them from the buffer. - * - * @param count the number of bytes to read, undefined or null for all. - * - * @return a UTF-8 string of bytes. - */ -util.DataBuffer.prototype.getBytes = function(count) { - // TODO: deprecate this method, it is poorly named and - // this.toString('binary') replaces it - // add a toTypedArray()/toArrayBuffer() function - var rval; - if(count) { - // read count bytes - count = Math.min(this.length(), count); - rval = this.data.slice(this.read, this.read + count); - this.read += count; - } else if(count === 0) { - rval = ''; - } else { - // read all bytes, optimize to only copy when needed - rval = (this.read === 0) ? this.data : this.data.slice(this.read); - this.clear(); - } - return rval; -}; - -/** - * Gets a UTF-8 encoded string of the bytes from this buffer without modifying - * the read pointer. - * - * @param count the number of bytes to get, omit to get all. - * - * @return a string full of UTF-8 encoded characters. - */ -util.DataBuffer.prototype.bytes = function(count) { - // TODO: deprecate this method, it is poorly named, add "getString()" - return (typeof(count) === 'undefined' ? - this.data.slice(this.read) : - this.data.slice(this.read, this.read + count)); -}; - -/** - * Gets a byte at the given index without modifying the read pointer. - * - * @param i the byte index. - * - * @return the byte. - */ -util.DataBuffer.prototype.at = function(i) { - return this.data.getUint8(this.read + i); -}; - -/** - * Puts a byte at the given index without modifying the read pointer. - * - * @param i the byte index. - * @param b the byte to put. - * - * @return this buffer. - */ -util.DataBuffer.prototype.setAt = function(i, b) { - this.data.setUint8(i, b); - return this; -}; - -/** - * Gets the last byte without modifying the read pointer. - * - * @return the last byte. - */ -util.DataBuffer.prototype.last = function() { - return this.data.getUint8(this.write - 1); -}; - -/** - * Creates a copy of this buffer. - * - * @return the copy. - */ -util.DataBuffer.prototype.copy = function() { - return new util.DataBuffer(this); -}; - -/** - * Compacts this buffer. - * - * @return this buffer. - */ -util.DataBuffer.prototype.compact = function() { - if(this.read > 0) { - var src = new Uint8Array(this.data.buffer, this.read); - var dst = new Uint8Array(src.byteLength); - dst.set(src); - this.data = new DataView(dst); - this.write -= this.read; - this.read = 0; - } - return this; -}; - -/** - * Clears this buffer. - * - * @return this buffer. - */ -util.DataBuffer.prototype.clear = function() { - this.data = new DataView(new ArrayBuffer(0)); - this.read = this.write = 0; - return this; -}; - -/** - * Shortens this buffer by triming bytes off of the end of this buffer. - * - * @param count the number of bytes to trim off. - * - * @return this buffer. - */ -util.DataBuffer.prototype.truncate = function(count) { - this.write = Math.max(0, this.length() - count); - this.read = Math.min(this.read, this.write); - return this; -}; - -/** - * Converts this buffer to a hexadecimal string. - * - * @return a hexadecimal string. - */ -util.DataBuffer.prototype.toHex = function() { - var rval = ''; - for(var i = this.read; i < this.data.byteLength; ++i) { - var b = this.data.getUint8(i); - if(b < 16) { - rval += '0'; - } - rval += b.toString(16); - } - return rval; -}; - -/** - * Converts this buffer to a string, using the given encoding. If no - * encoding is given, 'utf8' (UTF-8) is used. - * - * @param [encoding] the encoding to use: 'binary', 'utf8', 'utf16', 'hex', - * 'base64' (default: 'utf8'). - * - * @return a string representation of the bytes in this buffer. - */ -util.DataBuffer.prototype.toString = function(encoding) { - var view = new Uint8Array(this.data, this.read, this.length()); - encoding = encoding || 'utf8'; - - // encode to string - if(encoding === 'binary' || encoding === 'raw') { - return util.binary.raw.encode(view); - } - if(encoding === 'hex') { - return util.binary.hex.encode(view); - } - if(encoding === 'base64') { - return util.binary.base64.encode(view); - } - - // decode to text - if(encoding === 'utf8') { - return util.text.utf8.decode(view); - } - if(encoding === 'utf16') { - return util.text.utf16.decode(view); - } - - throw new Error('Invalid encoding: ' + encoding); -}; - -/** End Buffer w/UInt8Array backing */ - - -/** - * Creates a buffer that stores bytes. A value may be given to put into the - * buffer that is either a string of bytes or a UTF-16 string that will - * be encoded using UTF-8 (to do the latter, specify 'utf8' as the encoding). - * - * @param [input] the bytes to wrap (as a string) or a UTF-16 string to encode - * as UTF-8. - * @param [encoding] (default: 'raw', other: 'utf8'). - */ -util.createBuffer = function(input, encoding) { - // TODO: deprecate, use new ByteBuffer() instead - encoding = encoding || 'raw'; - if(input !== undefined && encoding === 'utf8') { - input = util.encodeUtf8(input); - } - return new util.ByteBuffer(input); -}; - -/** - * Fills a string with a particular value. If you want the string to be a byte - * string, pass in String.fromCharCode(theByte). - * - * @param c the character to fill the string with, use String.fromCharCode - * to fill the string with a byte value. - * @param n the number of characters of value c to fill with. - * - * @return the filled string. - */ -util.fillString = function(c, n) { - var s = ''; - while(n > 0) { - if(n & 1) { - s += c; - } - n >>>= 1; - if(n > 0) { - c += c; - } - } - return s; -}; - -/** - * Performs a per byte XOR between two byte strings and returns the result as a - * string of bytes. - * - * @param s1 first string of bytes. - * @param s2 second string of bytes. - * @param n the number of bytes to XOR. - * - * @return the XOR'd result. - */ -util.xorBytes = function(s1, s2, n) { - var s3 = ''; - var b = ''; - var t = ''; - var i = 0; - var c = 0; - for(; n > 0; --n, ++i) { - b = s1.charCodeAt(i) ^ s2.charCodeAt(i); - if(c >= 10) { - s3 += t; - t = ''; - c = 0; - } - t += String.fromCharCode(b); - ++c; - } - s3 += t; - return s3; -}; - -/** - * Converts a hex string into a 'binary' encoded string of bytes. - * - * @param hex the hexadecimal string to convert. - * - * @return the binary-encoded string of bytes. - */ -util.hexToBytes = function(hex) { - // TODO: deprecate: "Deprecated. Use util.binary.hex.decode instead." - var rval = ''; - var i = 0; - if(hex.length & 1 == 1) { - // odd number of characters, convert first character alone - i = 1; - rval += String.fromCharCode(parseInt(hex[0], 16)); - } - // convert 2 characters (1 byte) at a time - for(; i < hex.length; i += 2) { - rval += String.fromCharCode(parseInt(hex.substr(i, 2), 16)); - } - return rval; -}; - -/** - * Converts a 'binary' encoded string of bytes to hex. - * - * @param bytes the byte string to convert. - * - * @return the string of hexadecimal characters. - */ -util.bytesToHex = function(bytes) { - // TODO: deprecate: "Deprecated. Use util.binary.hex.encode instead." - return util.createBuffer(bytes).toHex(); -}; - -/** - * Converts an 32-bit integer to 4-big-endian byte string. - * - * @param i the integer. - * - * @return the byte string. - */ -util.int32ToBytes = function(i) { - return ( - String.fromCharCode(i >> 24 & 0xFF) + - String.fromCharCode(i >> 16 & 0xFF) + - String.fromCharCode(i >> 8 & 0xFF) + - String.fromCharCode(i & 0xFF)); -}; - -// base64 characters, reverse mapping -var _base64 = - 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='; -var _base64Idx = [ -/*43 -43 = 0*/ -/*'+', 1, 2, 3,'/' */ - 62, -1, -1, -1, 63, - -/*'0','1','2','3','4','5','6','7','8','9' */ - 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, - -/*15, 16, 17,'=', 19, 20, 21 */ - -1, -1, -1, 64, -1, -1, -1, - -/*65 - 43 = 22*/ -/*'A','B','C','D','E','F','G','H','I','J','K','L','M', */ - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, - -/*'N','O','P','Q','R','S','T','U','V','W','X','Y','Z' */ - 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, - -/*91 - 43 = 48 */ -/*48, 49, 50, 51, 52, 53 */ - -1, -1, -1, -1, -1, -1, - -/*97 - 43 = 54*/ -/*'a','b','c','d','e','f','g','h','i','j','k','l','m' */ - 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, - -/*'n','o','p','q','r','s','t','u','v','w','x','y','z' */ - 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51 -]; - -/** - * Base64 encodes a 'binary' encoded string of bytes. - * - * @param input the binary encoded string of bytes to base64-encode. - * @param maxline the maximum number of encoded characters per line to use, - * defaults to none. - * - * @return the base64-encoded output. - */ -util.encode64 = function(input, maxline) { - // TODO: deprecate: "Deprecated. Use util.binary.base64.encode instead." - var line = ''; - var output = ''; - var chr1, chr2, chr3; - var i = 0; - while(i < input.length) { - chr1 = input.charCodeAt(i++); - chr2 = input.charCodeAt(i++); - chr3 = input.charCodeAt(i++); - - // encode 4 character group - line += _base64.charAt(chr1 >> 2); - line += _base64.charAt(((chr1 & 3) << 4) | (chr2 >> 4)); - if(isNaN(chr2)) { - line += '=='; - } else { - line += _base64.charAt(((chr2 & 15) << 2) | (chr3 >> 6)); - line += isNaN(chr3) ? '=' : _base64.charAt(chr3 & 63); - } - - if(maxline && line.length > maxline) { - output += line.substr(0, maxline) + '\r\n'; - line = line.substr(maxline); - } - } - output += line; - return output; -}; - -/** - * Base64 decodes a string into a 'binary' encoded string of bytes. - * - * @param input the base64-encoded input. - * - * @return the binary encoded string. - */ -util.decode64 = function(input) { - // TODO: deprecate: "Deprecated. Use util.binary.base64.decode instead." - - // remove all non-base64 characters - input = input.replace(/[^A-Za-z0-9\+\/\=]/g, ''); - - var output = ''; - var enc1, enc2, enc3, enc4; - var i = 0; - - while(i < input.length) { - enc1 = _base64Idx[input.charCodeAt(i++) - 43]; - enc2 = _base64Idx[input.charCodeAt(i++) - 43]; - enc3 = _base64Idx[input.charCodeAt(i++) - 43]; - enc4 = _base64Idx[input.charCodeAt(i++) - 43]; - - output += String.fromCharCode((enc1 << 2) | (enc2 >> 4)); - if(enc3 !== 64) { - // decoded at least 2 bytes - output += String.fromCharCode(((enc2 & 15) << 4) | (enc3 >> 2)); - if(enc4 !== 64) { - // decoded 3 bytes - output += String.fromCharCode(((enc3 & 3) << 6) | enc4); - } - } - } - - return output; -}; - -/** - * UTF-8 encodes the given UTF-16 encoded string (a standard JavaScript - * string). Non-ASCII characters will be encoded as multiple bytes according - * to UTF-8. - * - * @param str the string to encode. - * - * @return the UTF-8 encoded string. - */ -util.encodeUtf8 = function(str) { - return unescape(encodeURIComponent(str)); -}; - -/** - * Decodes a UTF-8 encoded string into a UTF-16 string. - * - * @param str the string to decode. - * - * @return the UTF-16 encoded string (standard JavaScript string). - */ -util.decodeUtf8 = function(str) { - return decodeURIComponent(escape(str)); -}; - -// binary encoding/decoding tools -// FIXME: Experimental. Do not use yet. -util.binary = { - raw: {}, - hex: {}, - base64: {} -}; - -/** - * Encodes a Uint8Array as a binary-encoded string. This encoding uses - * a value between 0 and 255 for each character. - * - * @param bytes the Uint8Array to encode. - * - * @return the binary-encoded string. - */ -util.binary.raw.encode = function(bytes) { - return String.fromCharCode.apply(null, bytes); -}; - -/** - * Decodes a binary-encoded string to a Uint8Array. This encoding uses - * a value between 0 and 255 for each character. - * - * @param str the binary-encoded string to decode. - * @param [output] an optional Uint8Array to write the output to; if it - * is too small, an exception will be thrown. - * @param [offset] the start offset for writing to the output (default: 0). - * - * @return the Uint8Array or the number of bytes written if output was given. - */ -util.binary.raw.decode = function(str, output, offset) { - var out = output; - if(!out) { - out = new Uint8Array(str.length); - } - offset = offset || 0; - var j = offset; - for(var i = 0; i < str.length; ++i) { - out[j++] = str.charCodeAt(i); - } - return output ? (j - offset) : out; -}; - -/** - * Encodes a 'binary' string, ArrayBuffer, DataView, TypedArray, or - * ByteBuffer as a string of hexadecimal characters. - * - * @param bytes the bytes to convert. - * - * @return the string of hexadecimal characters. - */ -util.binary.hex.encode = util.bytesToHex; - -/** - * Decodes a hex-encoded string to a Uint8Array. - * - * @param hex the hexadecimal string to convert. - * @param [output] an optional Uint8Array to write the output to; if it - * is too small, an exception will be thrown. - * @param [offset] the start offset for writing to the output (default: 0). - * - * @return the Uint8Array or the number of bytes written if output was given. - */ -util.binary.hex.decode = function(hex, output, offset) { - var out = output; - if(!out) { - out = new Uint8Array(Math.ceil(hex.length / 2)); - } - offset = offset || 0; - var i = 0, j = offset; - if(hex.length & 1) { - // odd number of characters, convert first character alone - i = 1; - out[j++] = parseInt(hex[0], 16); - } - // convert 2 characters (1 byte) at a time - for(; i < hex.length; i += 2) { - out[j++] = parseInt(hex.substr(i, 2), 16); - } - return output ? (j - offset) : out; -}; - -/** - * Base64-encodes a Uint8Array. - * - * @param input the Uint8Array to encode. - * @param maxline the maximum number of encoded characters per line to use, - * defaults to none. - * - * @return the base64-encoded output string. - */ -util.binary.base64.encode = function(input, maxline) { - var line = ''; - var output = ''; - var chr1, chr2, chr3; - var i = 0; - while(i < input.byteLength) { - chr1 = input[i++]; - chr2 = input[i++]; - chr3 = input[i++]; - - // encode 4 character group - line += _base64.charAt(chr1 >> 2); - line += _base64.charAt(((chr1 & 3) << 4) | (chr2 >> 4)); - if(isNaN(chr2)) { - line += '=='; - } else { - line += _base64.charAt(((chr2 & 15) << 2) | (chr3 >> 6)); - line += isNaN(chr3) ? '=' : _base64.charAt(chr3 & 63); - } - - if(maxline && line.length > maxline) { - output += line.substr(0, maxline) + '\r\n'; - line = line.substr(maxline); - } - } - output += line; - return output; -}; - -/** - * Decodes a base64-encoded string to a Uint8Array. - * - * @param input the base64-encoded input string. - * @param [output] an optional Uint8Array to write the output to; if it - * is too small, an exception will be thrown. - * @param [offset] the start offset for writing to the output (default: 0). - * - * @return the Uint8Array or the number of bytes written if output was given. - */ -util.binary.base64.decode = function(input, output, offset) { - var out = output; - if(!out) { - out = new Uint8Array(Math.ceil(input.length / 4) * 3); - } - - // remove all non-base64 characters - input = input.replace(/[^A-Za-z0-9\+\/\=]/g, ''); - - offset = offset || 0; - var enc1, enc2, enc3, enc4; - var i = 0, j = offset; - - while(i < input.length) { - enc1 = _base64Idx[input.charCodeAt(i++) - 43]; - enc2 = _base64Idx[input.charCodeAt(i++) - 43]; - enc3 = _base64Idx[input.charCodeAt(i++) - 43]; - enc4 = _base64Idx[input.charCodeAt(i++) - 43]; - - out[j++] = (enc1 << 2) | (enc2 >> 4); - if(enc3 !== 64) { - // decoded at least 2 bytes - out[j++] = ((enc2 & 15) << 4) | (enc3 >> 2); - if(enc4 !== 64) { - // decoded 3 bytes - out[j++] = ((enc3 & 3) << 6) | enc4; - } - } - } - - // make sure result is the exact decoded length - return output ? - (j - offset) : - out.subarray(0, j); -}; - -// text encoding/decoding tools -// FIXME: Experimental. Do not use yet. -util.text = { - utf8: {}, - utf16: {} -}; - -/** - * Encodes the given string as UTF-8 in a Uint8Array. - * - * @param str the string to encode. - * @param [output] an optional Uint8Array to write the output to; if it - * is too small, an exception will be thrown. - * @param [offset] the start offset for writing to the output (default: 0). - * - * @return the Uint8Array or the number of bytes written if output was given. - */ -util.text.utf8.encode = function(str, output, offset) { - str = util.encodeUtf8(str); - var out = output; - if(!out) { - out = new Uint8Array(str.length); - } - offset = offset || 0; - var j = offset; - for(var i = 0; i < str.length; ++i) { - out[j++] = str.charCodeAt(i); - } - return output ? (j - offset) : out; -}; - -/** - * Decodes the UTF-8 contents from a Uint8Array. - * - * @param bytes the Uint8Array to decode. - * - * @return the resulting string. - */ -util.text.utf8.decode = function(bytes) { - return util.decodeUtf8(String.fromCharCode.apply(null, bytes)); -}; - -/** - * Encodes the given string as UTF-16 in a Uint8Array. - * - * @param str the string to encode. - * @param [output] an optional Uint8Array to write the output to; if it - * is too small, an exception will be thrown. - * @param [offset] the start offset for writing to the output (default: 0). - * - * @return the Uint8Array or the number of bytes written if output was given. - */ -util.text.utf16.encode = function(str, output, offset) { - var out = output; - if(!out) { - out = new Uint8Array(str.length); - } - var view = new Uint16Array(out); - offset = offset || 0; - var j = offset; - var k = offset; - for(var i = 0; i < str.length; ++i) { - view[k++] = str.charCodeAt(i); - j += 2; - } - return output ? (j - offset) : out; -}; - -/** - * Decodes the UTF-16 contents from a Uint8Array. - * - * @param bytes the Uint8Array to decode. - * - * @return the resulting string. - */ -util.text.utf16.decode = function(bytes) { - return String.fromCharCode.apply(null, new Uint16Array(bytes)); -}; - -/** - * Deflates the given data using a flash interface. - * - * @param api the flash interface. - * @param bytes the data. - * @param raw true to return only raw deflate data, false to include zlib - * header and trailer. - * - * @return the deflated data as a string. - */ -util.deflate = function(api, bytes, raw) { - bytes = util.decode64(api.deflate(util.encode64(bytes)).rval); - - // strip zlib header and trailer if necessary - if(raw) { - // zlib header is 2 bytes (CMF,FLG) where FLG indicates that - // there is a 4-byte DICT (alder-32) block before the data if - // its 5th bit is set - var start = 2; - var flg = bytes.charCodeAt(1); - if(flg & 0x20) { - start = 6; - } - // zlib trailer is 4 bytes of adler-32 - bytes = bytes.substring(start, bytes.length - 4); - } - - return bytes; -}; - -/** - * Inflates the given data using a flash interface. - * - * @param api the flash interface. - * @param bytes the data. - * @param raw true if the incoming data has no zlib header or trailer and is - * raw DEFLATE data. - * - * @return the inflated data as a string, null on error. - */ -util.inflate = function(api, bytes, raw) { - // TODO: add zlib header and trailer if necessary/possible - var rval = api.inflate(util.encode64(bytes)).rval; - return (rval === null) ? null : util.decode64(rval); -}; - -/** - * Sets a storage object. - * - * @param api the storage interface. - * @param id the storage ID to use. - * @param obj the storage object, null to remove. - */ -var _setStorageObject = function(api, id, obj) { - if(!api) { - throw new Error('WebStorage not available.'); - } - - var rval; - if(obj === null) { - rval = api.removeItem(id); - } else { - // json-encode and base64-encode object - obj = util.encode64(JSON.stringify(obj)); - rval = api.setItem(id, obj); - } - - // handle potential flash error - if(typeof(rval) !== 'undefined' && rval.rval !== true) { - var error = new Error(rval.error.message); - error.id = rval.error.id; - error.name = rval.error.name; - throw error; - } -}; - -/** - * Gets a storage object. - * - * @param api the storage interface. - * @param id the storage ID to use. - * - * @return the storage object entry or null if none exists. - */ -var _getStorageObject = function(api, id) { - if(!api) { - throw new Error('WebStorage not available.'); - } - - // get the existing entry - var rval = api.getItem(id); - - /* Note: We check api.init because we can't do (api == localStorage) - on IE because of "Class doesn't support Automation" exception. Only - the flash api has an init method so this works too, but we need a - better solution in the future. */ - - // flash returns item wrapped in an object, handle special case - if(api.init) { - if(rval.rval === null) { - if(rval.error) { - var error = new Error(rval.error.message); - error.id = rval.error.id; - error.name = rval.error.name; - throw error; - } - // no error, but also no item - rval = null; - } else { - rval = rval.rval; - } - } - - // handle decoding - if(rval !== null) { - // base64-decode and json-decode data - rval = JSON.parse(util.decode64(rval)); - } - - return rval; -}; - -/** - * Stores an item in local storage. - * - * @param api the storage interface. - * @param id the storage ID to use. - * @param key the key for the item. - * @param data the data for the item (any javascript object/primitive). - */ -var _setItem = function(api, id, key, data) { - // get storage object - var obj = _getStorageObject(api, id); - if(obj === null) { - // create a new storage object - obj = {}; - } - // update key - obj[key] = data; - - // set storage object - _setStorageObject(api, id, obj); -}; - -/** - * Gets an item from local storage. - * - * @param api the storage interface. - * @param id the storage ID to use. - * @param key the key for the item. - * - * @return the item. - */ -var _getItem = function(api, id, key) { - // get storage object - var rval = _getStorageObject(api, id); - if(rval !== null) { - // return data at key - rval = (key in rval) ? rval[key] : null; - } - - return rval; -}; - -/** - * Removes an item from local storage. - * - * @param api the storage interface. - * @param id the storage ID to use. - * @param key the key for the item. - */ -var _removeItem = function(api, id, key) { - // get storage object - var obj = _getStorageObject(api, id); - if(obj !== null && key in obj) { - // remove key - delete obj[key]; - - // see if entry has no keys remaining - var empty = true; - for(var prop in obj) { - empty = false; - break; - } - if(empty) { - // remove entry entirely if no keys are left - obj = null; - } - - // set storage object - _setStorageObject(api, id, obj); - } -}; - -/** - * Clears the local disk storage identified by the given ID. - * - * @param api the storage interface. - * @param id the storage ID to use. - */ -var _clearItems = function(api, id) { - _setStorageObject(api, id, null); -}; - -/** - * Calls a storage function. - * - * @param func the function to call. - * @param args the arguments for the function. - * @param location the location argument. - * - * @return the return value from the function. - */ -var _callStorageFunction = function(func, args, location) { - var rval = null; - - // default storage types - if(typeof(location) === 'undefined') { - location = ['web', 'flash']; - } - - // apply storage types in order of preference - var type; - var done = false; - var exception = null; - for(var idx in location) { - type = location[idx]; - try { - if(type === 'flash' || type === 'both') { - if(args[0] === null) { - throw new Error('Flash local storage not available.'); - } - rval = func.apply(this, args); - done = (type === 'flash'); - } - if(type === 'web' || type === 'both') { - args[0] = localStorage; - rval = func.apply(this, args); - done = true; - } - } catch(ex) { - exception = ex; - } - if(done) { - break; - } - } - - if(!done) { - throw exception; - } - - return rval; -}; - -/** - * Stores an item on local disk. - * - * The available types of local storage include 'flash', 'web', and 'both'. - * - * The type 'flash' refers to flash local storage (SharedObject). In order - * to use flash local storage, the 'api' parameter must be valid. The type - * 'web' refers to WebStorage, if supported by the browser. The type 'both' - * refers to storing using both 'flash' and 'web', not just one or the - * other. - * - * The location array should list the storage types to use in order of - * preference: - * - * ['flash']: flash only storage - * ['web']: web only storage - * ['both']: try to store in both - * ['flash','web']: store in flash first, but if not available, 'web' - * ['web','flash']: store in web first, but if not available, 'flash' - * - * The location array defaults to: ['web', 'flash'] - * - * @param api the flash interface, null to use only WebStorage. - * @param id the storage ID to use. - * @param key the key for the item. - * @param data the data for the item (any javascript object/primitive). - * @param location an array with the preferred types of storage to use. - */ -util.setItem = function(api, id, key, data, location) { - _callStorageFunction(_setItem, arguments, location); -}; - -/** - * Gets an item on local disk. - * - * Set setItem() for details on storage types. - * - * @param api the flash interface, null to use only WebStorage. - * @param id the storage ID to use. - * @param key the key for the item. - * @param location an array with the preferred types of storage to use. - * - * @return the item. - */ -util.getItem = function(api, id, key, location) { - return _callStorageFunction(_getItem, arguments, location); -}; - -/** - * Removes an item on local disk. - * - * Set setItem() for details on storage types. - * - * @param api the flash interface. - * @param id the storage ID to use. - * @param key the key for the item. - * @param location an array with the preferred types of storage to use. - */ -util.removeItem = function(api, id, key, location) { - _callStorageFunction(_removeItem, arguments, location); -}; - -/** - * Clears the local disk storage identified by the given ID. - * - * Set setItem() for details on storage types. - * - * @param api the flash interface if flash is available. - * @param id the storage ID to use. - * @param location an array with the preferred types of storage to use. - */ -util.clearItems = function(api, id, location) { - _callStorageFunction(_clearItems, arguments, location); -}; - -/** - * Parses the scheme, host, and port from an http(s) url. - * - * @param str the url string. - * - * @return the parsed url object or null if the url is invalid. - */ -util.parseUrl = function(str) { - // FIXME: this regex looks a bit broken - var regex = /^(https?):\/\/([^:&^\/]*):?(\d*)(.*)$/g; - regex.lastIndex = 0; - var m = regex.exec(str); - var url = (m === null) ? null : { - full: str, - scheme: m[1], - host: m[2], - port: m[3], - path: m[4] - }; - if(url) { - url.fullHost = url.host; - if(url.port) { - if(url.port !== 80 && url.scheme === 'http') { - url.fullHost += ':' + url.port; - } else if(url.port !== 443 && url.scheme === 'https') { - url.fullHost += ':' + url.port; - } - } else if(url.scheme === 'http') { - url.port = 80; - } else if(url.scheme === 'https') { - url.port = 443; - } - url.full = url.scheme + '://' + url.fullHost; - } - return url; -}; - -/* Storage for query variables */ -var _queryVariables = null; - -/** - * Returns the window location query variables. Query is parsed on the first - * call and the same object is returned on subsequent calls. The mapping - * is from keys to an array of values. Parameters without values will have - * an object key set but no value added to the value array. Values are - * unescaped. - * - * ...?k1=v1&k2=v2: - * { - * "k1": ["v1"], - * "k2": ["v2"] - * } - * - * ...?k1=v1&k1=v2: - * { - * "k1": ["v1", "v2"] - * } - * - * ...?k1=v1&k2: - * { - * "k1": ["v1"], - * "k2": [] - * } - * - * ...?k1=v1&k1: - * { - * "k1": ["v1"] - * } - * - * ...?k1&k1: - * { - * "k1": [] - * } - * - * @param query the query string to parse (optional, default to cached - * results from parsing window location search query). - * - * @return object mapping keys to variables. - */ -util.getQueryVariables = function(query) { - var parse = function(q) { - var rval = {}; - var kvpairs = q.split('&'); - for(var i = 0; i < kvpairs.length; i++) { - var pos = kvpairs[i].indexOf('='); - var key; - var val; - if(pos > 0) { - key = kvpairs[i].substring(0, pos); - val = kvpairs[i].substring(pos + 1); - } else { - key = kvpairs[i]; - val = null; - } - if(!(key in rval)) { - rval[key] = []; - } - // disallow overriding object prototype keys - if(!(key in Object.prototype) && val !== null) { - rval[key].push(unescape(val)); - } - } - return rval; - }; - - var rval; - if(typeof(query) === 'undefined') { - // set cached variables if needed - if(_queryVariables === null) { - if(typeof(window) !== 'undefined' && window.location && window.location.search) { - // parse window search query - _queryVariables = parse(window.location.search.substring(1)); - } else { - // no query variables available - _queryVariables = {}; - } - } - rval = _queryVariables; - } else { - // parse given query - rval = parse(query); - } - return rval; -}; - -/** - * Parses a fragment into a path and query. This method will take a URI - * fragment and break it up as if it were the main URI. For example: - * /bar/baz?a=1&b=2 - * results in: - * { - * path: ["bar", "baz"], - * query: {"k1": ["v1"], "k2": ["v2"]} - * } - * - * @return object with a path array and query object. - */ -util.parseFragment = function(fragment) { - // default to whole fragment - var fp = fragment; - var fq = ''; - // split into path and query if possible at the first '?' - var pos = fragment.indexOf('?'); - if(pos > 0) { - fp = fragment.substring(0, pos); - fq = fragment.substring(pos + 1); - } - // split path based on '/' and ignore first element if empty - var path = fp.split('/'); - if(path.length > 0 && path[0] === '') { - path.shift(); - } - // convert query into object - var query = (fq === '') ? {} : util.getQueryVariables(fq); - - return { - pathString: fp, - queryString: fq, - path: path, - query: query - }; -}; - -/** - * Makes a request out of a URI-like request string. This is intended to - * be used where a fragment id (after a URI '#') is parsed as a URI with - * path and query parts. The string should have a path beginning and - * delimited by '/' and optional query parameters following a '?'. The - * query should be a standard URL set of key value pairs delimited by - * '&'. For backwards compatibility the initial '/' on the path is not - * required. The request object has the following API, (fully described - * in the method code): - * { - * path: <the path string part>. - * query: <the query string part>, - * getPath(i): get part or all of the split path array, - * getQuery(k, i): get part or all of a query key array, - * getQueryLast(k, _default): get last element of a query key array. - * } - * - * @return object with request parameters. - */ -util.makeRequest = function(reqString) { - var frag = util.parseFragment(reqString); - var req = { - // full path string - path: frag.pathString, - // full query string - query: frag.queryString, - /** - * Get path or element in path. - * - * @param i optional path index. - * - * @return path or part of path if i provided. - */ - getPath: function(i) { - return (typeof(i) === 'undefined') ? frag.path : frag.path[i]; - }, - /** - * Get query, values for a key, or value for a key index. - * - * @param k optional query key. - * @param i optional query key index. - * - * @return query, values for a key, or value for a key index. - */ - getQuery: function(k, i) { - var rval; - if(typeof(k) === 'undefined') { - rval = frag.query; - } else { - rval = frag.query[k]; - if(rval && typeof(i) !== 'undefined') { - rval = rval[i]; - } - } - return rval; - }, - getQueryLast: function(k, _default) { - var rval; - var vals = req.getQuery(k); - if(vals) { - rval = vals[vals.length - 1]; - } else { - rval = _default; - } - return rval; - } - }; - return req; -}; - -/** - * Makes a URI out of a path, an object with query parameters, and a - * fragment. Uses jQuery.param() internally for query string creation. - * If the path is an array, it will be joined with '/'. - * - * @param path string path or array of strings. - * @param query object with query parameters. (optional) - * @param fragment fragment string. (optional) - * - * @return string object with request parameters. - */ -util.makeLink = function(path, query, fragment) { - // join path parts if needed - path = jQuery.isArray(path) ? path.join('/') : path; - - var qstr = jQuery.param(query || {}); - fragment = fragment || ''; - return path + - ((qstr.length > 0) ? ('?' + qstr) : '') + - ((fragment.length > 0) ? ('#' + fragment) : ''); -}; - -/** - * Follows a path of keys deep into an object hierarchy and set a value. - * If a key does not exist or it's value is not an object, create an - * object in it's place. This can be destructive to a object tree if - * leaf nodes are given as non-final path keys. - * Used to avoid exceptions from missing parts of the path. - * - * @param object the starting object. - * @param keys an array of string keys. - * @param value the value to set. - */ -util.setPath = function(object, keys, value) { - // need to start at an object - if(typeof(object) === 'object' && object !== null) { - var i = 0; - var len = keys.length; - while(i < len) { - var next = keys[i++]; - if(i == len) { - // last - object[next] = value; - } else { - // more - var hasNext = (next in object); - if(!hasNext || - (hasNext && typeof(object[next]) !== 'object') || - (hasNext && object[next] === null)) { - object[next] = {}; - } - object = object[next]; - } - } - } -}; - -/** - * Follows a path of keys deep into an object hierarchy and return a value. - * If a key does not exist, create an object in it's place. - * Used to avoid exceptions from missing parts of the path. - * - * @param object the starting object. - * @param keys an array of string keys. - * @param _default value to return if path not found. - * - * @return the value at the path if found, else default if given, else - * undefined. - */ -util.getPath = function(object, keys, _default) { - var i = 0; - var len = keys.length; - var hasNext = true; - while(hasNext && i < len && - typeof(object) === 'object' && object !== null) { - var next = keys[i++]; - hasNext = next in object; - if(hasNext) { - object = object[next]; - } - } - return (hasNext ? object : _default); -}; - -/** - * Follow a path of keys deep into an object hierarchy and delete the - * last one. If a key does not exist, do nothing. - * Used to avoid exceptions from missing parts of the path. - * - * @param object the starting object. - * @param keys an array of string keys. - */ -util.deletePath = function(object, keys) { - // need to start at an object - if(typeof(object) === 'object' && object !== null) { - var i = 0; - var len = keys.length; - while(i < len) { - var next = keys[i++]; - if(i == len) { - // last - delete object[next]; - } else { - // more - if(!(next in object) || - (typeof(object[next]) !== 'object') || - (object[next] === null)) { - break; - } - object = object[next]; - } - } - } -}; - -/** - * Check if an object is empty. - * - * Taken from: - * http://stackoverflow.com/questions/679915/how-do-i-test-for-an-empty-javascript-object-from-json/679937#679937 - * - * @param object the object to check. - */ -util.isEmpty = function(obj) { - for(var prop in obj) { - if(obj.hasOwnProperty(prop)) { - return false; - } - } - return true; -}; - -/** - * Format with simple printf-style interpolation. - * - * %%: literal '%' - * %s,%o: convert next argument into a string. - * - * @param format the string to format. - * @param ... arguments to interpolate into the format string. - */ -util.format = function(format) { - var re = /%./g; - // current match - var match; - // current part - var part; - // current arg index - var argi = 0; - // collected parts to recombine later - var parts = []; - // last index found - var last = 0; - // loop while matches remain - while((match = re.exec(format))) { - part = format.substring(last, re.lastIndex - 2); - // don't add empty strings (ie, parts between %s%s) - if(part.length > 0) { - parts.push(part); - } - last = re.lastIndex; - // switch on % code - var code = match[0][1]; - switch(code) { - case 's': - case 'o': - // check if enough arguments were given - if(argi < arguments.length) { - parts.push(arguments[argi++ + 1]); - } else { - parts.push('<?>'); - } - break; - // FIXME: do proper formating for numbers, etc - //case 'f': - //case 'd': - case '%': - parts.push('%'); - break; - default: - parts.push('<%' + code + '?>'); - } - } - // add trailing part of format string - parts.push(format.substring(last)); - return parts.join(''); -}; - -/** - * Formats a number. - * - * http://snipplr.com/view/5945/javascript-numberformat--ported-from-php/ - */ -util.formatNumber = function(number, decimals, dec_point, thousands_sep) { - // http://kevin.vanzonneveld.net - // + original by: Jonas Raoni Soares Silva (http://www.jsfromhell.com) - // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) - // + bugfix by: Michael White (http://crestidg.com) - // + bugfix by: Benjamin Lupton - // + bugfix by: Allan Jensen (http://www.winternet.no) - // + revised by: Jonas Raoni Soares Silva (http://www.jsfromhell.com) - // * example 1: number_format(1234.5678, 2, '.', ''); - // * returns 1: 1234.57 - - var n = number, c = isNaN(decimals = Math.abs(decimals)) ? 2 : decimals; - var d = dec_point === undefined ? ',' : dec_point; - var t = thousands_sep === undefined ? - '.' : thousands_sep, s = n < 0 ? '-' : ''; - var i = parseInt((n = Math.abs(+n || 0).toFixed(c)), 10) + ''; - var j = (i.length > 3) ? i.length % 3 : 0; - return s + (j ? i.substr(0, j) + t : '') + - i.substr(j).replace(/(\d{3})(?=\d)/g, '$1' + t) + - (c ? d + Math.abs(n - i).toFixed(c).slice(2) : ''); -}; - -/** - * Formats a byte size. - * - * http://snipplr.com/view/5949/format-humanize-file-byte-size-presentation-in-javascript/ - */ -util.formatSize = function(size) { - if(size >= 1073741824) { - size = util.formatNumber(size / 1073741824, 2, '.', '') + ' GiB'; - } else if(size >= 1048576) { - size = util.formatNumber(size / 1048576, 2, '.', '') + ' MiB'; - } else if(size >= 1024) { - size = util.formatNumber(size / 1024, 0) + ' KiB'; - } else { - size = util.formatNumber(size, 0) + ' bytes'; - } - return size; -}; - -/** - * Converts an IPv4 or IPv6 string representation into bytes (in network order). - * - * @param ip the IPv4 or IPv6 address to convert. - * - * @return the 4-byte IPv6 or 16-byte IPv6 address or null if the address can't - * be parsed. - */ -util.bytesFromIP = function(ip) { - if(ip.indexOf('.') !== -1) { - return util.bytesFromIPv4(ip); - } - if(ip.indexOf(':') !== -1) { - return util.bytesFromIPv6(ip); - } - return null; -}; - -/** - * Converts an IPv4 string representation into bytes (in network order). - * - * @param ip the IPv4 address to convert. - * - * @return the 4-byte address or null if the address can't be parsed. - */ -util.bytesFromIPv4 = function(ip) { - ip = ip.split('.'); - if(ip.length !== 4) { - return null; - } - var b = util.createBuffer(); - for(var i = 0; i < ip.length; ++i) { - var num = parseInt(ip[i], 10); - if(isNaN(num)) { - return null; - } - b.putByte(num); - } - return b.getBytes(); -}; - -/** - * Converts an IPv6 string representation into bytes (in network order). - * - * @param ip the IPv6 address to convert. - * - * @return the 16-byte address or null if the address can't be parsed. - */ -util.bytesFromIPv6 = function(ip) { - var blanks = 0; - ip = ip.split(':').filter(function(e) { - if(e.length === 0) ++blanks; - return true; - }); - var zeros = (8 - ip.length + blanks) * 2; - var b = util.createBuffer(); - for(var i = 0; i < 8; ++i) { - if(!ip[i] || ip[i].length === 0) { - b.fillWithByte(0, zeros); - zeros = 0; - continue; - } - var bytes = util.hexToBytes(ip[i]); - if(bytes.length < 2) { - b.putByte(0); - } - b.putBytes(bytes); - } - return b.getBytes(); -}; - -/** - * Converts 4-bytes into an IPv4 string representation or 16-bytes into - * an IPv6 string representation. The bytes must be in network order. - * - * @param bytes the bytes to convert. - * - * @return the IPv4 or IPv6 string representation if 4 or 16 bytes, - * respectively, are given, otherwise null. - */ -util.bytesToIP = function(bytes) { - if(bytes.length === 4) { - return util.bytesToIPv4(bytes); - } - if(bytes.length === 16) { - return util.bytesToIPv6(bytes); - } - return null; -}; - -/** - * Converts 4-bytes into an IPv4 string representation. The bytes must be - * in network order. - * - * @param bytes the bytes to convert. - * - * @return the IPv4 string representation or null for an invalid # of bytes. - */ -util.bytesToIPv4 = function(bytes) { - if(bytes.length !== 4) { - return null; - } - var ip = []; - for(var i = 0; i < bytes.length; ++i) { - ip.push(bytes.charCodeAt(i)); - } - return ip.join('.'); -}; - -/** - * Converts 16-bytes into an IPv16 string representation. The bytes must be - * in network order. - * - * @param bytes the bytes to convert. - * - * @return the IPv16 string representation or null for an invalid # of bytes. - */ -util.bytesToIPv6 = function(bytes) { - if(bytes.length !== 16) { - return null; - } - var ip = []; - var zeroGroups = []; - var zeroMaxGroup = 0; - for(var i = 0; i < bytes.length; i += 2) { - var hex = util.bytesToHex(bytes[i] + bytes[i + 1]); - // canonicalize zero representation - while(hex[0] === '0' && hex !== '0') { - hex = hex.substr(1); - } - if(hex === '0') { - var last = zeroGroups[zeroGroups.length - 1]; - var idx = ip.length; - if(!last || idx !== last.end + 1) { - zeroGroups.push({start: idx, end: idx}); - } else { - last.end = idx; - if((last.end - last.start) > - (zeroGroups[zeroMaxGroup].end - zeroGroups[zeroMaxGroup].start)) { - zeroMaxGroup = zeroGroups.length - 1; - } - } - } - ip.push(hex); - } - if(zeroGroups.length > 0) { - var group = zeroGroups[zeroMaxGroup]; - // only shorten group of length > 0 - if(group.end - group.start > 0) { - ip.splice(group.start, group.end - group.start + 1, ''); - if(group.start === 0) { - ip.unshift(''); - } - if(group.end === 7) { - ip.push(''); - } - } - } - return ip.join(':'); -}; - -/** - * Estimates the number of processes that can be run concurrently. If - * creating Web Workers, keep in mind that the main JavaScript process needs - * its own core. - * - * @param options the options to use: - * update true to force an update (not use the cached value). - * @param callback(err, max) called once the operation completes. - */ -util.estimateCores = function(options, callback) { - if(typeof options === 'function') { - callback = options; - options = {}; - } - options = options || {}; - if('cores' in util && !options.update) { - return callback(null, util.cores); - } - if(typeof navigator !== 'undefined' && - 'hardwareConcurrency' in navigator && - navigator.hardwareConcurrency > 0) { - util.cores = navigator.hardwareConcurrency; - return callback(null, util.cores); - } - if(typeof Worker === 'undefined') { - // workers not available - util.cores = 1; - return callback(null, util.cores); - } - if(typeof Blob === 'undefined') { - // can't estimate, default to 2 - util.cores = 2; - return callback(null, util.cores); - } - - // create worker concurrency estimation code as blob - var blobUrl = URL.createObjectURL(new Blob(['(', - function() { - self.addEventListener('message', function(e) { - // run worker for 4 ms - var st = Date.now(); - var et = st + 4; - while(Date.now() < et); - self.postMessage({st: st, et: et}); - }); - }.toString(), - ')()'], {type: 'application/javascript'})); - - // take 5 samples using 16 workers - sample([], 5, 16); - - function sample(max, samples, numWorkers) { - if(samples === 0) { - // get overlap average - var avg = Math.floor(max.reduce(function(avg, x) { - return avg + x; - }, 0) / max.length); - util.cores = Math.max(1, avg); - URL.revokeObjectURL(blobUrl); - return callback(null, util.cores); - } - map(numWorkers, function(err, results) { - max.push(reduce(numWorkers, results)); - sample(max, samples - 1, numWorkers); - }); - } - - function map(numWorkers, callback) { - var workers = []; - var results = []; - for(var i = 0; i < numWorkers; ++i) { - var worker = new Worker(blobUrl); - worker.addEventListener('message', function(e) { - results.push(e.data); - if(results.length === numWorkers) { - for(var i = 0; i < numWorkers; ++i) { - workers[i].terminate(); - } - callback(null, results); - } - }); - workers.push(worker); - } - for(var i = 0; i < numWorkers; ++i) { - workers[i].postMessage(i); - } - } - - function reduce(numWorkers, results) { - // find overlapping time windows - var overlaps = []; - for(var n = 0; n < numWorkers; ++n) { - var r1 = results[n]; - var overlap = overlaps[n] = []; - for(var i = 0; i < numWorkers; ++i) { - if(n === i) { - continue; - } - var r2 = results[i]; - if((r1.st > r2.st && r1.st < r2.et) || - (r2.st > r1.st && r2.st < r1.et)) { - overlap.push(i); - } - } - } - // get maximum overlaps ... don't include overlapping worker itself - // as the main JS process was also being scheduled during the work and - // would have to be subtracted from the estimate anyway - return overlaps.reduce(function(max, overlap) { - return Math.max(max, overlap.length); - }, 0); - } -}; - -} // end module implementation - -/* ########## Begin module wrapper ########## */ -var name = 'util'; -if(typeof define !== 'function') { - // NodeJS -> AMD - if(typeof module === 'object' && module.exports) { - var nodeJS = true; - define = function(ids, factory) { - factory(require, module); - }; - } else { - // <script> - if(typeof forge === 'undefined') { - forge = {}; - } - return initModule(forge); - } -} -// AMD -var deps; -var defineFunc = function(require, module) { - module.exports = function(forge) { - var mods = deps.map(function(dep) { - return require(dep); - }).concat(initModule); - // handle circular dependencies - forge = forge || {}; - forge.defined = forge.defined || {}; - if(forge.defined[name]) { - return forge[name]; - } - forge.defined[name] = true; - for(var i = 0; i < mods.length; ++i) { - mods[i](forge); - } - return forge[name]; - }; -}; -var tmpDefine = define; -define = function(ids, factory) { - deps = (typeof ids === 'string') ? factory.slice(2) : ids.slice(2); - if(nodeJS) { - delete define; - return tmpDefine.apply(null, Array.prototype.slice.call(arguments, 0)); - } - define = tmpDefine; - return define.apply(null, Array.prototype.slice.call(arguments, 0)); -}; -define(['require', 'module'], function() { - defineFunc.apply(null, Array.prototype.slice.call(arguments, 0)); -}); -})(); diff --git a/alarm/node_modules/node-forge/js/x509.js b/alarm/node_modules/node-forge/js/x509.js deleted file mode 100644 index 4545293..0000000 --- a/alarm/node_modules/node-forge/js/x509.js +++ /dev/null @@ -1,3178 +0,0 @@ -/** - * Javascript implementation of X.509 and related components (such as - * Certification Signing Requests) of a Public Key Infrastructure. - * - * @author Dave Longley - * - * Copyright (c) 2010-2014 Digital Bazaar, Inc. - * - * The ASN.1 representation of an X.509v3 certificate is as follows - * (see RFC 2459): - * - * Certificate ::= SEQUENCE { - * tbsCertificate TBSCertificate, - * signatureAlgorithm AlgorithmIdentifier, - * signatureValue BIT STRING - * } - * - * TBSCertificate ::= SEQUENCE { - * version [0] EXPLICIT Version DEFAULT v1, - * serialNumber CertificateSerialNumber, - * signature AlgorithmIdentifier, - * issuer Name, - * validity Validity, - * subject Name, - * subjectPublicKeyInfo SubjectPublicKeyInfo, - * issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL, - * -- If present, version shall be v2 or v3 - * subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL, - * -- If present, version shall be v2 or v3 - * extensions [3] EXPLICIT Extensions OPTIONAL - * -- If present, version shall be v3 - * } - * - * Version ::= INTEGER { v1(0), v2(1), v3(2) } - * - * CertificateSerialNumber ::= INTEGER - * - * Name ::= CHOICE { - * // only one possible choice for now - * RDNSequence - * } - * - * RDNSequence ::= SEQUENCE OF RelativeDistinguishedName - * - * RelativeDistinguishedName ::= SET OF AttributeTypeAndValue - * - * AttributeTypeAndValue ::= SEQUENCE { - * type AttributeType, - * value AttributeValue - * } - * AttributeType ::= OBJECT IDENTIFIER - * AttributeValue ::= ANY DEFINED BY AttributeType - * - * Validity ::= SEQUENCE { - * notBefore Time, - * notAfter Time - * } - * - * Time ::= CHOICE { - * utcTime UTCTime, - * generalTime GeneralizedTime - * } - * - * UniqueIdentifier ::= BIT STRING - * - * SubjectPublicKeyInfo ::= SEQUENCE { - * algorithm AlgorithmIdentifier, - * subjectPublicKey BIT STRING - * } - * - * Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension - * - * Extension ::= SEQUENCE { - * extnID OBJECT IDENTIFIER, - * critical BOOLEAN DEFAULT FALSE, - * extnValue OCTET STRING - * } - * - * The only key algorithm currently supported for PKI is RSA. - * - * RSASSA-PSS signatures are described in RFC 3447 and RFC 4055. - * - * PKCS#10 v1.7 describes certificate signing requests: - * - * CertificationRequestInfo: - * - * CertificationRequestInfo ::= SEQUENCE { - * version INTEGER { v1(0) } (v1,...), - * subject Name, - * subjectPKInfo SubjectPublicKeyInfo{{ PKInfoAlgorithms }}, - * attributes [0] Attributes{{ CRIAttributes }} - * } - * - * Attributes { ATTRIBUTE:IOSet } ::= SET OF Attribute{{ IOSet }} - * - * CRIAttributes ATTRIBUTE ::= { - * ... -- add any locally defined attributes here -- } - * - * Attribute { ATTRIBUTE:IOSet } ::= SEQUENCE { - * type ATTRIBUTE.&id({IOSet}), - * values SET SIZE(1..MAX) OF ATTRIBUTE.&Type({IOSet}{@type}) - * } - * - * CertificationRequest ::= SEQUENCE { - * certificationRequestInfo CertificationRequestInfo, - * signatureAlgorithm AlgorithmIdentifier{{ SignatureAlgorithms }}, - * signature BIT STRING - * } - */ -(function() { -/* ########## Begin module implementation ########## */ -function initModule(forge) { - -// shortcut for asn.1 API -var asn1 = forge.asn1; - -/* Public Key Infrastructure (PKI) implementation. */ -var pki = forge.pki = forge.pki || {}; -var oids = pki.oids; - -// short name OID mappings -var _shortNames = {}; -_shortNames['CN'] = oids['commonName']; -_shortNames['commonName'] = 'CN'; -_shortNames['C'] = oids['countryName']; -_shortNames['countryName'] = 'C'; -_shortNames['L'] = oids['localityName']; -_shortNames['localityName'] = 'L'; -_shortNames['ST'] = oids['stateOrProvinceName']; -_shortNames['stateOrProvinceName'] = 'ST'; -_shortNames['O'] = oids['organizationName']; -_shortNames['organizationName'] = 'O'; -_shortNames['OU'] = oids['organizationalUnitName']; -_shortNames['organizationalUnitName'] = 'OU'; -_shortNames['E'] = oids['emailAddress']; -_shortNames['emailAddress'] = 'E'; - -// validator for an SubjectPublicKeyInfo structure -// Note: Currently only works with an RSA public key -var publicKeyValidator = forge.pki.rsa.publicKeyValidator; - -// validator for an X.509v3 certificate -var x509CertificateValidator = { - name: 'Certificate', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.SEQUENCE, - constructed: true, - value: [{ - name: 'Certificate.TBSCertificate', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.SEQUENCE, - constructed: true, - captureAsn1: 'tbsCertificate', - value: [{ - name: 'Certificate.TBSCertificate.version', - tagClass: asn1.Class.CONTEXT_SPECIFIC, - type: 0, - constructed: true, - optional: true, - value: [{ - name: 'Certificate.TBSCertificate.version.integer', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.INTEGER, - constructed: false, - capture: 'certVersion' - }] - }, { - name: 'Certificate.TBSCertificate.serialNumber', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.INTEGER, - constructed: false, - capture: 'certSerialNumber' - }, { - name: 'Certificate.TBSCertificate.signature', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.SEQUENCE, - constructed: true, - value: [{ - name: 'Certificate.TBSCertificate.signature.algorithm', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.OID, - constructed: false, - capture: 'certinfoSignatureOid' - }, { - name: 'Certificate.TBSCertificate.signature.parameters', - tagClass: asn1.Class.UNIVERSAL, - optional: true, - captureAsn1: 'certinfoSignatureParams' - }] - }, { - name: 'Certificate.TBSCertificate.issuer', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.SEQUENCE, - constructed: true, - captureAsn1: 'certIssuer' - }, { - name: 'Certificate.TBSCertificate.validity', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.SEQUENCE, - constructed: true, - // Note: UTC and generalized times may both appear so the capture - // names are based on their detected order, the names used below - // are only for the common case, which validity time really means - // "notBefore" and which means "notAfter" will be determined by order - value: [{ - // notBefore (Time) (UTC time case) - name: 'Certificate.TBSCertificate.validity.notBefore (utc)', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.UTCTIME, - constructed: false, - optional: true, - capture: 'certValidity1UTCTime' - }, { - // notBefore (Time) (generalized time case) - name: 'Certificate.TBSCertificate.validity.notBefore (generalized)', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.GENERALIZEDTIME, - constructed: false, - optional: true, - capture: 'certValidity2GeneralizedTime' - }, { - // notAfter (Time) (only UTC time is supported) - name: 'Certificate.TBSCertificate.validity.notAfter (utc)', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.UTCTIME, - constructed: false, - optional: true, - capture: 'certValidity3UTCTime' - }, { - // notAfter (Time) (only UTC time is supported) - name: 'Certificate.TBSCertificate.validity.notAfter (generalized)', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.GENERALIZEDTIME, - constructed: false, - optional: true, - capture: 'certValidity4GeneralizedTime' - }] - }, { - // Name (subject) (RDNSequence) - name: 'Certificate.TBSCertificate.subject', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.SEQUENCE, - constructed: true, - captureAsn1: 'certSubject' - }, - // SubjectPublicKeyInfo - publicKeyValidator, - { - // issuerUniqueID (optional) - name: 'Certificate.TBSCertificate.issuerUniqueID', - tagClass: asn1.Class.CONTEXT_SPECIFIC, - type: 1, - constructed: true, - optional: true, - value: [{ - name: 'Certificate.TBSCertificate.issuerUniqueID.id', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.BITSTRING, - constructed: false, - capture: 'certIssuerUniqueId' - }] - }, { - // subjectUniqueID (optional) - name: 'Certificate.TBSCertificate.subjectUniqueID', - tagClass: asn1.Class.CONTEXT_SPECIFIC, - type: 2, - constructed: true, - optional: true, - value: [{ - name: 'Certificate.TBSCertificate.subjectUniqueID.id', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.BITSTRING, - constructed: false, - capture: 'certSubjectUniqueId' - }] - }, { - // Extensions (optional) - name: 'Certificate.TBSCertificate.extensions', - tagClass: asn1.Class.CONTEXT_SPECIFIC, - type: 3, - constructed: true, - captureAsn1: 'certExtensions', - optional: true - }] - }, { - // AlgorithmIdentifier (signature algorithm) - name: 'Certificate.signatureAlgorithm', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.SEQUENCE, - constructed: true, - value: [{ - // algorithm - name: 'Certificate.signatureAlgorithm.algorithm', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.OID, - constructed: false, - capture: 'certSignatureOid' - }, { - name: 'Certificate.TBSCertificate.signature.parameters', - tagClass: asn1.Class.UNIVERSAL, - optional: true, - captureAsn1: 'certSignatureParams' - }] - }, { - // SignatureValue - name: 'Certificate.signatureValue', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.BITSTRING, - constructed: false, - capture: 'certSignature' - }] -}; - -var rsassaPssParameterValidator = { - name: 'rsapss', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.SEQUENCE, - constructed: true, - value: [{ - name: 'rsapss.hashAlgorithm', - tagClass: asn1.Class.CONTEXT_SPECIFIC, - type: 0, - constructed: true, - value: [{ - name: 'rsapss.hashAlgorithm.AlgorithmIdentifier', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Class.SEQUENCE, - constructed: true, - optional: true, - value: [{ - name: 'rsapss.hashAlgorithm.AlgorithmIdentifier.algorithm', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.OID, - constructed: false, - capture: 'hashOid' - /* parameter block omitted, for SHA1 NULL anyhow. */ - }] - }] - }, { - name: 'rsapss.maskGenAlgorithm', - tagClass: asn1.Class.CONTEXT_SPECIFIC, - type: 1, - constructed: true, - value: [{ - name: 'rsapss.maskGenAlgorithm.AlgorithmIdentifier', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Class.SEQUENCE, - constructed: true, - optional: true, - value: [{ - name: 'rsapss.maskGenAlgorithm.AlgorithmIdentifier.algorithm', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.OID, - constructed: false, - capture: 'maskGenOid' - }, { - name: 'rsapss.maskGenAlgorithm.AlgorithmIdentifier.params', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.SEQUENCE, - constructed: true, - value: [{ - name: 'rsapss.maskGenAlgorithm.AlgorithmIdentifier.params.algorithm', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.OID, - constructed: false, - capture: 'maskGenHashOid' - /* parameter block omitted, for SHA1 NULL anyhow. */ - }] - }] - }] - }, { - name: 'rsapss.saltLength', - tagClass: asn1.Class.CONTEXT_SPECIFIC, - type: 2, - optional: true, - value: [{ - name: 'rsapss.saltLength.saltLength', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Class.INTEGER, - constructed: false, - capture: 'saltLength' - }] - }, { - name: 'rsapss.trailerField', - tagClass: asn1.Class.CONTEXT_SPECIFIC, - type: 3, - optional: true, - value: [{ - name: 'rsapss.trailer.trailer', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Class.INTEGER, - constructed: false, - capture: 'trailer' - }] - }] -}; - -// validator for a CertificationRequestInfo structure -var certificationRequestInfoValidator = { - name: 'CertificationRequestInfo', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.SEQUENCE, - constructed: true, - captureAsn1: 'certificationRequestInfo', - value: [{ - name: 'CertificationRequestInfo.integer', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.INTEGER, - constructed: false, - capture: 'certificationRequestInfoVersion' - }, { - // Name (subject) (RDNSequence) - name: 'CertificationRequestInfo.subject', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.SEQUENCE, - constructed: true, - captureAsn1: 'certificationRequestInfoSubject' - }, - // SubjectPublicKeyInfo - publicKeyValidator, - { - name: 'CertificationRequestInfo.attributes', - tagClass: asn1.Class.CONTEXT_SPECIFIC, - type: 0, - constructed: true, - optional: true, - capture: 'certificationRequestInfoAttributes', - value: [{ - name: 'CertificationRequestInfo.attributes', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.SEQUENCE, - constructed: true, - value: [{ - name: 'CertificationRequestInfo.attributes.type', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.OID, - constructed: false - }, { - name: 'CertificationRequestInfo.attributes.value', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.SET, - constructed: true - }] - }] - }] -}; - -// validator for a CertificationRequest structure -var certificationRequestValidator = { - name: 'CertificationRequest', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.SEQUENCE, - constructed: true, - captureAsn1: 'csr', - value: [ - certificationRequestInfoValidator, { - // AlgorithmIdentifier (signature algorithm) - name: 'CertificationRequest.signatureAlgorithm', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.SEQUENCE, - constructed: true, - value: [{ - // algorithm - name: 'CertificationRequest.signatureAlgorithm.algorithm', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.OID, - constructed: false, - capture: 'csrSignatureOid' - }, { - name: 'CertificationRequest.signatureAlgorithm.parameters', - tagClass: asn1.Class.UNIVERSAL, - optional: true, - captureAsn1: 'csrSignatureParams' - }] - }, { - // signature - name: 'CertificationRequest.signature', - tagClass: asn1.Class.UNIVERSAL, - type: asn1.Type.BITSTRING, - constructed: false, - capture: 'csrSignature' - }] -}; - -/** - * Converts an RDNSequence of ASN.1 DER-encoded RelativeDistinguishedName - * sets into an array with objects that have type and value properties. - * - * @param rdn the RDNSequence to convert. - * @param md a message digest to append type and value to if provided. - */ -pki.RDNAttributesAsArray = function(rdn, md) { - var rval = []; - - // each value in 'rdn' in is a SET of RelativeDistinguishedName - var set, attr, obj; - for(var si = 0; si < rdn.value.length; ++si) { - // get the RelativeDistinguishedName set - set = rdn.value[si]; - - // each value in the SET is an AttributeTypeAndValue sequence - // containing first a type (an OID) and second a value (defined by - // the OID) - for(var i = 0; i < set.value.length; ++i) { - obj = {}; - attr = set.value[i]; - obj.type = asn1.derToOid(attr.value[0].value); - obj.value = attr.value[1].value; - obj.valueTagClass = attr.value[1].type; - // if the OID is known, get its name and short name - if(obj.type in oids) { - obj.name = oids[obj.type]; - if(obj.name in _shortNames) { - obj.shortName = _shortNames[obj.name]; - } - } - if(md) { - md.update(obj.type); - md.update(obj.value); - } - rval.push(obj); - } - } - - return rval; -}; - -/** - * Converts ASN.1 CRIAttributes into an array with objects that have type and - * value properties. - * - * @param attributes the CRIAttributes to convert. - */ -pki.CRIAttributesAsArray = function(attributes) { - var rval = []; - - // each value in 'attributes' in is a SEQUENCE with an OID and a SET - for(var si = 0; si < attributes.length; ++si) { - // get the attribute sequence - var seq = attributes[si]; - - // each value in the SEQUENCE containing first a type (an OID) and - // second a set of values (defined by the OID) - var type = asn1.derToOid(seq.value[0].value); - var values = seq.value[1].value; - for(var vi = 0; vi < values.length; ++vi) { - var obj = {}; - obj.type = type; - obj.value = values[vi].value; - obj.valueTagClass = values[vi].type; - // if the OID is known, get its name and short name - if(obj.type in oids) { - obj.name = oids[obj.type]; - if(obj.name in _shortNames) { - obj.shortName = _shortNames[obj.name]; - } - } - // parse extensions - if(obj.type === oids.extensionRequest) { - obj.extensions = []; - for(var ei = 0; ei < obj.value.length; ++ei) { - obj.extensions.push(pki.certificateExtensionFromAsn1(obj.value[ei])); - } - } - rval.push(obj); - } - } - - return rval; -}; - -/** - * Gets an issuer or subject attribute from its name, type, or short name. - * - * @param obj the issuer or subject object. - * @param options a short name string or an object with: - * shortName the short name for the attribute. - * name the name for the attribute. - * type the type for the attribute. - * - * @return the attribute. - */ -function _getAttribute(obj, options) { - if(typeof options === 'string') { - options = {shortName: options}; - } - - var rval = null; - var attr; - for(var i = 0; rval === null && i < obj.attributes.length; ++i) { - attr = obj.attributes[i]; - if(options.type && options.type === attr.type) { - rval = attr; - } else if(options.name && options.name === attr.name) { - rval = attr; - } else if(options.shortName && options.shortName === attr.shortName) { - rval = attr; - } - } - return rval; -} - -/** - * Converts signature parameters from ASN.1 structure. - * - * Currently only RSASSA-PSS supported. The PKCS#1 v1.5 signature scheme had - * no parameters. - * - * RSASSA-PSS-params ::= SEQUENCE { - * hashAlgorithm [0] HashAlgorithm DEFAULT - * sha1Identifier, - * maskGenAlgorithm [1] MaskGenAlgorithm DEFAULT - * mgf1SHA1Identifier, - * saltLength [2] INTEGER DEFAULT 20, - * trailerField [3] INTEGER DEFAULT 1 - * } - * - * HashAlgorithm ::= AlgorithmIdentifier - * - * MaskGenAlgorithm ::= AlgorithmIdentifier - * - * AlgorithmIdentifer ::= SEQUENCE { - * algorithm OBJECT IDENTIFIER, - * parameters ANY DEFINED BY algorithm OPTIONAL - * } - * - * @param oid The OID specifying the signature algorithm - * @param obj The ASN.1 structure holding the parameters - * @param fillDefaults Whether to use return default values where omitted - * @return signature parameter object - */ -var _readSignatureParameters = function(oid, obj, fillDefaults) { - var params = {}; - - if(oid !== oids['RSASSA-PSS']) { - return params; - } - - if(fillDefaults) { - params = { - hash: { - algorithmOid: oids['sha1'] - }, - mgf: { - algorithmOid: oids['mgf1'], - hash: { - algorithmOid: oids['sha1'] - } - }, - saltLength: 20 - }; - } - - var capture = {}; - var errors = []; - if(!asn1.validate(obj, rsassaPssParameterValidator, capture, errors)) { - var error = new Error('Cannot read RSASSA-PSS parameter block.'); - error.errors = errors; - throw error; - } - - if(capture.hashOid !== undefined) { - params.hash = params.hash || {}; - params.hash.algorithmOid = asn1.derToOid(capture.hashOid); - } - - if(capture.maskGenOid !== undefined) { - params.mgf = params.mgf || {}; - params.mgf.algorithmOid = asn1.derToOid(capture.maskGenOid); - params.mgf.hash = params.mgf.hash || {}; - params.mgf.hash.algorithmOid = asn1.derToOid(capture.maskGenHashOid); - } - - if(capture.saltLength !== undefined) { - params.saltLength = capture.saltLength.charCodeAt(0); - } - - return params; -}; - -/** - * Converts an X.509 certificate from PEM format. - * - * Note: If the certificate is to be verified then compute hash should - * be set to true. This will scan the TBSCertificate part of the ASN.1 - * object while it is converted so it doesn't need to be converted back - * to ASN.1-DER-encoding later. - * - * @param pem the PEM-formatted certificate. - * @param computeHash true to compute the hash for verification. - * @param strict true to be strict when checking ASN.1 value lengths, false to - * allow truncated values (default: true). - * - * @return the certificate. - */ -pki.certificateFromPem = function(pem, computeHash, strict) { - var msg = forge.pem.decode(pem)[0]; - - if(msg.type !== 'CERTIFICATE' && - msg.type !== 'X509 CERTIFICATE' && - msg.type !== 'TRUSTED CERTIFICATE') { - var error = new Error('Could not convert certificate from PEM; PEM header type ' + - 'is not "CERTIFICATE", "X509 CERTIFICATE", or "TRUSTED CERTIFICATE".'); - error.headerType = msg.type; - throw error; - } - if(msg.procType && msg.procType.type === 'ENCRYPTED') { - throw new Error('Could not convert certificate from PEM; PEM is encrypted.'); - } - - // convert DER to ASN.1 object - var obj = asn1.fromDer(msg.body, strict); - - return pki.certificateFromAsn1(obj, computeHash); -}; - -/** - * Converts an X.509 certificate to PEM format. - * - * @param cert the certificate. - * @param maxline the maximum characters per line, defaults to 64. - * - * @return the PEM-formatted certificate. - */ -pki.certificateToPem = function(cert, maxline) { - // convert to ASN.1, then DER, then PEM-encode - var msg = { - type: 'CERTIFICATE', - body: asn1.toDer(pki.certificateToAsn1(cert)).getBytes() - }; - return forge.pem.encode(msg, {maxline: maxline}); -}; - -/** - * Converts an RSA public key from PEM format. - * - * @param pem the PEM-formatted public key. - * - * @return the public key. - */ -pki.publicKeyFromPem = function(pem) { - var msg = forge.pem.decode(pem)[0]; - - if(msg.type !== 'PUBLIC KEY' && msg.type !== 'RSA PUBLIC KEY') { - var error = new Error('Could not convert public key from PEM; PEM header ' + - 'type is not "PUBLIC KEY" or "RSA PUBLIC KEY".'); - error.headerType = msg.type; - throw error; - } - if(msg.procType && msg.procType.type === 'ENCRYPTED') { - throw new Error('Could not convert public key from PEM; PEM is encrypted.'); - } - - // convert DER to ASN.1 object - var obj = asn1.fromDer(msg.body); - - return pki.publicKeyFromAsn1(obj); -}; - -/** - * Converts an RSA public key to PEM format (using a SubjectPublicKeyInfo). - * - * @param key the public key. - * @param maxline the maximum characters per line, defaults to 64. - * - * @return the PEM-formatted public key. - */ -pki.publicKeyToPem = function(key, maxline) { - // convert to ASN.1, then DER, then PEM-encode - var msg = { - type: 'PUBLIC KEY', - body: asn1.toDer(pki.publicKeyToAsn1(key)).getBytes() - }; - return forge.pem.encode(msg, {maxline: maxline}); -}; - -/** - * Converts an RSA public key to PEM format (using an RSAPublicKey). - * - * @param key the public key. - * @param maxline the maximum characters per line, defaults to 64. - * - * @return the PEM-formatted public key. - */ -pki.publicKeyToRSAPublicKeyPem = function(key, maxline) { - // convert to ASN.1, then DER, then PEM-encode - var msg = { - type: 'RSA PUBLIC KEY', - body: asn1.toDer(pki.publicKeyToRSAPublicKey(key)).getBytes() - }; - return forge.pem.encode(msg, {maxline: maxline}); -}; - -/** - * Gets a fingerprint for the given public key. - * - * @param options the options to use. - * [md] the message digest object to use (defaults to forge.md.sha1). - * [type] the type of fingerprint, such as 'RSAPublicKey', - * 'SubjectPublicKeyInfo' (defaults to 'RSAPublicKey'). - * [encoding] an alternative output encoding, such as 'hex' - * (defaults to none, outputs a byte buffer). - * [delimiter] the delimiter to use between bytes for 'hex' encoded - * output, eg: ':' (defaults to none). - * - * @return the fingerprint as a byte buffer or other encoding based on options. - */ -pki.getPublicKeyFingerprint = function(key, options) { - options = options || {}; - var md = options.md || forge.md.sha1.create(); - var type = options.type || 'RSAPublicKey'; - - var bytes; - switch(type) { - case 'RSAPublicKey': - bytes = asn1.toDer(pki.publicKeyToRSAPublicKey(key)).getBytes(); - break; - case 'SubjectPublicKeyInfo': - bytes = asn1.toDer(pki.publicKeyToAsn1(key)).getBytes(); - break; - default: - throw new Error('Unknown fingerprint type "' + options.type + '".'); - } - - // hash public key bytes - md.start(); - md.update(bytes); - var digest = md.digest(); - if(options.encoding === 'hex') { - var hex = digest.toHex(); - if(options.delimiter) { - return hex.match(/.{2}/g).join(options.delimiter); - } - return hex; - } else if(options.encoding === 'binary') { - return digest.getBytes(); - } else if(options.encoding) { - throw new Error('Unknown encoding "' + options.encoding + '".'); - } - return digest; -}; - -/** - * Converts a PKCS#10 certification request (CSR) from PEM format. - * - * Note: If the certification request is to be verified then compute hash - * should be set to true. This will scan the CertificationRequestInfo part of - * the ASN.1 object while it is converted so it doesn't need to be converted - * back to ASN.1-DER-encoding later. - * - * @param pem the PEM-formatted certificate. - * @param computeHash true to compute the hash for verification. - * @param strict true to be strict when checking ASN.1 value lengths, false to - * allow truncated values (default: true). - * - * @return the certification request (CSR). - */ -pki.certificationRequestFromPem = function(pem, computeHash, strict) { - var msg = forge.pem.decode(pem)[0]; - - if(msg.type !== 'CERTIFICATE REQUEST') { - var error = new Error('Could not convert certification request from PEM; ' + - 'PEM header type is not "CERTIFICATE REQUEST".'); - error.headerType = msg.type; - throw error; - } - if(msg.procType && msg.procType.type === 'ENCRYPTED') { - throw new Error('Could not convert certification request from PEM; ' + - 'PEM is encrypted.'); - } - - // convert DER to ASN.1 object - var obj = asn1.fromDer(msg.body, strict); - - return pki.certificationRequestFromAsn1(obj, computeHash); -}; - -/** - * Converts a PKCS#10 certification request (CSR) to PEM format. - * - * @param csr the certification request. - * @param maxline the maximum characters per line, defaults to 64. - * - * @return the PEM-formatted certification request. - */ -pki.certificationRequestToPem = function(csr, maxline) { - // convert to ASN.1, then DER, then PEM-encode - var msg = { - type: 'CERTIFICATE REQUEST', - body: asn1.toDer(pki.certificationRequestToAsn1(csr)).getBytes() - }; - return forge.pem.encode(msg, {maxline: maxline}); -}; - -/** - * Creates an empty X.509v3 RSA certificate. - * - * @return the certificate. - */ -pki.createCertificate = function() { - var cert = {}; - cert.version = 0x02; - cert.serialNumber = '00'; - cert.signatureOid = null; - cert.signature = null; - cert.siginfo = {}; - cert.siginfo.algorithmOid = null; - cert.validity = {}; - cert.validity.notBefore = new Date(); - cert.validity.notAfter = new Date(); - - cert.issuer = {}; - cert.issuer.getField = function(sn) { - return _getAttribute(cert.issuer, sn); - }; - cert.issuer.addField = function(attr) { - _fillMissingFields([attr]); - cert.issuer.attributes.push(attr); - }; - cert.issuer.attributes = []; - cert.issuer.hash = null; - - cert.subject = {}; - cert.subject.getField = function(sn) { - return _getAttribute(cert.subject, sn); - }; - cert.subject.addField = function(attr) { - _fillMissingFields([attr]); - cert.subject.attributes.push(attr); - }; - cert.subject.attributes = []; - cert.subject.hash = null; - - cert.extensions = []; - cert.publicKey = null; - cert.md = null; - - /** - * Sets the subject of this certificate. - * - * @param attrs the array of subject attributes to use. - * @param uniqueId an optional a unique ID to use. - */ - cert.setSubject = function(attrs, uniqueId) { - // set new attributes, clear hash - _fillMissingFields(attrs); - cert.subject.attributes = attrs; - delete cert.subject.uniqueId; - if(uniqueId) { - cert.subject.uniqueId = uniqueId; - } - cert.subject.hash = null; - }; - - /** - * Sets the issuer of this certificate. - * - * @param attrs the array of issuer attributes to use. - * @param uniqueId an optional a unique ID to use. - */ - cert.setIssuer = function(attrs, uniqueId) { - // set new attributes, clear hash - _fillMissingFields(attrs); - cert.issuer.attributes = attrs; - delete cert.issuer.uniqueId; - if(uniqueId) { - cert.issuer.uniqueId = uniqueId; - } - cert.issuer.hash = null; - }; - - /** - * Sets the extensions of this certificate. - * - * @param exts the array of extensions to use. - */ - cert.setExtensions = function(exts) { - for(var i = 0; i < exts.length; ++i) { - _fillMissingExtensionFields(exts[i], {cert: cert}); - } - // set new extensions - cert.extensions = exts; - }; - - /** - * Gets an extension by its name or id. - * - * @param options the name to use or an object with: - * name the name to use. - * id the id to use. - * - * @return the extension or null if not found. - */ - cert.getExtension = function(options) { - if(typeof options === 'string') { - options = {name: options}; - } - - var rval = null; - var ext; - for(var i = 0; rval === null && i < cert.extensions.length; ++i) { - ext = cert.extensions[i]; - if(options.id && ext.id === options.id) { - rval = ext; - } else if(options.name && ext.name === options.name) { - rval = ext; - } - } - return rval; - }; - - /** - * Signs this certificate using the given private key. - * - * @param key the private key to sign with. - * @param md the message digest object to use (defaults to forge.md.sha1). - */ - cert.sign = function(key, md) { - // TODO: get signature OID from private key - cert.md = md || forge.md.sha1.create(); - var algorithmOid = oids[cert.md.algorithm + 'WithRSAEncryption']; - if(!algorithmOid) { - var error = new Error('Could not compute certificate digest. ' + - 'Unknown message digest algorithm OID.'); - error.algorithm = cert.md.algorithm; - throw error; - } - cert.signatureOid = cert.siginfo.algorithmOid = algorithmOid; - - // get TBSCertificate, convert to DER - cert.tbsCertificate = pki.getTBSCertificate(cert); - var bytes = asn1.toDer(cert.tbsCertificate); - - // digest and sign - cert.md.update(bytes.getBytes()); - cert.signature = key.sign(cert.md); - }; - - /** - * Attempts verify the signature on the passed certificate using this - * certificate's public key. - * - * @param child the certificate to verify. - * - * @return true if verified, false if not. - */ - cert.verify = function(child) { - var rval = false; - - if(!cert.issued(child)) { - var issuer = child.issuer; - var subject = cert.subject; - var error = new Error('The parent certificate did not issue the given child ' + - 'certificate; the child certificate\'s issuer does not match the ' + - 'parent\'s subject.'); - error.expectedIssuer = issuer.attributes; - error.actualIssuer = subject.attributes; - throw error; - } - - var md = child.md; - if(md === null) { - // check signature OID for supported signature types - if(child.signatureOid in oids) { - var oid = oids[child.signatureOid]; - switch(oid) { - case 'sha1WithRSAEncryption': - md = forge.md.sha1.create(); - break; - case 'md5WithRSAEncryption': - md = forge.md.md5.create(); - break; - case 'sha256WithRSAEncryption': - md = forge.md.sha256.create(); - break; - case 'RSASSA-PSS': - md = forge.md.sha256.create(); - break; - } - } - if(md === null) { - var error = new Error('Could not compute certificate digest. ' + - 'Unknown signature OID.'); - error.signatureOid = child.signatureOid; - throw error; - } - - // produce DER formatted TBSCertificate and digest it - var tbsCertificate = child.tbsCertificate || pki.getTBSCertificate(child); - var bytes = asn1.toDer(tbsCertificate); - md.update(bytes.getBytes()); - } - - if(md !== null) { - var scheme; - - switch(child.signatureOid) { - case oids.sha1WithRSAEncryption: - scheme = undefined; /* use PKCS#1 v1.5 padding scheme */ - break; - case oids['RSASSA-PSS']: - var hash, mgf; - - /* initialize mgf */ - hash = oids[child.signatureParameters.mgf.hash.algorithmOid]; - if(hash === undefined || forge.md[hash] === undefined) { - var error = new Error('Unsupported MGF hash function.'); - error.oid = child.signatureParameters.mgf.hash.algorithmOid; - error.name = hash; - throw error; - } - - mgf = oids[child.signatureParameters.mgf.algorithmOid]; - if(mgf === undefined || forge.mgf[mgf] === undefined) { - var error = new Error('Unsupported MGF function.'); - error.oid = child.signatureParameters.mgf.algorithmOid; - error.name = mgf; - throw error; - } - - mgf = forge.mgf[mgf].create(forge.md[hash].create()); - - /* initialize hash function */ - hash = oids[child.signatureParameters.hash.algorithmOid]; - if(hash === undefined || forge.md[hash] === undefined) { - throw { - message: 'Unsupported RSASSA-PSS hash function.', - oid: child.signatureParameters.hash.algorithmOid, - name: hash - }; - } - - scheme = forge.pss.create(forge.md[hash].create(), mgf, - child.signatureParameters.saltLength); - break; - } - - // verify signature on cert using public key - rval = cert.publicKey.verify( - md.digest().getBytes(), child.signature, scheme); - } - - return rval; - }; - - /** - * Returns true if this certificate's issuer matches the passed - * certificate's subject. Note that no signature check is performed. - * - * @param parent the certificate to check. - * - * @return true if this certificate's issuer matches the passed certificate's - * subject. - */ - cert.isIssuer = function(parent) { - var rval = false; - - var i = cert.issuer; - var s = parent.subject; - - // compare hashes if present - if(i.hash && s.hash) { - rval = (i.hash === s.hash); - } else if(i.attributes.length === s.attributes.length) { - // all attributes are the same so issuer matches subject - rval = true; - var iattr, sattr; - for(var n = 0; rval && n < i.attributes.length; ++n) { - iattr = i.attributes[n]; - sattr = s.attributes[n]; - if(iattr.type !== sattr.type || iattr.value !== sattr.value) { - // attribute mismatch - rval = false; - } - } - } - - return rval; - }; - - /** - * Returns true if this certificate's subject matches the issuer of the - * given certificate). Note that not signature check is performed. - * - * @param child the certificate to check. - * - * @return true if this certificate's subject matches the passed - * certificate's issuer. - */ - cert.issued = function(child) { - return child.isIssuer(cert); - }; - - /** - * Generates the subjectKeyIdentifier for this certificate as byte buffer. - * - * @return the subjectKeyIdentifier for this certificate as byte buffer. - */ - cert.generateSubjectKeyIdentifier = function() { - /* See: 4.2.1.2 section of the the RFC3280, keyIdentifier is either: - - (1) The keyIdentifier is composed of the 160-bit SHA-1 hash of the - value of the BIT STRING subjectPublicKey (excluding the tag, - length, and number of unused bits). - - (2) The keyIdentifier is composed of a four bit type field with - the value 0100 followed by the least significant 60 bits of the - SHA-1 hash of the value of the BIT STRING subjectPublicKey - (excluding the tag, length, and number of unused bit string bits). - */ - - // skipping the tag, length, and number of unused bits is the same - // as just using the RSAPublicKey (for RSA keys, which are the - // only ones supported) - return pki.getPublicKeyFingerprint(cert.publicKey, {type: 'RSAPublicKey'}); - }; - - /** - * Verifies the subjectKeyIdentifier extension value for this certificate - * against its public key. If no extension is found, false will be - * returned. - * - * @return true if verified, false if not. - */ - cert.verifySubjectKeyIdentifier = function() { - var oid = oids['subjectKeyIdentifier']; - for(var i = 0; i < cert.extensions.length; ++i) { - var ext = cert.extensions[i]; - if(ext.id === oid) { - var ski = cert.generateSubjectKeyIdentifier().getBytes(); - return (forge.util.hexToBytes(ext.subjectKeyIdentifier) === ski); - } - } - return false; - }; - - return cert; -}; - -/** - * Converts an X.509v3 RSA certificate from an ASN.1 object. - * - * Note: If the certificate is to be verified then compute hash should - * be set to true. There is currently no implementation for converting - * a certificate back to ASN.1 so the TBSCertificate part of the ASN.1 - * object needs to be scanned before the cert object is created. - * - * @param obj the asn1 representation of an X.509v3 RSA certificate. - * @param computeHash true to compute the hash for verification. - * - * @return the certificate. - */ -pki.certificateFromAsn1 = function(obj, computeHash) { - // validate certificate and capture data - var capture = {}; - var errors = []; - if(!asn1.validate(obj, x509CertificateValidator, capture, errors)) { - var error = new Error('Cannot read X.509 certificate. ' + - 'ASN.1 object is not an X509v3 Certificate.'); - error.errors = errors; - throw error; - } - - // ensure signature is not interpreted as an embedded ASN.1 object - if(typeof capture.certSignature !== 'string') { - var certSignature = '\x00'; - for(var i = 0; i < capture.certSignature.length; ++i) { - certSignature += asn1.toDer(capture.certSignature[i]).getBytes(); - } - capture.certSignature = certSignature; - } - - // get oid - var oid = asn1.derToOid(capture.publicKeyOid); - if(oid !== pki.oids['rsaEncryption']) { - throw new Error('Cannot read public key. OID is not RSA.'); - } - - // create certificate - var cert = pki.createCertificate(); - cert.version = capture.certVersion ? - capture.certVersion.charCodeAt(0) : 0; - var serial = forge.util.createBuffer(capture.certSerialNumber); - cert.serialNumber = serial.toHex(); - cert.signatureOid = forge.asn1.derToOid(capture.certSignatureOid); - cert.signatureParameters = _readSignatureParameters( - cert.signatureOid, capture.certSignatureParams, true); - cert.siginfo.algorithmOid = forge.asn1.derToOid(capture.certinfoSignatureOid); - cert.siginfo.parameters = _readSignatureParameters(cert.siginfo.algorithmOid, - capture.certinfoSignatureParams, false); - // skip "unused bits" in signature value BITSTRING - var signature = forge.util.createBuffer(capture.certSignature); - ++signature.read; - cert.signature = signature.getBytes(); - - var validity = []; - if(capture.certValidity1UTCTime !== undefined) { - validity.push(asn1.utcTimeToDate(capture.certValidity1UTCTime)); - } - if(capture.certValidity2GeneralizedTime !== undefined) { - validity.push(asn1.generalizedTimeToDate( - capture.certValidity2GeneralizedTime)); - } - if(capture.certValidity3UTCTime !== undefined) { - validity.push(asn1.utcTimeToDate(capture.certValidity3UTCTime)); - } - if(capture.certValidity4GeneralizedTime !== undefined) { - validity.push(asn1.generalizedTimeToDate( - capture.certValidity4GeneralizedTime)); - } - if(validity.length > 2) { - throw new Error('Cannot read notBefore/notAfter validity times; more ' + - 'than two times were provided in the certificate.'); - } - if(validity.length < 2) { - throw new Error('Cannot read notBefore/notAfter validity times; they ' + - 'were not provided as either UTCTime or GeneralizedTime.'); - } - cert.validity.notBefore = validity[0]; - cert.validity.notAfter = validity[1]; - - // keep TBSCertificate to preserve signature when exporting - cert.tbsCertificate = capture.tbsCertificate; - - if(computeHash) { - // check signature OID for supported signature types - cert.md = null; - if(cert.signatureOid in oids) { - var oid = oids[cert.signatureOid]; - switch(oid) { - case 'sha1WithRSAEncryption': - cert.md = forge.md.sha1.create(); - break; - case 'md5WithRSAEncryption': - cert.md = forge.md.md5.create(); - break; - case 'sha256WithRSAEncryption': - cert.md = forge.md.sha256.create(); - break; - case 'RSASSA-PSS': - cert.md = forge.md.sha256.create(); - break; - } - } - if(cert.md === null) { - var error = new Error('Could not compute certificate digest. ' + - 'Unknown signature OID.'); - error.signatureOid = cert.signatureOid; - throw error; - } - - // produce DER formatted TBSCertificate and digest it - var bytes = asn1.toDer(cert.tbsCertificate); - cert.md.update(bytes.getBytes()); - } - - // handle issuer, build issuer message digest - var imd = forge.md.sha1.create(); - cert.issuer.getField = function(sn) { - return _getAttribute(cert.issuer, sn); - }; - cert.issuer.addField = function(attr) { - _fillMissingFields([attr]); - cert.issuer.attributes.push(attr); - }; - cert.issuer.attributes = pki.RDNAttributesAsArray(capture.certIssuer, imd); - if(capture.certIssuerUniqueId) { - cert.issuer.uniqueId = capture.certIssuerUniqueId; - } - cert.issuer.hash = imd.digest().toHex(); - - // handle subject, build subject message digest - var smd = forge.md.sha1.create(); - cert.subject.getField = function(sn) { - return _getAttribute(cert.subject, sn); - }; - cert.subject.addField = function(attr) { - _fillMissingFields([attr]); - cert.subject.attributes.push(attr); - }; - cert.subject.attributes = pki.RDNAttributesAsArray(capture.certSubject, smd); - if(capture.certSubjectUniqueId) { - cert.subject.uniqueId = capture.certSubjectUniqueId; - } - cert.subject.hash = smd.digest().toHex(); - - // handle extensions - if(capture.certExtensions) { - cert.extensions = pki.certificateExtensionsFromAsn1(capture.certExtensions); - } else { - cert.extensions = []; - } - - // convert RSA public key from ASN.1 - cert.publicKey = pki.publicKeyFromAsn1(capture.subjectPublicKeyInfo); - - return cert; -}; - -/** - * Converts an ASN.1 extensions object (with extension sequences as its - * values) into an array of extension objects with types and values. - * - * Supported extensions: - * - * id-ce-keyUsage OBJECT IDENTIFIER ::= { id-ce 15 } - * KeyUsage ::= BIT STRING { - * digitalSignature (0), - * nonRepudiation (1), - * keyEncipherment (2), - * dataEncipherment (3), - * keyAgreement (4), - * keyCertSign (5), - * cRLSign (6), - * encipherOnly (7), - * decipherOnly (8) - * } - * - * id-ce-basicConstraints OBJECT IDENTIFIER ::= { id-ce 19 } - * BasicConstraints ::= SEQUENCE { - * cA BOOLEAN DEFAULT FALSE, - * pathLenConstraint INTEGER (0..MAX) OPTIONAL - * } - * - * subjectAltName EXTENSION ::= { - * SYNTAX GeneralNames - * IDENTIFIED BY id-ce-subjectAltName - * } - * - * GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName - * - * GeneralName ::= CHOICE { - * otherName [0] INSTANCE OF OTHER-NAME, - * rfc822Name [1] IA5String, - * dNSName [2] IA5String, - * x400Address [3] ORAddress, - * directoryName [4] Name, - * ediPartyName [5] EDIPartyName, - * uniformResourceIdentifier [6] IA5String, - * IPAddress [7] OCTET STRING, - * registeredID [8] OBJECT IDENTIFIER - * } - * - * OTHER-NAME ::= TYPE-IDENTIFIER - * - * EDIPartyName ::= SEQUENCE { - * nameAssigner [0] DirectoryString {ub-name} OPTIONAL, - * partyName [1] DirectoryString {ub-name} - * } - * - * @param exts the extensions ASN.1 with extension sequences to parse. - * - * @return the array. - */ -pki.certificateExtensionsFromAsn1 = function(exts) { - var rval = []; - for(var i = 0; i < exts.value.length; ++i) { - // get extension sequence - var extseq = exts.value[i]; - for(var ei = 0; ei < extseq.value.length; ++ei) { - rval.push(pki.certificateExtensionFromAsn1(extseq.value[ei])); - } - } - - return rval; -}; - -/** - * Parses a single certificate extension from ASN.1. - * - * @param ext the extension in ASN.1 format. - * - * @return the parsed extension as an object. - */ -pki.certificateExtensionFromAsn1 = function(ext) { - // an extension has: - // [0] extnID OBJECT IDENTIFIER - // [1] critical BOOLEAN DEFAULT FALSE - // [2] extnValue OCTET STRING - var e = {}; - e.id = asn1.derToOid(ext.value[0].value); - e.critical = false; - if(ext.value[1].type === asn1.Type.BOOLEAN) { - e.critical = (ext.value[1].value.charCodeAt(0) !== 0x00); - e.value = ext.value[2].value; - } else { - e.value = ext.value[1].value; - } - // if the oid is known, get its name - if(e.id in oids) { - e.name = oids[e.id]; - - // handle key usage - if(e.name === 'keyUsage') { - // get value as BIT STRING - var ev = asn1.fromDer(e.value); - var b2 = 0x00; - var b3 = 0x00; - if(ev.value.length > 1) { - // skip first byte, just indicates unused bits which - // will be padded with 0s anyway - // get bytes with flag bits - b2 = ev.value.charCodeAt(1); - b3 = ev.value.length > 2 ? ev.value.charCodeAt(2) : 0; - } - // set flags - e.digitalSignature = (b2 & 0x80) === 0x80; - e.nonRepudiation = (b2 & 0x40) === 0x40; - e.keyEncipherment = (b2 & 0x20) === 0x20; - e.dataEncipherment = (b2 & 0x10) === 0x10; - e.keyAgreement = (b2 & 0x08) === 0x08; - e.keyCertSign = (b2 & 0x04) === 0x04; - e.cRLSign = (b2 & 0x02) === 0x02; - e.encipherOnly = (b2 & 0x01) === 0x01; - e.decipherOnly = (b3 & 0x80) === 0x80; - } else if(e.name === 'basicConstraints') { - // handle basic constraints - // get value as SEQUENCE - var ev = asn1.fromDer(e.value); - // get cA BOOLEAN flag (defaults to false) - if(ev.value.length > 0 && ev.value[0].type === asn1.Type.BOOLEAN) { - e.cA = (ev.value[0].value.charCodeAt(0) !== 0x00); - } else { - e.cA = false; - } - // get path length constraint - var value = null; - if(ev.value.length > 0 && ev.value[0].type === asn1.Type.INTEGER) { - value = ev.value[0].value; - } else if(ev.value.length > 1) { - value = ev.value[1].value; - } - if(value !== null) { - e.pathLenConstraint = asn1.derToInteger(value); - } - } else if(e.name === 'extKeyUsage') { - // handle extKeyUsage - // value is a SEQUENCE of OIDs - var ev = asn1.fromDer(e.value); - for(var vi = 0; vi < ev.value.length; ++vi) { - var oid = asn1.derToOid(ev.value[vi].value); - if(oid in oids) { - e[oids[oid]] = true; - } else { - e[oid] = true; - } - } - } else if(e.name === 'nsCertType') { - // handle nsCertType - // get value as BIT STRING - var ev = asn1.fromDer(e.value); - var b2 = 0x00; - if(ev.value.length > 1) { - // skip first byte, just indicates unused bits which - // will be padded with 0s anyway - // get bytes with flag bits - b2 = ev.value.charCodeAt(1); - } - // set flags - e.client = (b2 & 0x80) === 0x80; - e.server = (b2 & 0x40) === 0x40; - e.email = (b2 & 0x20) === 0x20; - e.objsign = (b2 & 0x10) === 0x10; - e.reserved = (b2 & 0x08) === 0x08; - e.sslCA = (b2 & 0x04) === 0x04; - e.emailCA = (b2 & 0x02) === 0x02; - e.objCA = (b2 & 0x01) === 0x01; - } else if( - e.name === 'subjectAltName' || - e.name === 'issuerAltName') { - // handle subjectAltName/issuerAltName - e.altNames = []; - - // ev is a SYNTAX SEQUENCE - var gn; - var ev = asn1.fromDer(e.value); - for(var n = 0; n < ev.value.length; ++n) { - // get GeneralName - gn = ev.value[n]; - - var altName = { - type: gn.type, - value: gn.value - }; - e.altNames.push(altName); - - // Note: Support for types 1,2,6,7,8 - switch(gn.type) { - // rfc822Name - case 1: - // dNSName - case 2: - // uniformResourceIdentifier (URI) - case 6: - break; - // IPAddress - case 7: - // convert to IPv4/IPv6 string representation - altName.ip = forge.util.bytesToIP(gn.value); - break; - // registeredID - case 8: - altName.oid = asn1.derToOid(gn.value); - break; - default: - // unsupported - } - } - } else if(e.name === 'subjectKeyIdentifier') { - // value is an OCTETSTRING w/the hash of the key-type specific - // public key structure (eg: RSAPublicKey) - var ev = asn1.fromDer(e.value); - e.subjectKeyIdentifier = forge.util.bytesToHex(ev.value); - } - } - return e; -}; - -/** - * Converts a PKCS#10 certification request (CSR) from an ASN.1 object. - * - * Note: If the certification request is to be verified then compute hash - * should be set to true. There is currently no implementation for converting - * a certificate back to ASN.1 so the CertificationRequestInfo part of the - * ASN.1 object needs to be scanned before the csr object is created. - * - * @param obj the asn1 representation of a PKCS#10 certification request (CSR). - * @param computeHash true to compute the hash for verification. - * - * @return the certification request (CSR). - */ -pki.certificationRequestFromAsn1 = function(obj, computeHash) { - // validate certification request and capture data - var capture = {}; - var errors = []; - if(!asn1.validate(obj, certificationRequestValidator, capture, errors)) { - var error = new Error('Cannot read PKCS#10 certificate request. ' + - 'ASN.1 object is not a PKCS#10 CertificationRequest.'); - error.errors = errors; - throw error; - } - - // ensure signature is not interpreted as an embedded ASN.1 object - if(typeof capture.csrSignature !== 'string') { - var csrSignature = '\x00'; - for(var i = 0; i < capture.csrSignature.length; ++i) { - csrSignature += asn1.toDer(capture.csrSignature[i]).getBytes(); - } - capture.csrSignature = csrSignature; - } - - // get oid - var oid = asn1.derToOid(capture.publicKeyOid); - if(oid !== pki.oids.rsaEncryption) { - throw new Error('Cannot read public key. OID is not RSA.'); - } - - // create certification request - var csr = pki.createCertificationRequest(); - csr.version = capture.csrVersion ? capture.csrVersion.charCodeAt(0) : 0; - csr.signatureOid = forge.asn1.derToOid(capture.csrSignatureOid); - csr.signatureParameters = _readSignatureParameters( - csr.signatureOid, capture.csrSignatureParams, true); - csr.siginfo.algorithmOid = forge.asn1.derToOid(capture.csrSignatureOid); - csr.siginfo.parameters = _readSignatureParameters( - csr.siginfo.algorithmOid, capture.csrSignatureParams, false); - // skip "unused bits" in signature value BITSTRING - var signature = forge.util.createBuffer(capture.csrSignature); - ++signature.read; - csr.signature = signature.getBytes(); - - // keep CertificationRequestInfo to preserve signature when exporting - csr.certificationRequestInfo = capture.certificationRequestInfo; - - if(computeHash) { - // check signature OID for supported signature types - csr.md = null; - if(csr.signatureOid in oids) { - var oid = oids[csr.signatureOid]; - switch(oid) { - case 'sha1WithRSAEncryption': - csr.md = forge.md.sha1.create(); - break; - case 'md5WithRSAEncryption': - csr.md = forge.md.md5.create(); - break; - case 'sha256WithRSAEncryption': - csr.md = forge.md.sha256.create(); - break; - case 'RSASSA-PSS': - csr.md = forge.md.sha256.create(); - break; - } - } - if(csr.md === null) { - var error = new Error('Could not compute certification request digest. ' + - 'Unknown signature OID.'); - error.signatureOid = csr.signatureOid; - throw error; - } - - // produce DER formatted CertificationRequestInfo and digest it - var bytes = asn1.toDer(csr.certificationRequestInfo); - csr.md.update(bytes.getBytes()); - } - - // handle subject, build subject message digest - var smd = forge.md.sha1.create(); - csr.subject.getField = function(sn) { - return _getAttribute(csr.subject, sn); - }; - csr.subject.addField = function(attr) { - _fillMissingFields([attr]); - csr.subject.attributes.push(attr); - }; - csr.subject.attributes = pki.RDNAttributesAsArray( - capture.certificationRequestInfoSubject, smd); - csr.subject.hash = smd.digest().toHex(); - - // convert RSA public key from ASN.1 - csr.publicKey = pki.publicKeyFromAsn1(capture.subjectPublicKeyInfo); - - // convert attributes from ASN.1 - csr.getAttribute = function(sn) { - return _getAttribute(csr, sn); - }; - csr.addAttribute = function(attr) { - _fillMissingFields([attr]); - csr.attributes.push(attr); - }; - csr.attributes = pki.CRIAttributesAsArray( - capture.certificationRequestInfoAttributes || []); - - return csr; -}; - -/** - * Creates an empty certification request (a CSR or certificate signing - * request). Once created, its public key and attributes can be set and then - * it can be signed. - * - * @return the empty certification request. - */ -pki.createCertificationRequest = function() { - var csr = {}; - csr.version = 0x00; - csr.signatureOid = null; - csr.signature = null; - csr.siginfo = {}; - csr.siginfo.algorithmOid = null; - - csr.subject = {}; - csr.subject.getField = function(sn) { - return _getAttribute(csr.subject, sn); - }; - csr.subject.addField = function(attr) { - _fillMissingFields([attr]); - csr.subject.attributes.push(attr); - }; - csr.subject.attributes = []; - csr.subject.hash = null; - - csr.publicKey = null; - csr.attributes = []; - csr.getAttribute = function(sn) { - return _getAttribute(csr, sn); - }; - csr.addAttribute = function(attr) { - _fillMissingFields([attr]); - csr.attributes.push(attr); - }; - csr.md = null; - - /** - * Sets the subject of this certification request. - * - * @param attrs the array of subject attributes to use. - */ - csr.setSubject = function(attrs) { - // set new attributes - _fillMissingFields(attrs); - csr.subject.attributes = attrs; - csr.subject.hash = null; - }; - - /** - * Sets the attributes of this certification request. - * - * @param attrs the array of attributes to use. - */ - csr.setAttributes = function(attrs) { - // set new attributes - _fillMissingFields(attrs); - csr.attributes = attrs; - }; - - /** - * Signs this certification request using the given private key. - * - * @param key the private key to sign with. - * @param md the message digest object to use (defaults to forge.md.sha1). - */ - csr.sign = function(key, md) { - // TODO: get signature OID from private key - csr.md = md || forge.md.sha1.create(); - var algorithmOid = oids[csr.md.algorithm + 'WithRSAEncryption']; - if(!algorithmOid) { - var error = new Error('Could not compute certification request digest. ' + - 'Unknown message digest algorithm OID.'); - error.algorithm = csr.md.algorithm; - throw error; - } - csr.signatureOid = csr.siginfo.algorithmOid = algorithmOid; - - // get CertificationRequestInfo, convert to DER - csr.certificationRequestInfo = pki.getCertificationRequestInfo(csr); - var bytes = asn1.toDer(csr.certificationRequestInfo); - - // digest and sign - csr.md.update(bytes.getBytes()); - csr.signature = key.sign(csr.md); - }; - - /** - * Attempts verify the signature on the passed certification request using - * its public key. - * - * A CSR that has been exported to a file in PEM format can be verified using - * OpenSSL using this command: - * - * openssl req -in <the-csr-pem-file> -verify -noout -text - * - * @return true if verified, false if not. - */ - csr.verify = function() { - var rval = false; - - var md = csr.md; - if(md === null) { - // check signature OID for supported signature types - if(csr.signatureOid in oids) { - var oid = oids[csr.signatureOid]; - switch(oid) { - case 'sha1WithRSAEncryption': - md = forge.md.sha1.create(); - break; - case 'md5WithRSAEncryption': - md = forge.md.md5.create(); - break; - case 'sha256WithRSAEncryption': - md = forge.md.sha256.create(); - break; - case 'RSASSA-PSS': - md = forge.md.sha256.create(); - break; - } - } - if(md === null) { - var error = new Error('Could not compute certification request digest. ' + - 'Unknown signature OID.'); - error.signatureOid = csr.signatureOid; - throw error; - } - - // produce DER formatted CertificationRequestInfo and digest it - var cri = csr.certificationRequestInfo || - pki.getCertificationRequestInfo(csr); - var bytes = asn1.toDer(cri); - md.update(bytes.getBytes()); - } - - if(md !== null) { - var scheme; - - switch(csr.signatureOid) { - case oids.sha1WithRSAEncryption: - /* use PKCS#1 v1.5 padding scheme */ - break; - case oids['RSASSA-PSS']: - var hash, mgf; - - /* initialize mgf */ - hash = oids[csr.signatureParameters.mgf.hash.algorithmOid]; - if(hash === undefined || forge.md[hash] === undefined) { - var error = new Error('Unsupported MGF hash function.'); - error.oid = csr.signatureParameters.mgf.hash.algorithmOid; - error.name = hash; - throw error; - } - - mgf = oids[csr.signatureParameters.mgf.algorithmOid]; - if(mgf === undefined || forge.mgf[mgf] === undefined) { - var error = new Error('Unsupported MGF function.'); - error.oid = csr.signatureParameters.mgf.algorithmOid; - error.name = mgf; - throw error; - } - - mgf = forge.mgf[mgf].create(forge.md[hash].create()); - - /* initialize hash function */ - hash = oids[csr.signatureParameters.hash.algorithmOid]; - if(hash === undefined || forge.md[hash] === undefined) { - var error = new Error('Unsupported RSASSA-PSS hash function.'); - error.oid = csr.signatureParameters.hash.algorithmOid; - error.name = hash; - throw error; - } - - scheme = forge.pss.create(forge.md[hash].create(), mgf, - csr.signatureParameters.saltLength); - break; - } - - // verify signature on csr using its public key - rval = csr.publicKey.verify( - md.digest().getBytes(), csr.signature, scheme); - } - - return rval; - }; - - return csr; -}; - -/** - * Converts an X.509 subject or issuer to an ASN.1 RDNSequence. - * - * @param obj the subject or issuer (distinguished name). - * - * @return the ASN.1 RDNSequence. - */ -function _dnToAsn1(obj) { - // create an empty RDNSequence - var rval = asn1.create( - asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, []); - - // iterate over attributes - var attr, set; - var attrs = obj.attributes; - for(var i = 0; i < attrs.length; ++i) { - attr = attrs[i]; - var value = attr.value; - - // reuse tag class for attribute value if available - var valueTagClass = asn1.Type.PRINTABLESTRING; - if('valueTagClass' in attr) { - valueTagClass = attr.valueTagClass; - - if(valueTagClass === asn1.Type.UTF8) { - value = forge.util.encodeUtf8(value); - } - // FIXME: handle more encodings - } - - // create a RelativeDistinguishedName set - // each value in the set is an AttributeTypeAndValue first - // containing the type (an OID) and second the value - set = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SET, true, [ - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [ - // AttributeType - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, - asn1.oidToDer(attr.type).getBytes()), - // AttributeValue - asn1.create(asn1.Class.UNIVERSAL, valueTagClass, false, value) - ]) - ]); - rval.value.push(set); - } - - return rval; -} - -/** - * Gets all printable attributes (typically of an issuer or subject) in a - * simplified JSON format for display. - * - * @param attrs the attributes. - * - * @return the JSON for display. - */ -function _getAttributesAsJson(attrs) { - var rval = {}; - for(var i = 0; i < attrs.length; ++i) { - var attr = attrs[i]; - if(attr.shortName && ( - attr.valueTagClass === asn1.Type.UTF8 || - attr.valueTagClass === asn1.Type.PRINTABLESTRING || - attr.valueTagClass === asn1.Type.IA5STRING)) { - var value = attr.value; - if(attr.valueTagClass === asn1.Type.UTF8) { - value = forge.util.encodeUtf8(attr.value); - } - if(!(attr.shortName in rval)) { - rval[attr.shortName] = value; - } else if(forge.util.isArray(rval[attr.shortName])) { - rval[attr.shortName].push(value); - } else { - rval[attr.shortName] = [rval[attr.shortName], value]; - } - } - } - return rval; -} - -/** - * Fills in missing fields in attributes. - * - * @param attrs the attributes to fill missing fields in. - */ -function _fillMissingFields(attrs) { - var attr; - for(var i = 0; i < attrs.length; ++i) { - attr = attrs[i]; - - // populate missing name - if(typeof attr.name === 'undefined') { - if(attr.type && attr.type in pki.oids) { - attr.name = pki.oids[attr.type]; - } else if(attr.shortName && attr.shortName in _shortNames) { - attr.name = pki.oids[_shortNames[attr.shortName]]; - } - } - - // populate missing type (OID) - if(typeof attr.type === 'undefined') { - if(attr.name && attr.name in pki.oids) { - attr.type = pki.oids[attr.name]; - } else { - var error = new Error('Attribute type not specified.'); - error.attribute = attr; - throw error; - } - } - - // populate missing shortname - if(typeof attr.shortName === 'undefined') { - if(attr.name && attr.name in _shortNames) { - attr.shortName = _shortNames[attr.name]; - } - } - - // convert extensions to value - if(attr.type === oids.extensionRequest) { - attr.valueConstructed = true; - attr.valueTagClass = asn1.Type.SEQUENCE; - if(!attr.value && attr.extensions) { - attr.value = []; - for(var ei = 0; ei < attr.extensions.length; ++ei) { - attr.value.push(pki.certificateExtensionToAsn1( - _fillMissingExtensionFields(attr.extensions[ei]))); - } - } - } - - if(typeof attr.value === 'undefined') { - var error = new Error('Attribute value not specified.'); - error.attribute = attr; - throw error; - } - } -} - -/** - * Fills in missing fields in certificate extensions. - * - * @param e the extension. - * @param [options] the options to use. - * [cert] the certificate the extensions are for. - * - * @return the extension. - */ -function _fillMissingExtensionFields(e, options) { - options = options || {}; - - // populate missing name - if(typeof e.name === 'undefined') { - if(e.id && e.id in pki.oids) { - e.name = pki.oids[e.id]; - } - } - - // populate missing id - if(typeof e.id === 'undefined') { - if(e.name && e.name in pki.oids) { - e.id = pki.oids[e.name]; - } else { - var error = new Error('Extension ID not specified.'); - error.extension = e; - throw error; - } - } - - if(typeof e.value !== 'undefined') { - return e; - } - - // handle missing value: - - // value is a BIT STRING - if(e.name === 'keyUsage') { - // build flags - var unused = 0; - var b2 = 0x00; - var b3 = 0x00; - if(e.digitalSignature) { - b2 |= 0x80; - unused = 7; - } - if(e.nonRepudiation) { - b2 |= 0x40; - unused = 6; - } - if(e.keyEncipherment) { - b2 |= 0x20; - unused = 5; - } - if(e.dataEncipherment) { - b2 |= 0x10; - unused = 4; - } - if(e.keyAgreement) { - b2 |= 0x08; - unused = 3; - } - if(e.keyCertSign) { - b2 |= 0x04; - unused = 2; - } - if(e.cRLSign) { - b2 |= 0x02; - unused = 1; - } - if(e.encipherOnly) { - b2 |= 0x01; - unused = 0; - } - if(e.decipherOnly) { - b3 |= 0x80; - unused = 7; - } - - // create bit string - var value = String.fromCharCode(unused); - if(b3 !== 0) { - value += String.fromCharCode(b2) + String.fromCharCode(b3); - } else if(b2 !== 0) { - value += String.fromCharCode(b2); - } - e.value = asn1.create( - asn1.Class.UNIVERSAL, asn1.Type.BITSTRING, false, value); - } else if(e.name === 'basicConstraints') { - // basicConstraints is a SEQUENCE - e.value = asn1.create( - asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, []); - // cA BOOLEAN flag defaults to false - if(e.cA) { - e.value.value.push(asn1.create( - asn1.Class.UNIVERSAL, asn1.Type.BOOLEAN, false, - String.fromCharCode(0xFF))); - } - if('pathLenConstraint' in e) { - e.value.value.push(asn1.create( - asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false, - asn1.integerToDer(e.pathLenConstraint).getBytes())); - } - } else if(e.name === 'extKeyUsage') { - // extKeyUsage is a SEQUENCE of OIDs - e.value = asn1.create( - asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, []); - var seq = e.value.value; - for(var key in e) { - if(e[key] !== true) { - continue; - } - // key is name in OID map - if(key in oids) { - seq.push(asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, - false, asn1.oidToDer(oids[key]).getBytes())); - } else if(key.indexOf('.') !== -1) { - // assume key is an OID - seq.push(asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, - false, asn1.oidToDer(key).getBytes())); - } - } - } else if(e.name === 'nsCertType') { - // nsCertType is a BIT STRING - // build flags - var unused = 0; - var b2 = 0x00; - - if(e.client) { - b2 |= 0x80; - unused = 7; - } - if(e.server) { - b2 |= 0x40; - unused = 6; - } - if(e.email) { - b2 |= 0x20; - unused = 5; - } - if(e.objsign) { - b2 |= 0x10; - unused = 4; - } - if(e.reserved) { - b2 |= 0x08; - unused = 3; - } - if(e.sslCA) { - b2 |= 0x04; - unused = 2; - } - if(e.emailCA) { - b2 |= 0x02; - unused = 1; - } - if(e.objCA) { - b2 |= 0x01; - unused = 0; - } - - // create bit string - var value = String.fromCharCode(unused); - if(b2 !== 0) { - value += String.fromCharCode(b2); - } - e.value = asn1.create( - asn1.Class.UNIVERSAL, asn1.Type.BITSTRING, false, value); - } else if(e.name === 'subjectAltName' || e.name === 'issuerAltName') { - // SYNTAX SEQUENCE - e.value = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, []); - - var altName; - for(var n = 0; n < e.altNames.length; ++n) { - altName = e.altNames[n]; - var value = altName.value; - // handle IP - if(altName.type === 7 && altName.ip) { - value = forge.util.bytesFromIP(altName.ip); - if(value === null) { - var error = new Error( - 'Extension "ip" value is not a valid IPv4 or IPv6 address.'); - error.extension = e; - throw error; - } - } else if(altName.type === 8) { - // handle OID - if(altName.oid) { - value = asn1.oidToDer(asn1.oidToDer(altName.oid)); - } else { - // deprecated ... convert value to OID - value = asn1.oidToDer(value); - } - } - e.value.value.push(asn1.create( - asn1.Class.CONTEXT_SPECIFIC, altName.type, false, - value)); - } - } else if(e.name === 'subjectKeyIdentifier' && options.cert) { - var ski = options.cert.generateSubjectKeyIdentifier(); - e.subjectKeyIdentifier = ski.toHex(); - // OCTETSTRING w/digest - e.value = asn1.create( - asn1.Class.UNIVERSAL, asn1.Type.OCTETSTRING, false, ski.getBytes()); - } - - // ensure value has been defined by now - if(typeof e.value === 'undefined') { - var error = new Error('Extension value not specified.'); - error.extension = e; - throw error; - } - - return e; -} - -/** - * Convert signature parameters object to ASN.1 - * - * @param {String} oid Signature algorithm OID - * @param params The signature parametrs object - * @return ASN.1 object representing signature parameters - */ -function _signatureParametersToAsn1(oid, params) { - switch(oid) { - case oids['RSASSA-PSS']: - var parts = []; - - if(params.hash.algorithmOid !== undefined) { - parts.push(asn1.create(asn1.Class.CONTEXT_SPECIFIC, 0, true, [ - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [ - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, - asn1.oidToDer(params.hash.algorithmOid).getBytes()), - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.NULL, false, '') - ]) - ])); - } - - if(params.mgf.algorithmOid !== undefined) { - parts.push(asn1.create(asn1.Class.CONTEXT_SPECIFIC, 1, true, [ - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [ - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, - asn1.oidToDer(params.mgf.algorithmOid).getBytes()), - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [ - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, - asn1.oidToDer(params.mgf.hash.algorithmOid).getBytes()), - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.NULL, false, '') - ]) - ]) - ])); - } - - if(params.saltLength !== undefined) { - parts.push(asn1.create(asn1.Class.CONTEXT_SPECIFIC, 2, true, [ - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false, - asn1.integerToDer(params.saltLength).getBytes()) - ])); - } - - return asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, parts); - - default: - return asn1.create(asn1.Class.UNIVERSAL, asn1.Type.NULL, false, ''); - } -} - -/** - * Converts a certification request's attributes to an ASN.1 set of - * CRIAttributes. - * - * @param csr certification request. - * - * @return the ASN.1 set of CRIAttributes. - */ -function _CRIAttributesToAsn1(csr) { - // create an empty context-specific container - var rval = asn1.create(asn1.Class.CONTEXT_SPECIFIC, 0, true, []); - - // no attributes, return empty container - if(csr.attributes.length === 0) { - return rval; - } - - // each attribute has a sequence with a type and a set of values - var attrs = csr.attributes; - for(var i = 0; i < attrs.length; ++i) { - var attr = attrs[i]; - var value = attr.value; - - // reuse tag class for attribute value if available - var valueTagClass = asn1.Type.UTF8; - if('valueTagClass' in attr) { - valueTagClass = attr.valueTagClass; - } - if(valueTagClass === asn1.Type.UTF8) { - value = forge.util.encodeUtf8(value); - } - var valueConstructed = false; - if('valueConstructed' in attr) { - valueConstructed = attr.valueConstructed; - } - // FIXME: handle more encodings - - // create a RelativeDistinguishedName set - // each value in the set is an AttributeTypeAndValue first - // containing the type (an OID) and second the value - var seq = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [ - // AttributeType - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, - asn1.oidToDer(attr.type).getBytes()), - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SET, true, [ - // AttributeValue - asn1.create( - asn1.Class.UNIVERSAL, valueTagClass, valueConstructed, value) - ]) - ]); - rval.value.push(seq); - } - - return rval; -} - -/** - * Gets the ASN.1 TBSCertificate part of an X.509v3 certificate. - * - * @param cert the certificate. - * - * @return the asn1 TBSCertificate. - */ -pki.getTBSCertificate = function(cert) { - // TBSCertificate - var tbs = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [ - // version - asn1.create(asn1.Class.CONTEXT_SPECIFIC, 0, true, [ - // integer - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false, - asn1.integerToDer(cert.version).getBytes()) - ]), - // serialNumber - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false, - forge.util.hexToBytes(cert.serialNumber)), - // signature - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [ - // algorithm - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, - asn1.oidToDer(cert.siginfo.algorithmOid).getBytes()), - // parameters - _signatureParametersToAsn1( - cert.siginfo.algorithmOid, cert.siginfo.parameters) - ]), - // issuer - _dnToAsn1(cert.issuer), - // validity - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [ - // notBefore - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.UTCTIME, false, - asn1.dateToUtcTime(cert.validity.notBefore)), - // notAfter - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.UTCTIME, false, - asn1.dateToUtcTime(cert.validity.notAfter)) - ]), - // subject - _dnToAsn1(cert.subject), - // SubjectPublicKeyInfo - pki.publicKeyToAsn1(cert.publicKey) - ]); - - if(cert.issuer.uniqueId) { - // issuerUniqueID (optional) - tbs.value.push( - asn1.create(asn1.Class.CONTEXT_SPECIFIC, 1, true, [ - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.BITSTRING, false, - String.fromCharCode(0x00) + - cert.issuer.uniqueId - ) - ]) - ); - } - if(cert.subject.uniqueId) { - // subjectUniqueID (optional) - tbs.value.push( - asn1.create(asn1.Class.CONTEXT_SPECIFIC, 2, true, [ - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.BITSTRING, false, - String.fromCharCode(0x00) + - cert.subject.uniqueId - ) - ]) - ); - } - - if(cert.extensions.length > 0) { - // extensions (optional) - tbs.value.push(pki.certificateExtensionsToAsn1(cert.extensions)); - } - - return tbs; -}; - -/** - * Gets the ASN.1 CertificationRequestInfo part of a - * PKCS#10 CertificationRequest. - * - * @param csr the certification request. - * - * @return the asn1 CertificationRequestInfo. - */ -pki.getCertificationRequestInfo = function(csr) { - // CertificationRequestInfo - var cri = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [ - // version - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false, - asn1.integerToDer(csr.version).getBytes()), - // subject - _dnToAsn1(csr.subject), - // SubjectPublicKeyInfo - pki.publicKeyToAsn1(csr.publicKey), - // attributes - _CRIAttributesToAsn1(csr) - ]); - - return cri; -}; - -/** - * Converts a DistinguishedName (subject or issuer) to an ASN.1 object. - * - * @param dn the DistinguishedName. - * - * @return the asn1 representation of a DistinguishedName. - */ -pki.distinguishedNameToAsn1 = function(dn) { - return _dnToAsn1(dn); -}; - -/** - * Converts an X.509v3 RSA certificate to an ASN.1 object. - * - * @param cert the certificate. - * - * @return the asn1 representation of an X.509v3 RSA certificate. - */ -pki.certificateToAsn1 = function(cert) { - // prefer cached TBSCertificate over generating one - var tbsCertificate = cert.tbsCertificate || pki.getTBSCertificate(cert); - - // Certificate - return asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [ - // TBSCertificate - tbsCertificate, - // AlgorithmIdentifier (signature algorithm) - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [ - // algorithm - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, - asn1.oidToDer(cert.signatureOid).getBytes()), - // parameters - _signatureParametersToAsn1(cert.signatureOid, cert.signatureParameters) - ]), - // SignatureValue - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.BITSTRING, false, - String.fromCharCode(0x00) + cert.signature) - ]); -}; - -/** - * Converts X.509v3 certificate extensions to ASN.1. - * - * @param exts the extensions to convert. - * - * @return the extensions in ASN.1 format. - */ -pki.certificateExtensionsToAsn1 = function(exts) { - // create top-level extension container - var rval = asn1.create(asn1.Class.CONTEXT_SPECIFIC, 3, true, []); - - // create extension sequence (stores a sequence for each extension) - var seq = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, []); - rval.value.push(seq); - - for(var i = 0; i < exts.length; ++i) { - seq.value.push(pki.certificateExtensionToAsn1(exts[i])); - } - - return rval; -}; - -/** - * Converts a single certificate extension to ASN.1. - * - * @param ext the extension to convert. - * - * @return the extension in ASN.1 format. - */ -pki.certificateExtensionToAsn1 = function(ext) { - // create a sequence for each extension - var extseq = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, []); - - // extnID (OID) - extseq.value.push(asn1.create( - asn1.Class.UNIVERSAL, asn1.Type.OID, false, - asn1.oidToDer(ext.id).getBytes())); - - // critical defaults to false - if(ext.critical) { - // critical BOOLEAN DEFAULT FALSE - extseq.value.push(asn1.create( - asn1.Class.UNIVERSAL, asn1.Type.BOOLEAN, false, - String.fromCharCode(0xFF))); - } - - var value = ext.value; - if(typeof ext.value !== 'string') { - // value is asn.1 - value = asn1.toDer(value).getBytes(); - } - - // extnValue (OCTET STRING) - extseq.value.push(asn1.create( - asn1.Class.UNIVERSAL, asn1.Type.OCTETSTRING, false, value)); - - return extseq; -}; - -/** - * Converts a PKCS#10 certification request to an ASN.1 object. - * - * @param csr the certification request. - * - * @return the asn1 representation of a certification request. - */ -pki.certificationRequestToAsn1 = function(csr) { - // prefer cached CertificationRequestInfo over generating one - var cri = csr.certificationRequestInfo || - pki.getCertificationRequestInfo(csr); - - // Certificate - return asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [ - // CertificationRequestInfo - cri, - // AlgorithmIdentifier (signature algorithm) - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [ - // algorithm - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, - asn1.oidToDer(csr.signatureOid).getBytes()), - // parameters - _signatureParametersToAsn1(csr.signatureOid, csr.signatureParameters) - ]), - // signature - asn1.create(asn1.Class.UNIVERSAL, asn1.Type.BITSTRING, false, - String.fromCharCode(0x00) + csr.signature) - ]); -}; - -/** - * Creates a CA store. - * - * @param certs an optional array of certificate objects or PEM-formatted - * certificate strings to add to the CA store. - * - * @return the CA store. - */ -pki.createCaStore = function(certs) { - // create CA store - var caStore = { - // stored certificates - certs: {} - }; - - /** - * Gets the certificate that issued the passed certificate or its - * 'parent'. - * - * @param cert the certificate to get the parent for. - * - * @return the parent certificate or null if none was found. - */ - caStore.getIssuer = function(cert) { - var rval = getBySubject(cert.issuer); - - // see if there are multiple matches - /*if(forge.util.isArray(rval)) { - // TODO: resolve multiple matches by checking - // authorityKey/subjectKey/issuerUniqueID/other identifiers, etc. - // FIXME: or alternatively do authority key mapping - // if possible (X.509v1 certs can't work?) - throw new Error('Resolving multiple issuer matches not implemented yet.'); - }*/ - - return rval; - }; - - /** - * Adds a trusted certificate to the store. - * - * @param cert the certificate to add as a trusted certificate (either a - * pki.certificate object or a PEM-formatted certificate). - */ - caStore.addCertificate = function(cert) { - // convert from pem if necessary - if(typeof cert === 'string') { - cert = forge.pki.certificateFromPem(cert); - } - - // produce subject hash if it doesn't exist - if(!cert.subject.hash) { - var md = forge.md.sha1.create(); - cert.subject.attributes = pki.RDNAttributesAsArray( - _dnToAsn1(cert.subject), md); - cert.subject.hash = md.digest().toHex(); - } - - if(cert.subject.hash in caStore.certs) { - // subject hash already exists, append to array - var tmp = caStore.certs[cert.subject.hash]; - if(!forge.util.isArray(tmp)) { - tmp = [tmp]; - } - tmp.push(cert); - } else { - caStore.certs[cert.subject.hash] = cert; - } - }; - - /** - * Checks to see if the given certificate is in the store. - * - * @param cert the certificate to check. - * - * @return true if the certificate is in the store, false if not. - */ - caStore.hasCertificate = function(cert) { - var match = getBySubject(cert.subject); - if(!match) { - return false; - } - if(!forge.util.isArray(match)) { - match = [match]; - } - // compare DER-encoding of certificates - var der1 = asn1.toDer(pki.certificateToAsn1(cert)).getBytes(); - for(var i = 0; i < match.length; ++i) { - var der2 = asn1.toDer(pki.certificateToAsn1(match[i])).getBytes(); - if(der1 === der2) { - return true; - } - } - return false; - }; - - function getBySubject(subject) { - // produce subject hash if it doesn't exist - if(!subject.hash) { - var md = forge.md.sha1.create(); - subject.attributes = pki.RDNAttributesAsArray(_dnToAsn1(subject), md); - subject.hash = md.digest().toHex(); - } - return caStore.certs[subject.hash] || null; - } - - // auto-add passed in certs - if(certs) { - // parse PEM-formatted certificates as necessary - for(var i = 0; i < certs.length; ++i) { - var cert = certs[i]; - caStore.addCertificate(cert); - } - } - - return caStore; -}; - -/** - * Certificate verification errors, based on TLS. - */ -pki.certificateError = { - bad_certificate: 'forge.pki.BadCertificate', - unsupported_certificate: 'forge.pki.UnsupportedCertificate', - certificate_revoked: 'forge.pki.CertificateRevoked', - certificate_expired: 'forge.pki.CertificateExpired', - certificate_unknown: 'forge.pki.CertificateUnknown', - unknown_ca: 'forge.pki.UnknownCertificateAuthority' -}; - -/** - * Verifies a certificate chain against the given Certificate Authority store - * with an optional custom verify callback. - * - * @param caStore a certificate store to verify against. - * @param chain the certificate chain to verify, with the root or highest - * authority at the end (an array of certificates). - * @param verify called for every certificate in the chain. - * - * The verify callback has the following signature: - * - * verified - Set to true if certificate was verified, otherwise the - * pki.certificateError for why the certificate failed. - * depth - The current index in the chain, where 0 is the end point's cert. - * certs - The certificate chain, *NOTE* an empty chain indicates an anonymous - * end point. - * - * The function returns true on success and on failure either the appropriate - * pki.certificateError or an object with 'error' set to the appropriate - * pki.certificateError and 'message' set to a custom error message. - * - * @return true if successful, error thrown if not. - */ -pki.verifyCertificateChain = function(caStore, chain, verify) { - /* From: RFC3280 - Internet X.509 Public Key Infrastructure Certificate - Section 6: Certification Path Validation - See inline parentheticals related to this particular implementation. - - The primary goal of path validation is to verify the binding between - a subject distinguished name or a subject alternative name and subject - public key, as represented in the end entity certificate, based on the - public key of the trust anchor. This requires obtaining a sequence of - certificates that support that binding. That sequence should be provided - in the passed 'chain'. The trust anchor should be in the given CA - store. The 'end entity' certificate is the certificate provided by the - end point (typically a server) and is the first in the chain. - - To meet this goal, the path validation process verifies, among other - things, that a prospective certification path (a sequence of n - certificates or a 'chain') satisfies the following conditions: - - (a) for all x in {1, ..., n-1}, the subject of certificate x is - the issuer of certificate x+1; - - (b) certificate 1 is issued by the trust anchor; - - (c) certificate n is the certificate to be validated; and - - (d) for all x in {1, ..., n}, the certificate was valid at the - time in question. - - Note that here 'n' is index 0 in the chain and 1 is the last certificate - in the chain and it must be signed by a certificate in the connection's - CA store. - - The path validation process also determines the set of certificate - policies that are valid for this path, based on the certificate policies - extension, policy mapping extension, policy constraints extension, and - inhibit any-policy extension. - - Note: Policy mapping extension not supported (Not Required). - - Note: If the certificate has an unsupported critical extension, then it - must be rejected. - - Note: A certificate is self-issued if the DNs that appear in the subject - and issuer fields are identical and are not empty. - - The path validation algorithm assumes the following seven inputs are - provided to the path processing logic. What this specific implementation - will use is provided parenthetically: - - (a) a prospective certification path of length n (the 'chain') - (b) the current date/time: ('now'). - (c) user-initial-policy-set: A set of certificate policy identifiers - naming the policies that are acceptable to the certificate user. - The user-initial-policy-set contains the special value any-policy - if the user is not concerned about certificate policy - (Not implemented. Any policy is accepted). - (d) trust anchor information, describing a CA that serves as a trust - anchor for the certification path. The trust anchor information - includes: - - (1) the trusted issuer name, - (2) the trusted public key algorithm, - (3) the trusted public key, and - (4) optionally, the trusted public key parameters associated - with the public key. - - (Trust anchors are provided via certificates in the CA store). - - The trust anchor information may be provided to the path processing - procedure in the form of a self-signed certificate. The trusted anchor - information is trusted because it was delivered to the path processing - procedure by some trustworthy out-of-band procedure. If the trusted - public key algorithm requires parameters, then the parameters are - provided along with the trusted public key (No parameters used in this - implementation). - - (e) initial-policy-mapping-inhibit, which indicates if policy mapping is - allowed in the certification path. - (Not implemented, no policy checking) - - (f) initial-explicit-policy, which indicates if the path must be valid - for at least one of the certificate policies in the user-initial- - policy-set. - (Not implemented, no policy checking) - - (g) initial-any-policy-inhibit, which indicates whether the - anyPolicy OID should be processed if it is included in a - certificate. - (Not implemented, so any policy is valid provided that it is - not marked as critical) */ - - /* Basic Path Processing: - - For each certificate in the 'chain', the following is checked: - - 1. The certificate validity period includes the current time. - 2. The certificate was signed by its parent (where the parent is either - the next in the chain or from the CA store). Allow processing to - continue to the next step if no parent is found but the certificate is - in the CA store. - 3. TODO: The certificate has not been revoked. - 4. The certificate issuer name matches the parent's subject name. - 5. TODO: If the certificate is self-issued and not the final certificate - in the chain, skip this step, otherwise verify that the subject name - is within one of the permitted subtrees of X.500 distinguished names - and that each of the alternative names in the subjectAltName extension - (critical or non-critical) is within one of the permitted subtrees for - that name type. - 6. TODO: If the certificate is self-issued and not the final certificate - in the chain, skip this step, otherwise verify that the subject name - is not within one of the excluded subtrees for X.500 distinguished - names and none of the subjectAltName extension names are excluded for - that name type. - 7. The other steps in the algorithm for basic path processing involve - handling the policy extension which is not presently supported in this - implementation. Instead, if a critical policy extension is found, the - certificate is rejected as not supported. - 8. If the certificate is not the first or if its the only certificate in - the chain (having no parent from the CA store or is self-signed) and it - has a critical key usage extension, verify that the keyCertSign bit is - set. If the key usage extension exists, verify that the basic - constraints extension exists. If the basic constraints extension exists, - verify that the cA flag is set. If pathLenConstraint is set, ensure that - the number of certificates that precede in the chain (come earlier - in the chain as implemented below), excluding the very first in the - chain (typically the end-entity one), isn't greater than the - pathLenConstraint. This constraint limits the number of intermediate - CAs that may appear below a CA before only end-entity certificates - may be issued. */ - - // copy cert chain references to another array to protect against changes - // in verify callback - chain = chain.slice(0); - var certs = chain.slice(0); - - // get current date - var now = new Date(); - - // verify each cert in the chain using its parent, where the parent - // is either the next in the chain or from the CA store - var first = true; - var error = null; - var depth = 0; - do { - var cert = chain.shift(); - var parent = null; - var selfSigned = false; - - // 1. check valid time - if(now < cert.validity.notBefore || now > cert.validity.notAfter) { - error = { - message: 'Certificate is not valid yet or has expired.', - error: pki.certificateError.certificate_expired, - notBefore: cert.validity.notBefore, - notAfter: cert.validity.notAfter, - now: now - }; - } - - // 2. verify with parent from chain or CA store - if(error === null) { - parent = chain[0] || caStore.getIssuer(cert); - if(parent === null) { - // check for self-signed cert - if(cert.isIssuer(cert)) { - selfSigned = true; - parent = cert; - } - } - - if(parent) { - // FIXME: current CA store implementation might have multiple - // certificates where the issuer can't be determined from the - // certificate (happens rarely with, eg: old certificates) so normalize - // by always putting parents into an array - // TODO: there's may be an extreme degenerate case currently uncovered - // where an old intermediate certificate seems to have a matching parent - // but none of the parents actually verify ... but the intermediate - // is in the CA and it should pass this check; needs investigation - var parents = parent; - if(!forge.util.isArray(parents)) { - parents = [parents]; - } - - // try to verify with each possible parent (typically only one) - var verified = false; - while(!verified && parents.length > 0) { - parent = parents.shift(); - try { - verified = parent.verify(cert); - } catch(ex) { - // failure to verify, don't care why, try next one - } - } - - if(!verified) { - error = { - message: 'Certificate signature is invalid.', - error: pki.certificateError.bad_certificate - }; - } - } - - if(error === null && (!parent || selfSigned) && - !caStore.hasCertificate(cert)) { - // no parent issuer and certificate itself is not trusted - error = { - message: 'Certificate is not trusted.', - error: pki.certificateError.unknown_ca - }; - } - } - - // TODO: 3. check revoked - - // 4. check for matching issuer/subject - if(error === null && parent && !cert.isIssuer(parent)) { - // parent is not issuer - error = { - message: 'Certificate issuer is invalid.', - error: pki.certificateError.bad_certificate - }; - } - - // 5. TODO: check names with permitted names tree - - // 6. TODO: check names against excluded names tree - - // 7. check for unsupported critical extensions - if(error === null) { - // supported extensions - var se = { - keyUsage: true, - basicConstraints: true - }; - for(var i = 0; error === null && i < cert.extensions.length; ++i) { - var ext = cert.extensions[i]; - if(ext.critical && !(ext.name in se)) { - error = { - message: - 'Certificate has an unsupported critical extension.', - error: pki.certificateError.unsupported_certificate - }; - } - } - } - - // 8. check for CA if cert is not first or is the only certificate - // remaining in chain with no parent or is self-signed - if(error === null && - (!first || (chain.length === 0 && (!parent || selfSigned)))) { - // first check keyUsage extension and then basic constraints - var bcExt = cert.getExtension('basicConstraints'); - var keyUsageExt = cert.getExtension('keyUsage'); - if(keyUsageExt !== null) { - // keyCertSign must be true and there must be a basic - // constraints extension - if(!keyUsageExt.keyCertSign || bcExt === null) { - // bad certificate - error = { - message: - 'Certificate keyUsage or basicConstraints conflict ' + - 'or indicate that the certificate is not a CA. ' + - 'If the certificate is the only one in the chain or ' + - 'isn\'t the first then the certificate must be a ' + - 'valid CA.', - error: pki.certificateError.bad_certificate - }; - } - } - // basic constraints cA flag must be set - if(error === null && bcExt !== null && !bcExt.cA) { - // bad certificate - error = { - message: - 'Certificate basicConstraints indicates the certificate ' + - 'is not a CA.', - error: pki.certificateError.bad_certificate - }; - } - // if error is not null and keyUsage is available, then we know it - // has keyCertSign and there is a basic constraints extension too, - // which means we can check pathLenConstraint (if it exists) - if(error === null && keyUsageExt !== null && - 'pathLenConstraint' in bcExt) { - // pathLen is the maximum # of intermediate CA certs that can be - // found between the current certificate and the end-entity (depth 0) - // certificate; this number does not include the end-entity (depth 0, - // last in the chain) even if it happens to be a CA certificate itself - var pathLen = depth - 1; - if(pathLen > bcExt.pathLenConstraint) { - // pathLenConstraint violated, bad certificate - error = { - message: - 'Certificate basicConstraints pathLenConstraint violated.', - error: pki.certificateError.bad_certificate - }; - } - } - } - - // call application callback - var vfd = (error === null) ? true : error.error; - var ret = verify ? verify(vfd, depth, certs) : vfd; - if(ret === true) { - // clear any set error - error = null; - } else { - // if passed basic tests, set default message and alert - if(vfd === true) { - error = { - message: 'The application rejected the certificate.', - error: pki.certificateError.bad_certificate - }; - } - - // check for custom error info - if(ret || ret === 0) { - // set custom message and error - if(typeof ret === 'object' && !forge.util.isArray(ret)) { - if(ret.message) { - error.message = ret.message; - } - if(ret.error) { - error.error = ret.error; - } - } else if(typeof ret === 'string') { - // set custom error - error.error = ret; - } - } - - // throw error - throw error; - } - - // no longer first cert in chain - first = false; - ++depth; - } while(chain.length > 0); - - return true; -}; - -} // end module implementation - -/* ########## Begin module wrapper ########## */ -var name = 'x509'; -if(typeof define !== 'function') { - // NodeJS -> AMD - if(typeof module === 'object' && module.exports) { - var nodeJS = true; - define = function(ids, factory) { - factory(require, module); - }; - } else { - // <script> - if(typeof forge === 'undefined') { - forge = {}; - } - return initModule(forge); - } -} -// AMD -var deps; -var defineFunc = function(require, module) { - module.exports = function(forge) { - var mods = deps.map(function(dep) { - return require(dep); - }).concat(initModule); - // handle circular dependencies - forge = forge || {}; - forge.defined = forge.defined || {}; - if(forge.defined[name]) { - return forge[name]; - } - forge.defined[name] = true; - for(var i = 0; i < mods.length; ++i) { - mods[i](forge); - } - return forge.pki; - }; -}; -var tmpDefine = define; -define = function(ids, factory) { - deps = (typeof ids === 'string') ? factory.slice(2) : ids.slice(2); - if(nodeJS) { - delete define; - return tmpDefine.apply(null, Array.prototype.slice.call(arguments, 0)); - } - define = tmpDefine; - return define.apply(null, Array.prototype.slice.call(arguments, 0)); -}; -define([ - 'require', - 'module', - './aes', - './asn1', - './des', - './md', - './mgf', - './oids', - './pem', - './pss', - './rsa', - './util' -], function() { - defineFunc.apply(null, Array.prototype.slice.call(arguments, 0)); -}); -})(); diff --git a/alarm/node_modules/node-forge/js/xhr.js b/alarm/node_modules/node-forge/js/xhr.js deleted file mode 100644 index 96082ad..0000000 --- a/alarm/node_modules/node-forge/js/xhr.js +++ /dev/null @@ -1,739 +0,0 @@ -/** - * XmlHttpRequest implementation that uses TLS and flash SocketPool. - * - * @author Dave Longley - * - * Copyright (c) 2010-2013 Digital Bazaar, Inc. - */ -(function($) { - -// logging category -var cat = 'forge.xhr'; - -/* -XMLHttpRequest interface definition from: -http://www.w3.org/TR/XMLHttpRequest - -interface XMLHttpRequest { - // event handler - attribute EventListener onreadystatechange; - - // state - const unsigned short UNSENT = 0; - const unsigned short OPENED = 1; - const unsigned short HEADERS_RECEIVED = 2; - const unsigned short LOADING = 3; - const unsigned short DONE = 4; - readonly attribute unsigned short readyState; - - // request - void open(in DOMString method, in DOMString url); - void open(in DOMString method, in DOMString url, in boolean async); - void open(in DOMString method, in DOMString url, - in boolean async, in DOMString user); - void open(in DOMString method, in DOMString url, - in boolean async, in DOMString user, in DOMString password); - void setRequestHeader(in DOMString header, in DOMString value); - void send(); - void send(in DOMString data); - void send(in Document data); - void abort(); - - // response - DOMString getAllResponseHeaders(); - DOMString getResponseHeader(in DOMString header); - readonly attribute DOMString responseText; - readonly attribute Document responseXML; - readonly attribute unsigned short status; - readonly attribute DOMString statusText; -}; -*/ - -// readyStates -var UNSENT = 0; -var OPENED = 1; -var HEADERS_RECEIVED = 2; -var LOADING = 3; -var DONE = 4; - -// exceptions -var INVALID_STATE_ERR = 11; -var SYNTAX_ERR = 12; -var SECURITY_ERR = 18; -var NETWORK_ERR = 19; -var ABORT_ERR = 20; - -// private flash socket pool vars -var _sp = null; -var _policyPort = 0; -var _policyUrl = null; - -// default client (used if no special URL provided when creating an XHR) -var _client = null; - -// all clients including the default, key'd by full base url -// (multiple cross-domain http clients are permitted so there may be more -// than one client in this map) -// TODO: provide optional clean up API for non-default clients -var _clients = {}; - -// the default maximum number of concurrents connections per client -var _maxConnections = 10; - -// local aliases -if(typeof forge === 'undefined') { - forge = {}; -} -var net = forge.net; -var http = forge.http; - -// define the xhr interface -var xhrApi = {}; - -/** - * Initializes flash XHR support. - * - * @param options: - * url: the default base URL to connect to if xhr URLs are relative, - * ie: https://myserver.com. - * flashId: the dom ID of the flash SocketPool. - * policyPort: the port that provides the server's flash policy, 0 to use - * the flash default. - * policyUrl: the policy file URL to use instead of a policy port. - * msie: true if browser is internet explorer, false if not. - * connections: the maximum number of concurrent connections. - * caCerts: a list of PEM-formatted certificates to trust. - * cipherSuites: an optional array of cipher suites to use, - * see forge.tls.CipherSuites. - * verify: optional TLS certificate verify callback to use (see forge.tls - * for details). - * getCertificate: an optional callback used to get a client-side - * certificate (see forge.tls for details). - * getPrivateKey: an optional callback used to get a client-side private - * key (see forge.tls for details). - * getSignature: an optional callback used to get a client-side signature - * (see forge.tls for details). - * persistCookies: true to use persistent cookies via flash local storage, - * false to only keep cookies in javascript. - * primeTlsSockets: true to immediately connect TLS sockets on their - * creation so that they will cache TLS sessions for reuse. - */ -xhrApi.init = function(options) { - forge.log.debug(cat, 'initializing', options); - - // update default policy port and max connections - _policyPort = options.policyPort || _policyPort; - _policyUrl = options.policyUrl || _policyUrl; - _maxConnections = options.connections || _maxConnections; - - // create the flash socket pool - _sp = net.createSocketPool({ - flashId: options.flashId, - policyPort: _policyPort, - policyUrl: _policyUrl, - msie: options.msie || false - }); - - // create default http client - _client = http.createClient({ - url: options.url || ( - window.location.protocol + '//' + window.location.host), - socketPool: _sp, - policyPort: _policyPort, - policyUrl: _policyUrl, - connections: options.connections || _maxConnections, - caCerts: options.caCerts, - cipherSuites: options.cipherSuites, - persistCookies: options.persistCookies || true, - primeTlsSockets: options.primeTlsSockets || false, - verify: options.verify, - getCertificate: options.getCertificate, - getPrivateKey: options.getPrivateKey, - getSignature: options.getSignature - }); - _clients[_client.url.full] = _client; - - forge.log.debug(cat, 'ready'); -}; - -/** - * Called to clean up the clients and socket pool. - */ -xhrApi.cleanup = function() { - // destroy all clients - for(var key in _clients) { - _clients[key].destroy(); - } - _clients = {}; - _client = null; - - // destroy socket pool - _sp.destroy(); - _sp = null; -}; - -/** - * Sets a cookie. - * - * @param cookie the cookie with parameters: - * name: the name of the cookie. - * value: the value of the cookie. - * comment: an optional comment string. - * maxAge: the age of the cookie in seconds relative to created time. - * secure: true if the cookie must be sent over a secure protocol. - * httpOnly: true to restrict access to the cookie from javascript - * (inaffective since the cookies are stored in javascript). - * path: the path for the cookie. - * domain: optional domain the cookie belongs to (must start with dot). - * version: optional version of the cookie. - * created: creation time, in UTC seconds, of the cookie. - */ -xhrApi.setCookie = function(cookie) { - // default cookie expiration to never - cookie.maxAge = cookie.maxAge || -1; - - // if the cookie's domain is set, use the appropriate client - if(cookie.domain) { - // add the cookies to the applicable domains - for(var key in _clients) { - var client = _clients[key]; - if(http.withinCookieDomain(client.url, cookie) && - client.secure === cookie.secure) { - client.setCookie(cookie); - } - } - } else { - // use the default domain - // FIXME: should a null domain cookie be added to all clients? should - // this be an option? - _client.setCookie(cookie); - } -}; - -/** - * Gets a cookie. - * - * @param name the name of the cookie. - * @param path an optional path for the cookie (if there are multiple cookies - * with the same name but different paths). - * @param domain an optional domain for the cookie (if not using the default - * domain). - * - * @return the cookie, cookies (if multiple matches), or null if not found. - */ -xhrApi.getCookie = function(name, path, domain) { - var rval = null; - - if(domain) { - // get the cookies from the applicable domains - for(var key in _clients) { - var client = _clients[key]; - if(http.withinCookieDomain(client.url, domain)) { - var cookie = client.getCookie(name, path); - if(cookie !== null) { - if(rval === null) { - rval = cookie; - } else if(!forge.util.isArray(rval)) { - rval = [rval, cookie]; - } else { - rval.push(cookie); - } - } - } - } - } else { - // get cookie from default domain - rval = _client.getCookie(name, path); - } - - return rval; -}; - -/** - * Removes a cookie. - * - * @param name the name of the cookie. - * @param path an optional path for the cookie (if there are multiple cookies - * with the same name but different paths). - * @param domain an optional domain for the cookie (if not using the default - * domain). - * - * @return true if a cookie was removed, false if not. - */ -xhrApi.removeCookie = function(name, path, domain) { - var rval = false; - - if(domain) { - // remove the cookies from the applicable domains - for(var key in _clients) { - var client = _clients[key]; - if(http.withinCookieDomain(client.url, domain)) { - if(client.removeCookie(name, path)) { - rval = true; - } - } - } - } else { - // remove cookie from default domain - rval = _client.removeCookie(name, path); - } - - return rval; -}; - -/** - * Creates a new XmlHttpRequest. By default the base URL, flash policy port, - * etc, will be used. However, an XHR can be created to point at another - * cross-domain URL. - * - * @param options: - * logWarningOnError: If true and an HTTP error status code is received then - * log a warning, otherwise log a verbose message. - * verbose: If true be very verbose in the output including the response - * event and response body, otherwise only include status, timing, and - * data size. - * logError: a multi-var log function for warnings that takes the log - * category as the first var. - * logWarning: a multi-var log function for warnings that takes the log - * category as the first var. - * logDebug: a multi-var log function for warnings that takes the log - * category as the first var. - * logVerbose: a multi-var log function for warnings that takes the log - * category as the first var. - * url: the default base URL to connect to if xhr URLs are relative, - * eg: https://myserver.com, and note that the following options will be - * ignored if the URL is absent or the same as the default base URL. - * policyPort: the port that provides the server's flash policy, 0 to use - * the flash default. - * policyUrl: the policy file URL to use instead of a policy port. - * connections: the maximum number of concurrent connections. - * caCerts: a list of PEM-formatted certificates to trust. - * cipherSuites: an optional array of cipher suites to use, see - * forge.tls.CipherSuites. - * verify: optional TLS certificate verify callback to use (see forge.tls - * for details). - * getCertificate: an optional callback used to get a client-side - * certificate. - * getPrivateKey: an optional callback used to get a client-side private key. - * getSignature: an optional callback used to get a client-side signature. - * persistCookies: true to use persistent cookies via flash local storage, - * false to only keep cookies in javascript. - * primeTlsSockets: true to immediately connect TLS sockets on their - * creation so that they will cache TLS sessions for reuse. - * - * @return the XmlHttpRequest. - */ -xhrApi.create = function(options) { - // set option defaults - options = $.extend({ - logWarningOnError: true, - verbose: false, - logError: function(){}, - logWarning: function(){}, - logDebug: function(){}, - logVerbose: function(){}, - url: null - }, options || {}); - - // private xhr state - var _state = { - // the http client to use - client: null, - // request storage - request: null, - // response storage - response: null, - // asynchronous, true if doing asynchronous communication - asynchronous: true, - // sendFlag, true if send has been called - sendFlag: false, - // errorFlag, true if a network error occurred - errorFlag: false - }; - - // private log functions - var _log = { - error: options.logError || forge.log.error, - warning: options.logWarning || forge.log.warning, - debug: options.logDebug || forge.log.debug, - verbose: options.logVerbose || forge.log.verbose - }; - - // create public xhr interface - var xhr = { - // an EventListener - onreadystatechange: null, - // readonly, the current readyState - readyState: UNSENT, - // a string with the response entity-body - responseText: '', - // a Document for response entity-bodies that are XML - responseXML: null, - // readonly, returns the HTTP status code (i.e. 404) - status: 0, - // readonly, returns the HTTP status message (i.e. 'Not Found') - statusText: '' - }; - - // determine which http client to use - if(options.url === null) { - // use default - _state.client = _client; - } else { - var url = http.parseUrl(options.url); - if(!url) { - var error = new Error('Invalid url.'); - error.details = { - url: options.url - }; - } - - // find client - if(url.full in _clients) { - // client found - _state.client = _clients[url.full]; - } else { - // create client - _state.client = http.createClient({ - url: options.url, - socketPool: _sp, - policyPort: options.policyPort || _policyPort, - policyUrl: options.policyUrl || _policyUrl, - connections: options.connections || _maxConnections, - caCerts: options.caCerts, - cipherSuites: options.cipherSuites, - persistCookies: options.persistCookies || true, - primeTlsSockets: options.primeTlsSockets || false, - verify: options.verify, - getCertificate: options.getCertificate, - getPrivateKey: options.getPrivateKey, - getSignature: options.getSignature - }); - _clients[url.full] = _state.client; - } - } - - /** - * Opens the request. This method will create the HTTP request to send. - * - * @param method the HTTP method (i.e. 'GET'). - * @param url the relative url (the HTTP request path). - * @param async always true, ignored. - * @param user always null, ignored. - * @param password always null, ignored. - */ - xhr.open = function(method, url, async, user, password) { - // 1. validate Document if one is associated - // TODO: not implemented (not used yet) - - // 2. validate method token - // 3. change method to uppercase if it matches a known - // method (here we just require it to be uppercase, and - // we do not allow the standard methods) - // 4. disallow CONNECT, TRACE, or TRACK with a security error - switch(method) { - case 'DELETE': - case 'GET': - case 'HEAD': - case 'OPTIONS': - case 'PATCH': - case 'POST': - case 'PUT': - // valid method - break; - case 'CONNECT': - case 'TRACE': - case 'TRACK': - throw new Error('CONNECT, TRACE and TRACK methods are disallowed'); - default: - throw new Error('Invalid method: ' + method);; - } - - // TODO: other validation steps in algorithm are not implemented - - // 19. set send flag to false - // set response body to null - // empty list of request headers - // set request method to given method - // set request URL - // set username, password - // set asychronous flag - _state.sendFlag = false; - xhr.responseText = ''; - xhr.responseXML = null; - - // custom: reset status and statusText - xhr.status = 0; - xhr.statusText = ''; - - // create the HTTP request - _state.request = http.createRequest({ - method: method, - path: url - }); - - // 20. set state to OPENED - xhr.readyState = OPENED; - - // 21. dispatch onreadystatechange - if(xhr.onreadystatechange) { - xhr.onreadystatechange(); - } - }; - - /** - * Adds an HTTP header field to the request. - * - * @param header the name of the header field. - * @param value the value of the header field. - */ - xhr.setRequestHeader = function(header, value) { - // 1. if state is not OPENED or send flag is true, raise exception - if(xhr.readyState != OPENED || _state.sendFlag) { - throw new Error('XHR not open or sending'); - } - - // TODO: other validation steps in spec aren't implemented - - // set header - _state.request.setField(header, value); - }; - - /** - * Sends the request and any associated data. - * - * @param data a string or Document object to send, null to send no data. - */ - xhr.send = function(data) { - // 1. if state is not OPENED or 2. send flag is true, raise - // an invalid state exception - if(xhr.readyState != OPENED || _state.sendFlag) { - throw new Error('XHR not open or sending'); - } - - // 3. ignore data if method is GET or HEAD - if(data && - _state.request.method !== 'GET' && - _state.request.method !== 'HEAD') { - // handle non-IE case - if(typeof(XMLSerializer) !== 'undefined') { - if(data instanceof Document) { - var xs = new XMLSerializer(); - _state.request.body = xs.serializeToString(data); - } else { - _state.request.body = data; - } - } else { - // poorly implemented IE case - if(typeof(data.xml) !== 'undefined') { - _state.request.body = data.xml; - } else { - _state.request.body = data; - } - } - } - - // 4. release storage mutex (not used) - - // 5. set error flag to false - _state.errorFlag = false; - - // 6. if asynchronous is true (must be in this implementation) - - // 6.1 set send flag to true - _state.sendFlag = true; - - // 6.2 dispatch onreadystatechange - if(xhr.onreadystatechange) { - xhr.onreadystatechange(); - } - - // create send options - var options = {}; - options.request = _state.request; - options.headerReady = function(e) { - // make cookies available for ease of use/iteration - xhr.cookies = _state.client.cookies; - - // TODO: update document.cookie with any cookies where the - // script's domain matches - - // headers received - xhr.readyState = HEADERS_RECEIVED; - xhr.status = e.response.code; - xhr.statusText = e.response.message; - _state.response = e.response; - if(xhr.onreadystatechange) { - xhr.onreadystatechange(); - } - if(!_state.response.aborted) { - // now loading body - xhr.readyState = LOADING; - if(xhr.onreadystatechange) { - xhr.onreadystatechange(); - } - } - }; - options.bodyReady = function(e) { - xhr.readyState = DONE; - var ct = e.response.getField('Content-Type'); - // Note: this null/undefined check is done outside because IE - // dies otherwise on a "'null' is null" error - if(ct) { - if(ct.indexOf('text/xml') === 0 || - ct.indexOf('application/xml') === 0 || - ct.indexOf('+xml') !== -1) { - try { - var doc = new ActiveXObject('MicrosoftXMLDOM'); - doc.async = false; - doc.loadXML(e.response.body); - xhr.responseXML = doc; - } catch(ex) { - var parser = new DOMParser(); - xhr.responseXML = parser.parseFromString(ex.body, 'text/xml'); - } - } - } - - var length = 0; - if(e.response.body !== null) { - xhr.responseText = e.response.body; - length = e.response.body.length; - } - // build logging output - var req = _state.request; - var output = - req.method + ' ' + req.path + ' ' + - xhr.status + ' ' + xhr.statusText + ' ' + - length + 'B ' + - (e.request.connectTime + e.request.time + e.response.time) + - 'ms'; - var lFunc; - if(options.verbose) { - lFunc = (xhr.status >= 400 && options.logWarningOnError) ? - _log.warning : _log.verbose; - lFunc(cat, output, - e, e.response.body ? '\n' + e.response.body : '\nNo content'); - } else { - lFunc = (xhr.status >= 400 && options.logWarningOnError) ? - _log.warning : _log.debug; - lFunc(cat, output); - } - if(xhr.onreadystatechange) { - xhr.onreadystatechange(); - } - }; - options.error = function(e) { - var req = _state.request; - _log.error(cat, req.method + ' ' + req.path, e); - - // 1. set response body to null - xhr.responseText = ''; - xhr.responseXML = null; - - // 2. set error flag to true (and reset status) - _state.errorFlag = true; - xhr.status = 0; - xhr.statusText = ''; - - // 3. set state to done - xhr.readyState = DONE; - - // 4. asyc flag is always true, so dispatch onreadystatechange - if(xhr.onreadystatechange) { - xhr.onreadystatechange(); - } - }; - - // 7. send request - _state.client.send(options); - }; - - /** - * Aborts the request. - */ - xhr.abort = function() { - // 1. abort send - // 2. stop network activity - _state.request.abort(); - - // 3. set response to null - xhr.responseText = ''; - xhr.responseXML = null; - - // 4. set error flag to true (and reset status) - _state.errorFlag = true; - xhr.status = 0; - xhr.statusText = ''; - - // 5. clear user headers - _state.request = null; - _state.response = null; - - // 6. if state is DONE or UNSENT, or if OPENED and send flag is false - if(xhr.readyState === DONE || xhr.readyState === UNSENT || - (xhr.readyState === OPENED && !_state.sendFlag)) { - // 7. set ready state to unsent - xhr.readyState = UNSENT; - } else { - // 6.1 set state to DONE - xhr.readyState = DONE; - - // 6.2 set send flag to false - _state.sendFlag = false; - - // 6.3 dispatch onreadystatechange - if(xhr.onreadystatechange) { - xhr.onreadystatechange(); - } - - // 7. set state to UNSENT - xhr.readyState = UNSENT; - } - }; - - /** - * Gets all response headers as a string. - * - * @return the HTTP-encoded response header fields. - */ - xhr.getAllResponseHeaders = function() { - var rval = ''; - if(_state.response !== null) { - var fields = _state.response.fields; - $.each(fields, function(name, array) { - $.each(array, function(i, value) { - rval += name + ': ' + value + '\r\n'; - }); - }); - } - return rval; - }; - - /** - * Gets a single header field value or, if there are multiple - * fields with the same name, a comma-separated list of header - * values. - * - * @return the header field value(s) or null. - */ - xhr.getResponseHeader = function(header) { - var rval = null; - if(_state.response !== null) { - if(header in _state.response.fields) { - rval = _state.response.fields[header]; - if(forge.util.isArray(rval)) { - rval = rval.join(); - } - } - } - return rval; - }; - - return xhr; -}; - -// expose public api -forge.xhr = xhrApi; - -})(jQuery); diff --git a/alarm/node_modules/node-forge/minify.js b/alarm/node_modules/node-forge/minify.js deleted file mode 100644 index 36430a2..0000000 --- a/alarm/node_modules/node-forge/minify.js +++ /dev/null @@ -1,10 +0,0 @@ -({ - name: 'node_modules/almond/almond', - include: ['js/forge'], - out: 'js/forge.min.js', - wrap: { - startFile: 'start.frag', - endFile: 'end.frag' - }, - preserveLicenseComments: false -}) diff --git a/alarm/node_modules/node-forge/mod_fsp/README b/alarm/node_modules/node-forge/mod_fsp/README deleted file mode 100644 index 0331e01..0000000 --- a/alarm/node_modules/node-forge/mod_fsp/README +++ /dev/null @@ -1,135 +0,0 @@ -======= -mod_fsp -======= - -mod_fsp is an Apache2 module for providing a Flash Socket Policy on the -same port that HTTP is served. The cross-domain policy that is served is -specified via a configuration option 'FSPPolicyFile'. - -If a flash application sends a policy file request to an Apache server -that has enabled and configured the mod_fsp module over its HTTP port, -then the configured cross-domain policy will be returned as the response. - -======== -Building -======== - -To build the mod_fsp source code you can use Apache2's module -build and installation tool: 'apxs2' which is, at the time of -this writing, available on debian in the package: - -apache2-threaded-dev - -To compile mod_fsp you would run the following command: - -apxs2 -c mod_fsp.c - -============ -Installation -============ - -To install mod_fsp you the following command as root: - -apxs2 -c -i -a mod_fsp.c - -You must then restart your apache2 process, typically like so: - -/etc/init.d/apache2 restart - -=================== -Manual Installation -=================== - -To manually enable mod_dsp on your Apache2 server, you must copy the -module file to the appropriate directory and create a load file. - -The module file: - -fsp.so (The library extension may vary if you are not using linux). - -Must be copied to Apache's module installation directory which is -typically located (on a debian system): - -/usr/lib/apache2/modules - -The load file: - -fsp.load - -Must be created in Apache2's 'mods-available' directory, typically -located (on a debian system): - -/etc/apache2/mods-available - -The load file should contain: - -LoadModule fsp_module /usr/lib/apache2/modules/mod_fsp.so - -If your Apache module installation directory is different from -the one listed above, you will need to set the correct one in the -fsp.load file. - -To actually enable the module you must create a symbolic link in -Apache's 'mods-enabled' directory, typically located (on debian): - -/etc/apache2/mods-enabled - -By typing (from that directory): - -ln -s ../mods-available/fsp.load fsp.load - -============= -Configuration -============= - -Once mod_fsp is installed, it must be configured. There is currently -only one configuration option for mod_fsp: 'FSPPolicyFile'. This -configuration option will set the file that mod_fsp will look in -on apache startup for the cross-domain policy to serve. This option -can be provided on a per-port basis. Each port can use a different -one, but VirtualServers on a single port will use the same one. This -is a limitation of the design by Adobe. - -Note: The cross-domain policy may fail to be served if the configuration -option isn't added in the first VirtualHost entry (for a given port) read -by Apache. - -An example of this configuration in use: - -<VirtualHost *:80> - ServerName example.com - DocumentRoot /var/www/example.com - ErrorLog /var/log/apache2/example.com-error.log - CustomLog /var/log/apache2/example.com-access.log vhost_combined - - # mod_fsp config option - FSPPolicyFile /etc/apache2/crossdomain/crossdomain.xml - - <Directory /var/www/example.com> - Options Indexes FollowSymLinks MultiViews - AllowOverride All - Order allow,deny - allow from all - </Directory> - -</VirtualHost> - -And example of the most permissive cross-domain policy file for flash: - -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE cross-domain-policy SYSTEM -"http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd"> -<cross-domain-policy> -<site-control permitted-cross-domain-policies="all"/> -<allow-access-from domain="*" to-ports="*"/> -<allow-http-request-headers-from domain="*" headers="*"/> -</cross-domain-policy> - -================== -Note about SSL/TLS -================== - -Flash currently has no built-in SSL/TLS support so there is no -reason to specify an 'FSPPolicyFile' option for SSL servers. The -Flash player cannot directly communicate with them when doing -internal look ups of policy files. diff --git a/alarm/node_modules/node-forge/mod_fsp/mod_fsp.c b/alarm/node_modules/node-forge/mod_fsp/mod_fsp.c deleted file mode 100644 index 8beb824..0000000 --- a/alarm/node_modules/node-forge/mod_fsp/mod_fsp.c +++ /dev/null @@ -1,415 +0,0 @@ -/** - * Flash Socket Policy Apache Module. - * - * This module provides a flash socket policy file on the same port that - * serves HTTP on Apache. This can help simplify setting up a server that - * supports cross-domain communication with flash. - * - * Quick note about Apache memory handling: Data is allocated from pools and - * is not manually returned to those pools. The pools are typically considered - * short-lived and will be cleaned up automatically by Apache. - * - * @author Dave Longley - * - * Copyright (c) 2010 Digital Bazaar, Inc. All rights reserved. - */ -#include "httpd.h" -#include "http_config.h" -#include "http_core.h" - -#include "ap_compat.h" - -#include <string.h> - -// length of a policy file request -#define PFR_LENGTH 23 - -// declare main module -module AP_MODULE_DECLARE_DATA fsp_module; - -// configuration for the module -typedef struct fsp_config -{ - // the cross-domain policy to serve - char* policy; - apr_size_t policy_length; -} fsp_config; - -// filter state for keeping track of detected policy file requests -typedef struct filter_state -{ - fsp_config* cfg; - int checked; - int found; -} filter_state; - -// for registering hooks, filters, etc. -static void fsp_register_hooks(apr_pool_t *p); -static int fsp_pre_connection(conn_rec *c, void *csd); - -// filter handler declarations -static apr_status_t fsp_input_filter( - ap_filter_t* f, apr_bucket_brigade* bb, - ap_input_mode_t mode, apr_read_type_e block, apr_off_t nbytes); -static int fsp_output_filter(ap_filter_t* f, apr_bucket_brigade* bb); - -/** - * Registers the hooks for this module. - * - * @param p the pool to allocate from, if necessary. - */ -static void fsp_register_hooks(apr_pool_t* p) -{ - // registers the pre-connection hook to handle adding filters - ap_hook_pre_connection( - fsp_pre_connection, NULL, NULL, APR_HOOK_MIDDLE); - - // will parse a policy file request, to be added in pre_connection - ap_register_input_filter( - "fsp_request", fsp_input_filter, - NULL, AP_FTYPE_CONNECTION); - - // will emit a cross-domain policy response to be added in pre_connection - ap_register_output_filter( - "fsp_response", fsp_output_filter, - NULL, AP_FTYPE_CONNECTION); -} - -/** - * A hook that is called before a connection is handled. This function will - * get the module configuration and add the flash socket policy filters if - * a cross-domain policy has been specified in the configuration. - * - * @param c the connection. - * @param csd the connection socket descriptor. - * - * @return OK on success. - */ -static int fsp_pre_connection(conn_rec* c, void* csd) -{ - // only install filters if a policy was specified in the module config - fsp_config* cfg = ap_get_module_config( - c->base_server->module_config, &fsp_module); - if(cfg->policy != NULL) - { - // allocate filter state - filter_state* state = apr_palloc(c->pool, sizeof(filter_state)); - if(state != NULL) - { - // initialize state - state->cfg = cfg; - state->checked = state->found = 0; - - // add filters - ap_add_input_filter("fsp_request", state, NULL, c); - ap_add_output_filter("fsp_response", state, NULL, c); - } - } - - return OK; -} - -/** - * Searches the input request for a flash socket policy request. This request, - * unfortunately, does not follow the HTTP protocol and cannot be handled - * via a special HTTP handler. Instead, it is a short xml string followed by - * a null character: - * - * '<policy-file-request/>\0' - * - * A peek into the incoming data checks the first character of the stream to - * see if it is '<' (as opposed to typically something else for HTTP). If it - * is not, then this function returns and HTTP input is read normally. If it - * is, then the remaining bytes in the policy-file-request are read and - * checked. If a match is found, then the filter state will be updated to - * inform the output filter to send a cross-domain policy as a response. If - * no match is found, HTTP traffic will proceed as usual. - * - * @param f the input filter. - * @param state the filter state. - * - * @return APR_SUCCESS on success, some other status on failure. - */ -static apr_status_t find_policy_file_request( - ap_filter_t* f, filter_state* state) -{ - apr_status_t rval = APR_SUCCESS; - - // create a temp buffer for speculative reads - apr_bucket_brigade* tmp = apr_brigade_create(f->c->pool, f->c->bucket_alloc); - - // FIXME: not sure how blocking mode works ... can it return fewer than - // the number of specified bytes? - - // peek at the first PFR_LENGTH bytes - rval = ap_get_brigade( - f->next, tmp, AP_MODE_SPECULATIVE, APR_BLOCK_READ, PFR_LENGTH); - if(rval == APR_SUCCESS) - { - // quickly check the first bucket for the beginning of a pfr - const char* data; - apr_size_t length; - apr_bucket* b = APR_BRIGADE_FIRST(tmp); - rval = apr_bucket_read(b, &data, &length, APR_BLOCK_READ); - if(rval == APR_SUCCESS && length > 0 && data[0] == '<') - { - // possible policy file request, fill local buffer - char pfr[PFR_LENGTH]; - char* ptr = pfr; - memcpy(ptr, data, length); - ptr += length; - memset(ptr, '\0', PFR_LENGTH - length); - b = APR_BUCKET_NEXT(b); - while(rval == APR_SUCCESS && b != APR_BRIGADE_SENTINEL(tmp)) - { - rval = apr_bucket_read(b, &data, &length, APR_BLOCK_READ); - if(rval == APR_SUCCESS) - { - memcpy(ptr, data, length); - ptr += length; - b = APR_BUCKET_NEXT(b); - } - } - - if(rval == APR_SUCCESS) - { - // see if pfr is a policy file request: '<policy-file-request/>\0' - if((ptr - pfr == PFR_LENGTH) && (pfr[PFR_LENGTH - 1] == '\0') && - (strncmp(pfr, "<policy-file-request/>", PFR_LENGTH -1) == 0)) - { - // pfr found - state->found = 1; - } - } - } - } - - return rval; -} - -/** - * Handles incoming data. If an attempt has not yet been made to look for - * a policy request (it is the beginning of the connection), then one is - * made. Otherwise this filter does nothing. - * - * If an attempt is made to find a policy request and one is not found, then - * reads proceed as normal. If one is found, then the filter state is modified - * to inform the output filter to send a policy request and the return value - * of this filter is EOF indicating that the connection should close after - * sending the cross-domain policy. - * - * @param f the input filter. - * @param bb the brigate to fill with input from the next filters in the chain - * and then process (look for a policy file request). - * @param mode the type of read requested (ie: AP_MODE_GETLINE means read until - * a CRLF is found, AP_MODE_GETBYTES means 'nbytes' of data, etc). - * @param block APR_BLOCK_READ or APR_NONBLOCK_READ, indicates the type of - * blocking to do when trying to read. - * @param nbytes used if the read mode is appropriate to specify the number of - * bytes to read (set to 0 for AP_MODE_GETLINE). - * - * @return the status of the input (ie: APR_SUCCESS for read success, APR_EOF - * for end of stream, APR_EAGAIN to read again when non-blocking). - */ -static apr_status_t fsp_input_filter( - ap_filter_t* f, apr_bucket_brigade* bb, - ap_input_mode_t mode, apr_read_type_e block, apr_off_t nbytes) -{ - apr_status_t rval = APR_SUCCESS; - - filter_state* state = f->ctx; - if(state->checked == 1) - { - // already checked for policy file request, just read from other filters - rval = ap_get_brigade(f->next, bb, mode, block, nbytes); - } - else - { - // try to find a policy file request - rval = find_policy_file_request(f, state); - state->checked = 1; - - if(rval == APR_SUCCESS) - { - if(state->found) - { - // do read of PFR_LENGTH bytes, consider end of stream - rval = ap_get_brigade( - f->next, bb, AP_MODE_READBYTES, APR_BLOCK_READ, PFR_LENGTH); - rval = APR_EOF; - } - else - { - // do normal read - rval = ap_get_brigade(f->next, bb, mode, block, nbytes); - } - } - } - - return rval; -} - -/** - * Handles outgoing data. If the filter state indicates that a cross-domain - * policy should be sent then it is added to the outgoing brigade of data. If - * a policy request was not detected, then this filter makes no changes to - * the outgoing data. - * - * @param f the output filter. - * @param bb the outgoing brigade of data. - * - * @return APR_SUCCESS on success, some other status on error. - */ -static int fsp_output_filter(ap_filter_t* f, apr_bucket_brigade* bb) -{ - apr_status_t rval = APR_SUCCESS; - - filter_state* state = f->ctx; - if(state->found) - { - // found policy-file-request, add response bucket - // bucket is immortal because the data is stored in the configuration - // and doesn't need to be copied - apr_bucket* head = apr_bucket_immortal_create( - state->cfg->policy, state->cfg->policy_length, bb->bucket_alloc); - APR_BRIGADE_INSERT_HEAD(bb, head); - } - - if(rval == APR_SUCCESS) - { - // pass brigade to next filter - rval = ap_pass_brigade(f->next, bb); - } - - return rval; -} - -/** - * Creates the configuration for this module. - * - * @param p the pool to allocate from. - * @param s the server the configuration is for. - * - * @return the configuration data. - */ -static void* fsp_create_config(apr_pool_t* p, server_rec* s) -{ - // allocate config - fsp_config* cfg = apr_palloc(p, sizeof(fsp_config)); - - // no default policy - cfg->policy = NULL; - cfg->policy_length = 0; - return cfg; -} - -/** - * Sets the policy file to use from the configuration. - * - * @param parms the command directive parameters. - * @param userdata NULL, not used. - * @param arg the string argument to the command directive (the file with - * the cross-domain policy to serve as content). - * - * @return NULL on success, otherwise an error string to display. - */ -static const char* fsp_set_policy_file( - cmd_parms* parms, void* userdata, const char* arg) -{ - const char* rval = NULL; - - apr_pool_t* pool = (apr_pool_t*)parms->pool; - fsp_config* cfg = ap_get_module_config( - parms->server->module_config, &fsp_module); - - // ensure command is in the correct context - rval = ap_check_cmd_context(parms, NOT_IN_DIR_LOC_FILE|NOT_IN_LIMIT); - if(rval == NULL) - { - // get canonical file name - char* fname = ap_server_root_relative(pool, arg); - if(fname == NULL) - { - rval = (const char*)apr_psprintf( - pool, "%s: Invalid policy file '%s'", - parms->cmd->name, arg); - } - else - { - // try to open the file - apr_status_t rv; - apr_file_t* fd; - apr_finfo_t finfo; - rv = apr_file_open(&fd, fname, APR_READ, APR_OS_DEFAULT, pool); - if(rv == APR_SUCCESS) - { - // stat file - rv = apr_file_info_get(&finfo, APR_FINFO_NORM, fd); - if(rv == APR_SUCCESS) - { - // ensure file is not empty - apr_size_t length = (apr_size_t)finfo.size; - if(length <= 0) - { - rval = (const char*)apr_psprintf( - pool, "%s: policy file '%s' is empty", - parms->cmd->name, fname); - } - // read file - else - { - char* buf = (char*)apr_palloc(pool, length + 1); - buf[length] = '\0'; - rv = apr_file_read_full(fd, buf, length, NULL); - if(rv == APR_SUCCESS) - { - // TODO: validate file - // save policy string - cfg->policy = buf; - cfg->policy_length = length + 1; - } - } - - // close the file - apr_file_close(fd); - } - } - - // handle error case - if(rv != APR_SUCCESS) - { - char errmsg[120]; - rval = (const char*)apr_psprintf( - pool, "%s: Invalid policy file '%s' (%s)", - parms->cmd->name, fname, - apr_strerror(rv, errmsg, sizeof(errmsg))); - } - } - } - - return rval; -} - -// table of configuration directives -static const command_rec fsp_cmds[] = -{ - AP_INIT_TAKE1( - "FSPPolicyFile", /* the directive */ - fsp_set_policy_file, /* function to call when directive is found */ - NULL, /* user data to pass to function, not used */ - RSRC_CONF, /* indicates the directive appears outside of <Location> */ - "FSPPolicyFile (string) The cross-domain policy file to use"), /* docs */ - {NULL} -}; - -// module setup -module AP_MODULE_DECLARE_DATA fsp_module = -{ - STANDARD20_MODULE_STUFF, /* stuff declared in every 2.0 mod */ - NULL, /* create per-directory config structure */ - NULL, /* merge per-directory config structures */ - fsp_create_config, /* create per-server config structure */ - NULL, /* merge per-server config structures */ - fsp_cmds, /* command apr_table_t */ - fsp_register_hooks /* register hooks */ -}; diff --git a/alarm/node_modules/node-forge/nodejs/.istanbul.yml b/alarm/node_modules/node-forge/nodejs/.istanbul.yml deleted file mode 100644 index 8a69b69..0000000 --- a/alarm/node_modules/node-forge/nodejs/.istanbul.yml +++ /dev/null @@ -1,2 +0,0 @@ -instrumentation: - root: .. diff --git a/alarm/node_modules/node-forge/nodejs/README.md b/alarm/node_modules/node-forge/nodejs/README.md deleted file mode 100644 index 1be00fa..0000000 --- a/alarm/node_modules/node-forge/nodejs/README.md +++ /dev/null @@ -1,34 +0,0 @@ -Running all the tests (headless-browser and node.js) -==================================================== - - npm install - npm test - -Running the browser-based tests -=============================== - - npm install - node server.js - -Then go to http://localhost:8083/. - -Testing Require.js optimised version of the JavaScript ------------------------------------------------------- - - npm install -g requirejs - r.js -o build.js - -You will now have a single optimised JS file at ui/test.min.js, containing the -tests and all the forge dependencies. - -Now edit ui/index.html and change `data-main="test"` to `data-main="test.min"`, -then reload http://localhost:8083/. - -Building a minimized single file for all forge modules ------------------------------------------------------- - - npm install -g requirejs - r.js -o minify.js - -You will now have forge.min.js, in the 'js' directory, which will contain all -forge modules. diff --git a/alarm/node_modules/node-forge/nodejs/build.js b/alarm/node_modules/node-forge/nodejs/build.js deleted file mode 100644 index 30ba7b5..0000000 --- a/alarm/node_modules/node-forge/nodejs/build.js +++ /dev/null @@ -1,8 +0,0 @@ -({ - paths: { - forge: '../js' - }, - name: 'ui/test.js', - out: 'ui/test.min.js', - preserveLicenseComments: false -}) diff --git a/alarm/node_modules/node-forge/nodejs/minify.js b/alarm/node_modules/node-forge/nodejs/minify.js deleted file mode 100644 index 69d96a9..0000000 --- a/alarm/node_modules/node-forge/nodejs/minify.js +++ /dev/null @@ -1,8 +0,0 @@ -({ - paths: { - forge: '../js' - }, - name: '../js/forge', - out: '../js/forge.min.js', - preserveLicenseComments: false -}) diff --git a/alarm/node_modules/node-forge/nodejs/package.json b/alarm/node_modules/node-forge/nodejs/package.json deleted file mode 100644 index cb88fc3..0000000 --- a/alarm/node_modules/node-forge/nodejs/package.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "name": "forge-nodejs-example", - "version": "0.1.0", - "private": true, - "main": "server.js", - "dependencies": { - "express": "~3.1.0", - "mocha": "~1.21.5", - "chai": "~1.10.0", - "grunt": "~0.4.5", - "grunt-mocha": "~0.4.12" - }, - "scripts": { - "run": "node server", - "test": "mocha -t 30000 -R spec test/*.js", - "coverage": "rm -rf coverage && ./node_modules/.bin/istanbul cover ./node_modules/.bin/_mocha -- -u exports -t 30000 -R spec test/*.js", - "coverage-lcov": "rm -rf coverage && ./node_modules/.bin/istanbul cover ./node_modules/.bin/_mocha --report lcovonly -- -u exports -t 30000 -R spec test/*.js", - "coverage-report": "./node_modules/.bin/istanbul report" - }, - "devDependencies": { - "istanbul": "^0.3.14", - "mocha-lcov-reporter": "0.0.2" - } -} diff --git a/alarm/node_modules/node-forge/nodejs/server.js b/alarm/node_modules/node-forge/nodejs/server.js deleted file mode 100644 index 175bd56..0000000 --- a/alarm/node_modules/node-forge/nodejs/server.js +++ /dev/null @@ -1,46 +0,0 @@ -var PATH = require('path'); -var express = require('express'); -var PORT = 8083; - -exports.main = function(callback) { - try { - var app = express(); - - mountStaticDir(app, /^\/forge\/(.*)$/, PATH.join(__dirname, '../js')); - mountStaticDir(app, /^\/test\/(.*)$/, PATH.join(__dirname, 'test')); - mountStaticDir(app, /^\/mocha\/(.*)$/, PATH.join(__dirname, 'node_modules/mocha')); - mountStaticDir(app, /^\/chai\/(.*)$/, PATH.join(__dirname, 'node_modules/chai')); - app.get(/^\//, express.static(PATH.join(__dirname, 'ui'))); - - var server = app.listen(PORT); - - console.log('open http://localhost:' + PORT + '/'); - - return callback(null, { - server: server, - port: PORT - }); - } catch(err) { - return callback(err); - } -}; - -function mountStaticDir(app, route, path) { - app.get(route, function(req, res, next) { - var originalUrl = req.url; - req.url = req.params[0]; - express.static(path)(req, res, function() { - req.url = originalUrl; - return next.apply(null, arguments); - }); - }); -} - -if(require.main === module) { - exports.main(function(err) { - if(err) { - console.error(err.stack); - process.exit(1); - } - }); -} diff --git a/alarm/node_modules/node-forge/nodejs/test/aes.js b/alarm/node_modules/node-forge/nodejs/test/aes.js deleted file mode 100644 index 6d8b221..0000000 --- a/alarm/node_modules/node-forge/nodejs/test/aes.js +++ /dev/null @@ -1,1498 +0,0 @@ -(function() { - -function Tests(ASSERT, CIPHER, AES, UTIL) { - describe('aes', function() { - it('should encrypt a single block with a 128-bit key', function() { - var key = [0x00010203, 0x04050607, 0x08090a0b, 0x0c0d0e0f]; - var block = [0x00112233, 0x44556677, 0x8899aabb, 0xccddeeff]; - - var output = []; - var w = AES._expandKey(key, false); - AES._updateBlock(w, block, output, false); - - var out = UTIL.createBuffer(); - out.putInt32(output[0]); - out.putInt32(output[1]); - out.putInt32(output[2]); - out.putInt32(output[3]); - - ASSERT.equal(out.toHex(), '69c4e0d86a7b0430d8cdb78070b4c55a'); - }); - - it('should decrypt a single block with a 128-bit key', function() { - var key = [0x00010203, 0x04050607, 0x08090a0b, 0x0c0d0e0f]; - var block = [0x69c4e0d8, 0x6a7b0430, 0xd8cdb780, 0x70b4c55a]; - - var output = []; - var w = AES._expandKey(key, true); - AES._updateBlock(w, block, output, true); - - var out = UTIL.createBuffer(); - out.putInt32(output[0]); - out.putInt32(output[1]); - out.putInt32(output[2]); - out.putInt32(output[3]); - - ASSERT.equal(out.toHex(), '00112233445566778899aabbccddeeff'); - }); - - it('should encrypt a single block with a 192-bit key', function() { - var key = [ - 0x00010203, 0x04050607, 0x08090a0b, 0x0c0d0e0f, - 0x10111213, 0x14151617]; - var block = [0x00112233, 0x44556677, 0x8899aabb, 0xccddeeff]; - - var output = []; - var w = AES._expandKey(key, false); - AES._updateBlock(w, block, output, false); - - var out = UTIL.createBuffer(); - out.putInt32(output[0]); - out.putInt32(output[1]); - out.putInt32(output[2]); - out.putInt32(output[3]); - - ASSERT.equal(out.toHex(), 'dda97ca4864cdfe06eaf70a0ec0d7191'); - }); - - it('should decrypt a single block with a 192-bit key', function() { - var key = [ - 0x00010203, 0x04050607, 0x08090a0b, 0x0c0d0e0f, - 0x10111213, 0x14151617]; - var block = [0xdda97ca4, 0x864cdfe0, 0x6eaf70a0, 0xec0d7191]; - - var output = []; - var w = AES._expandKey(key, true); - AES._updateBlock(w, block, output, true); - - var out = UTIL.createBuffer(); - out.putInt32(output[0]); - out.putInt32(output[1]); - out.putInt32(output[2]); - out.putInt32(output[3]); - - ASSERT.equal(out.toHex(), '00112233445566778899aabbccddeeff'); - }); - - it('should encrypt a single block with a 256-bit key', function() { - var key = [ - 0x00010203, 0x04050607, 0x08090a0b, 0x0c0d0e0f, - 0x10111213, 0x14151617, 0x18191a1b, 0x1c1d1e1f]; - var block = [0x00112233, 0x44556677, 0x8899aabb, 0xccddeeff]; - - var output = []; - var w = AES._expandKey(key, false); - AES._updateBlock(w, block, output, false); - - var out = UTIL.createBuffer(); - out.putInt32(output[0]); - out.putInt32(output[1]); - out.putInt32(output[2]); - out.putInt32(output[3]); - - ASSERT.equal(out.toHex(), '8ea2b7ca516745bfeafc49904b496089'); - }); - - it('should decrypt a single block with a 256-bit key', function() { - var key = [ - 0x00010203, 0x04050607, 0x08090a0b, 0x0c0d0e0f, - 0x10111213, 0x14151617, 0x18191a1b, 0x1c1d1e1f]; - var block = [0x8ea2b7ca, 0x516745bf, 0xeafc4990, 0x4b496089]; - - var output = []; - var w = AES._expandKey(key, true); - AES._updateBlock(w, block, output, true); - - var out = UTIL.createBuffer(); - out.putInt32(output[0]); - out.putInt32(output[1]); - out.putInt32(output[2]); - out.putInt32(output[3]); - - ASSERT.equal(out.toHex(), '00112233445566778899aabbccddeeff'); - }); - - // AES-128-ECB - (function() { - var keys = [ - '2b7e151628aed2a6abf7158809cf4f3c', - '2b7e151628aed2a6abf7158809cf4f3c', - '2b7e151628aed2a6abf7158809cf4f3c', - '2b7e151628aed2a6abf7158809cf4f3c' - ]; - - var inputs = [ - '6bc1bee22e409f96e93d7e117393172a', - 'ae2d8a571e03ac9c9eb76fac45af8e51', - '30c81c46a35ce411e5fbc1191a0a52ef', - 'f69f2445df4f9b17ad2b417be66c3710' - ]; - - var outputs = [ - '3ad77bb40d7a3660a89ecaf32466ef97', - 'f5d3d58503b9699de785895a96fdbaaf', - '43b1cd7f598ece23881b00e3ed030688', - '7b0c785e27e8ad3f8223207104725dd4' - ]; - - for(var i = 0; i < keys.length; ++i) { - (function(i) { - var key = UTIL.hexToBytes(keys[i]); - var input = UTIL.hexToBytes(inputs[i]); - var output = UTIL.hexToBytes(outputs[i]); - - it('should aes-128-ecb encrypt: ' + inputs[i], function() { - // encrypt w/no padding - var cipher = CIPHER.createCipher('AES-ECB', key); - cipher.mode.pad = false; - cipher.start(); - cipher.update(UTIL.createBuffer(input)); - cipher.finish(); - ASSERT.equal(cipher.output.toHex(), outputs[i]); - }); - - it('should aes-128-ecb decrypt: ' + outputs[i], function() { - // decrypt w/no padding - var cipher = CIPHER.createDecipher('AES-ECB', key); - cipher.mode.unpad = false; - cipher.start(); - cipher.update(UTIL.createBuffer(output)); - cipher.finish(); - ASSERT.equal(cipher.output.toHex(), inputs[i]); - }); - })(i); - } - })(); - - // AES-192-ECB - (function() { - var keys = [ - '8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b', - '8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b', - '8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b', - '8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b' - ]; - - var inputs = [ - '6bc1bee22e409f96e93d7e117393172a', - 'ae2d8a571e03ac9c9eb76fac45af8e51', - '30c81c46a35ce411e5fbc1191a0a52ef', - 'f69f2445df4f9b17ad2b417be66c3710' - ]; - - var outputs = [ - 'bd334f1d6e45f25ff712a214571fa5cc', - '974104846d0ad3ad7734ecb3ecee4eef', - 'ef7afd2270e2e60adce0ba2face6444e', - '9a4b41ba738d6c72fb16691603c18e0e' - ]; - - for(var i = 0; i < keys.length; ++i) { - (function(i) { - var key = UTIL.hexToBytes(keys[i]); - var input = UTIL.hexToBytes(inputs[i]); - var output = UTIL.hexToBytes(outputs[i]); - - it('should aes-192-ecb encrypt: ' + inputs[i], function() { - // encrypt w/no padding - var cipher = CIPHER.createCipher('AES-ECB', key); - cipher.mode.pad = false; - cipher.start(); - cipher.update(UTIL.createBuffer(input)); - cipher.finish(); - ASSERT.equal(cipher.output.toHex(), outputs[i]); - }); - - it('should aes-192-ecb decrypt: ' + outputs[i], function() { - // decrypt w/no padding - var cipher = CIPHER.createDecipher('AES-ECB', key); - cipher.mode.unpad = false; - cipher.start(); - cipher.update(UTIL.createBuffer(output)); - cipher.finish(); - ASSERT.equal(cipher.output.toHex(), inputs[i]); - }); - })(i); - } - })(); - - // AES-256-ECB - (function() { - var keys = [ - '603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4', - '603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4', - '603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4', - '603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4' - ]; - - var inputs = [ - '6bc1bee22e409f96e93d7e117393172a', - 'ae2d8a571e03ac9c9eb76fac45af8e51', - '30c81c46a35ce411e5fbc1191a0a52ef', - 'f69f2445df4f9b17ad2b417be66c3710' - ]; - - var outputs = [ - 'f3eed1bdb5d2a03c064b5a7e3db181f8', - '591ccb10d410ed26dc5ba74a31362870', - 'b6ed21b99ca6f4f9f153e7b1beafed1d', - '23304b7a39f9f3ff067d8d8f9e24ecc7' - ]; - - for(var i = 0; i < keys.length; ++i) { - (function(i) { - var key = UTIL.hexToBytes(keys[i]); - var input = UTIL.hexToBytes(inputs[i]); - var output = UTIL.hexToBytes(outputs[i]); - - it('should aes-256-ecb encrypt: ' + inputs[i], function() { - // encrypt w/no padding - var cipher = CIPHER.createCipher('AES-ECB', key); - cipher.mode.pad = false; - cipher.start(); - cipher.update(UTIL.createBuffer(input)); - cipher.finish(); - ASSERT.equal(cipher.output.toHex(), outputs[i]); - }); - - it('should aes-256-ecb decrypt: ' + outputs[i], function() { - // decrypt w/no padding - var cipher = CIPHER.createDecipher('AES-ECB', key); - cipher.mode.unpad = false; - cipher.start(); - cipher.update(UTIL.createBuffer(output)); - cipher.finish(); - ASSERT.equal(cipher.output.toHex(), inputs[i]); - }); - })(i); - } - })(); - - // AES-128-CBC - (function() { - var keys = [ - '06a9214036b8a15b512e03d534120006', - 'c286696d887c9aa0611bbb3e2025a45a', - '6c3ea0477630ce21a2ce334aa746c2cd', - '56e47a38c5598974bc46903dba290349' - ]; - - var ivs = [ - '3dafba429d9eb430b422da802c9fac41', - '562e17996d093d28ddb3ba695a2e6f58', - 'c782dc4c098c66cbd9cd27d825682c81', - '8ce82eefbea0da3c44699ed7db51b7d9' - ]; - - var inputs = [ - 'Single block msg', - '000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f', - 'This is a 48-byte message (exactly 3 AES blocks)', - 'a0a1a2a3a4a5a6a7a8a9aaabacadaeaf' + - 'b0b1b2b3b4b5b6b7b8b9babbbcbdbebf' + - 'c0c1c2c3c4c5c6c7c8c9cacbcccdcecf' + - 'd0d1d2d3d4d5d6d7d8d9dadbdcdddedf' - ]; - - var outputs = [ - 'e353779c1079aeb82708942dbe77181a', - 'd296cd94c2cccf8a3a863028b5e1dc0a7586602d253cfff91b8266bea6d61ab1', - 'd0a02b3836451753d493665d33f0e886' + - '2dea54cdb293abc7506939276772f8d5' + - '021c19216bad525c8579695d83ba2684', - 'c30e32ffedc0774e6aff6af0869f71aa' + - '0f3af07a9a31a9c684db207eb0ef8e4e' + - '35907aa632c3ffdf868bb7b29d3d46ad' + - '83ce9f9a102ee99d49a53e87f4c3da55' - ]; - - for(var i = 0; i < keys.length; ++i) { - (function(i) { - var key = UTIL.hexToBytes(keys[i]); - var iv = UTIL.hexToBytes(ivs[i]); - var input = (i & 1) ? UTIL.hexToBytes(inputs[i]) : inputs[i]; - var output = UTIL.hexToBytes(outputs[i]); - - it('should aes-128-cbc encrypt: ' + inputs[i], function() { - // encrypt w/no padding - var cipher = CIPHER.createCipher('AES-CBC', key); - cipher.mode.pad = false; - cipher.start({iv: iv}); - cipher.update(UTIL.createBuffer(input)); - cipher.finish(); - ASSERT.equal(cipher.output.toHex(), outputs[i]); - }); - - it('should aes-128-cbc decrypt: ' + outputs[i], function() { - // decrypt w/no padding - var cipher = CIPHER.createDecipher('AES-CBC', key); - cipher.mode.unpad = false; - cipher.start({iv: iv}); - cipher.update(UTIL.createBuffer(output)); - cipher.finish(); - var out = (i & 1) ? cipher.output.toHex() : cipher.output.bytes(); - ASSERT.equal(out, inputs[i]); - }); - })(i); - } - })(); - - // AES-192-CBC - (function() { - var keys = [ - '8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b', - '8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b', - '8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b', - '8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b' - ]; - - var ivs = [ - '000102030405060708090A0B0C0D0E0F', - '4F021DB243BC633D7178183A9FA071E8', - 'B4D9ADA9AD7DEDF4E5E738763F69145A', - '571B242012FB7AE07FA9BAAC3DF102E0' - ]; - - var inputs = [ - '6bc1bee22e409f96e93d7e117393172a', - 'ae2d8a571e03ac9c9eb76fac45af8e51', - '30c81c46a35ce411e5fbc1191a0a52ef', - 'f69f2445df4f9b17ad2b417be66c3710' - ]; - - var outputs = [ - '4f021db243bc633d7178183a9fa071e8', - 'b4d9ada9ad7dedf4e5e738763f69145a', - '571b242012fb7ae07fa9baac3df102e0', - '08b0e27988598881d920a9e64f5615cd' - ]; - - for(var i = 0; i < keys.length; ++i) { - (function(i) { - var key = UTIL.hexToBytes(keys[i]); - var iv = UTIL.hexToBytes(ivs[i]); - var input = UTIL.hexToBytes(inputs[i]); - var output = UTIL.hexToBytes(outputs[i]); - - it('should aes-192-cbc encrypt: ' + inputs[i], function() { - // encrypt w/no padding - var cipher = CIPHER.createCipher('AES-CBC', key); - cipher.mode.pad = false; - cipher.start({iv: iv}); - cipher.update(UTIL.createBuffer(input)); - cipher.finish(); - ASSERT.equal(cipher.output.toHex(), outputs[i]); - }); - - it('should aes-192-cbc decrypt: ' + outputs[i], function() { - // decrypt w/no padding - var cipher = CIPHER.createDecipher('AES-CBC', key); - cipher.mode.unpad = false; - cipher.start({iv: iv}); - cipher.update(UTIL.createBuffer(output)); - cipher.finish(); - var out = cipher.output.toHex(); - ASSERT.equal(out, inputs[i]); - }); - })(i); - } - })(); - - // AES-256-CBC - (function() { - var keys = [ - '603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4', - '603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4', - '603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4', - '603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4' - ]; - - var ivs = [ - '000102030405060708090A0B0C0D0E0F', - 'F58C4C04D6E5F1BA779EABFB5F7BFBD6', - '9CFC4E967EDB808D679F777BC6702C7D', - '39F23369A9D9BACFA530E26304231461' - ]; - - var inputs = [ - '6bc1bee22e409f96e93d7e117393172a', - 'ae2d8a571e03ac9c9eb76fac45af8e51', - '30c81c46a35ce411e5fbc1191a0a52ef', - 'f69f2445df4f9b17ad2b417be66c3710' - ]; - - var outputs = [ - 'f58c4c04d6e5f1ba779eabfb5f7bfbd6', - '9cfc4e967edb808d679f777bc6702c7d', - '39f23369a9d9bacfa530e26304231461', - 'b2eb05e2c39be9fcda6c19078c6a9d1b' - ]; - - for(var i = 0; i < keys.length; ++i) { - (function(i) { - var key = UTIL.hexToBytes(keys[i]); - var iv = UTIL.hexToBytes(ivs[i]); - var input = UTIL.hexToBytes(inputs[i]); - var output = UTIL.hexToBytes(outputs[i]); - - it('should aes-256-cbc encrypt: ' + inputs[i], function() { - // encrypt w/no padding - var cipher = CIPHER.createCipher('AES-CBC', key); - cipher.mode.pad = false; - cipher.start({iv: iv}); - cipher.update(UTIL.createBuffer(input)); - cipher.finish(); - ASSERT.equal(cipher.output.toHex(), outputs[i]); - }); - - it('should aes-256-cbc decrypt: ' + outputs[i], function() { - // decrypt w/no padding - var cipher = CIPHER.createDecipher('AES-CBC', key); - cipher.mode.unpad = false; - cipher.start({iv: iv}); - cipher.update(UTIL.createBuffer(output)); - cipher.finish(); - var out = cipher.output.toHex(); - ASSERT.equal(out, inputs[i]); - }); - })(i); - } - })(); - - // AES-128-CFB - (function() { - var keys = [ - '00000000000000000000000000000000', - '2b7e151628aed2a6abf7158809cf4f3c', - '2b7e151628aed2a6abf7158809cf4f3c', - '2b7e151628aed2a6abf7158809cf4f3c', - '2b7e151628aed2a6abf7158809cf4f3c', - '00000000000000000000000000000000' - ]; - - var ivs = [ - '80000000000000000000000000000000', - '000102030405060708090a0b0c0d0e0f', - '3B3FD92EB72DAD20333449F8E83CFB4A', - 'C8A64537A0B3A93FCDE3CDAD9F1CE58B', - '26751F67A3CBB140B1808CF187A4F4DF', - '60f9ff04fac1a25657bf5b36b5efaf75' - ]; - - var inputs = [ - '00000000000000000000000000000000', - '6bc1bee22e409f96e93d7e117393172a', - 'ae2d8a571e03ac9c9eb76fac45af8e51', - '30c81c46a35ce411e5fbc1191a0a52ef', - 'f69f2445df4f9b17ad2b417be66c3710', - 'This is a 48-byte message (exactly 3 AES blocks)' - ]; - - var outputs = [ - '3ad78e726c1ec02b7ebfe92b23d9ec34', - '3b3fd92eb72dad20333449f8e83cfb4a', - 'c8a64537a0b3a93fcde3cdad9f1ce58b', - '26751f67a3cbb140b1808cf187a4f4df', - 'c04b05357c5d1c0eeac4c66f9ff7f2e6', - '52396a2ba1ba420c5e5b699a814944d8' + - 'f4e7fbf984a038319fbc0b4ee45cfa6f' + - '07b2564beab5b5e92dbd44cb345f49b4' - ]; - - for(var i = 0; i < keys.length; ++i) { - (function(i) { - var key = UTIL.hexToBytes(keys[i]); - var iv = UTIL.hexToBytes(ivs[i]); - var input = (i !== 5) ? UTIL.hexToBytes(inputs[i]) : inputs[i]; - var output = UTIL.hexToBytes(outputs[i]); - - it('should aes-128-cfb encrypt: ' + inputs[i], function() { - // encrypt - var cipher = CIPHER.createCipher('AES-CFB', key); - cipher.start({iv: iv}); - cipher.update(UTIL.createBuffer(input)); - cipher.finish(); - ASSERT.equal(cipher.output.toHex(), outputs[i]); - }); - - it('should aes-128-cfb decrypt: ' + outputs[i], function() { - // decrypt - var cipher = CIPHER.createDecipher('AES-CFB', key); - cipher.start({iv: iv}); - cipher.update(UTIL.createBuffer(output)); - cipher.finish(); - var out = (i !== 5) ? - cipher.output.toHex() : cipher.output.getBytes(); - ASSERT.equal(out, inputs[i]); - }); - - it('should aes-128-cfb encrypt (one byte at a time): ' + inputs[i], function() { - // encrypt - var cipher = CIPHER.createCipher('AES-CFB', key); - cipher.start({iv: iv}); - var input_ = UTIL.createBuffer(input); - var out = UTIL.createBuffer(); - while(input_.length() > 0) { - cipher.update(UTIL.createBuffer(input_.getBytes(1))); - ASSERT.equal(cipher.output.length(), 1); - out.putByte(cipher.output.getByte()); - } - cipher.finish(); - ASSERT.equal(out.toHex(), outputs[i]); - }); - - it('should aes-128-cfb decrypt (one byte at a time): ' + outputs[i], function() { - // decrypt - var cipher = CIPHER.createDecipher('AES-CFB', key); - cipher.start({iv: iv}); - var output_ = UTIL.createBuffer(output); - var out = UTIL.createBuffer(); - while(output_.length() > 0) { - cipher.update(UTIL.createBuffer(output_.getBytes(1))); - ASSERT.equal(cipher.output.length(), 1); - out.putByte(cipher.output.getByte()); - } - cipher.finish(); - out = (i !== 5) ? out.toHex() : out.getBytes(); - ASSERT.equal(out, inputs[i]); - }); - })(i); - } - })(); - - // AES-192-CFB - (function() { - var keys = [ - '8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b', - '8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b', - '8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b', - '8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b' - ]; - - var ivs = [ - '000102030405060708090A0B0C0D0E0F', - 'CDC80D6FDDF18CAB34C25909C99A4174', - '67CE7F7F81173621961A2B70171D3D7A', - '2E1E8A1DD59B88B1C8E60FED1EFAC4C9' - ]; - - var inputs = [ - '6bc1bee22e409f96e93d7e117393172a', - 'ae2d8a571e03ac9c9eb76fac45af8e51', - '30c81c46a35ce411e5fbc1191a0a52ef', - 'f69f2445df4f9b17ad2b417be66c3710' - ]; - - var outputs = [ - 'cdc80d6fddf18cab34c25909c99a4174', - '67ce7f7f81173621961a2b70171d3d7a', - '2e1e8a1dd59b88b1c8e60fed1efac4c9', - 'c05f9f9ca9834fa042ae8fba584b09ff' - ]; - - for(var i = 0; i < keys.length; ++i) { - (function(i) { - var key = UTIL.hexToBytes(keys[i]); - var iv = UTIL.hexToBytes(ivs[i]); - var input = UTIL.hexToBytes(inputs[i]); - var output = UTIL.hexToBytes(outputs[i]); - - it('should aes-192-cfb encrypt: ' + inputs[i], function() { - // encrypt - var cipher = CIPHER.createCipher('AES-CFB', key); - cipher.start({iv: iv}); - cipher.update(UTIL.createBuffer(input)); - cipher.finish(); - ASSERT.equal(cipher.output.toHex(), outputs[i]); - }); - - it('should aes-192-cfb decrypt: ' + outputs[i], function() { - // decrypt - var cipher = CIPHER.createDecipher('AES-CFB', key); - cipher.start({iv: iv}); - cipher.update(UTIL.createBuffer(output)); - cipher.finish(); - var out = cipher.output.toHex(); - ASSERT.equal(out, inputs[i]); - }); - })(i); - } - })(); - - // AES-256-CFB - (function() { - var keys = [ - '861009ec4d599fab1f40abc76e6f89880cff5833c79c548c99f9045f191cd90b' - ]; - - var ivs = [ - 'd927ad81199aa7dcadfdb4e47b6dc694' - ]; - - var inputs = [ - 'MY-DATA-AND-HERE-IS-MORE-DATA' - ]; - - var outputs = [ - '80eb666a9fc9e263faf71e87ffc94451d7d8df7cfcf2606470351dd5ac' - ]; - - for(var i = 0; i < keys.length; ++i) { - (function(i) { - var key = UTIL.hexToBytes(keys[i]); - var iv = UTIL.hexToBytes(ivs[i]); - var input = inputs[i]; - var output = UTIL.hexToBytes(outputs[i]); - - it('should aes-256-cfb encrypt: ' + inputs[i], function() { - // encrypt - var cipher = CIPHER.createCipher('AES-CFB', key); - cipher.start({iv: iv}); - cipher.update(UTIL.createBuffer(input)); - cipher.finish(); - ASSERT.equal(cipher.output.toHex(), outputs[i]); - }); - - it('should aes-256-cfb decrypt: ' + outputs[i], function() { - // decrypt - var cipher = CIPHER.createDecipher('AES-CFB', key); - cipher.start({iv: iv}); - cipher.update(UTIL.createBuffer(output)); - cipher.finish(); - var out = cipher.output.getBytes(); - ASSERT.equal(out, inputs[i]); - }); - })(i); - } - })(); - - // AES-128-OFB - (function() { - var keys = [ - '00000000000000000000000000000000', - '00000000000000000000000000000000', - '00000000000000000000000000000000' - ]; - - var ivs = [ - '80000000000000000000000000000000', - 'c8ca0d6a35dbeac776e911ee16bea7d3', - '80000000000000000000000000000000' - ]; - - var inputs = [ - '00000000000000000000000000000000', - 'This is a 48-byte message (exactly 3 AES blocks)', - '0000' - ]; - - var outputs = [ - '3ad78e726c1ec02b7ebfe92b23d9ec34', - '39c0190727a76b2a90963426f63689cf' + - 'cdb8a2be8e20c5e877a81a724e3611f6' + - '2ecc386f2e941b2441c838906002be19', - '3ad7' - ]; - - for(var i = 0; i < keys.length; ++i) { - (function(i) { - var key = UTIL.hexToBytes(keys[i]); - var iv = UTIL.hexToBytes(ivs[i]); - var input = (i !== 1) ? UTIL.hexToBytes(inputs[i]) : inputs[i]; - var output = UTIL.hexToBytes(outputs[i]); - - it('should aes-128-ofb encrypt: ' + inputs[i], function() { - // encrypt - var cipher = CIPHER.createCipher('AES-OFB', key); - cipher.start({iv: iv}); - cipher.update(UTIL.createBuffer(input)); - cipher.finish(); - ASSERT.equal(cipher.output.toHex(), outputs[i]); - }); - - it('should aes-128-ofb decrypt: ' + outputs[i], function() { - // decrypt - var cipher = CIPHER.createDecipher('AES-OFB', key); - cipher.start({iv: iv}); - cipher.update(UTIL.createBuffer(output)); - cipher.finish(); - var out = (i !== 1) ? - cipher.output.toHex() : cipher.output.getBytes(); - ASSERT.equal(out, inputs[i]); - }); - - it('should aes-128-ofb encrypt (one byte at a time): ' + inputs[i], function() { - // encrypt - var cipher = CIPHER.createCipher('AES-OFB', key); - cipher.start({iv: iv}); - var input_ = UTIL.createBuffer(input); - var out = UTIL.createBuffer(); - while(input_.length() > 0) { - cipher.update(UTIL.createBuffer(input_.getBytes(1))); - ASSERT.equal(cipher.output.length(), 1); - out.putByte(cipher.output.getByte()); - } - cipher.finish(); - ASSERT.equal(out.toHex(), outputs[i]); - }); - - it('should aes-128-ofb decrypt (one byte at a time): ' + outputs[i], function() { - // decrypt - var cipher = CIPHER.createDecipher('AES-OFB', key); - cipher.start({iv: iv}); - var output_ = UTIL.createBuffer(output); - var out = UTIL.createBuffer(); - while(output_.length() > 0) { - cipher.update(UTIL.createBuffer(output_.getBytes(1))); - ASSERT.equal(cipher.output.length(), 1); - out.putByte(cipher.output.getByte()); - } - cipher.finish(); - out = (i !== 1) ? out.toHex() : out.getBytes(); - ASSERT.equal(out, inputs[i]); - }); - })(i); - } - })(); - - // AES-192-OFB - (function() { - var keys = [ - '8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b', - '8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b', - '8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b', - '8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b' - ]; - - var ivs = [ - '000102030405060708090A0B0C0D0E0F', - 'A609B38DF3B1133DDDFF2718BA09565E', - '52EF01DA52602FE0975F78AC84BF8A50', - 'BD5286AC63AABD7EB067AC54B553F71D' - ]; - - var inputs = [ - '6bc1bee22e409f96e93d7e117393172a', - 'ae2d8a571e03ac9c9eb76fac45af8e51', - '30c81c46a35ce411e5fbc1191a0a52ef', - 'f69f2445df4f9b17ad2b417be66c3710' - ]; - - var outputs = [ - 'cdc80d6fddf18cab34c25909c99a4174', - 'fcc28b8d4c63837c09e81700c1100401', - '8d9a9aeac0f6596f559c6d4daf59a5f2', - '6d9f200857ca6c3e9cac524bd9acc92a' - ]; - - for(var i = 0; i < keys.length; ++i) { - (function(i) { - var key = UTIL.hexToBytes(keys[i]); - var iv = UTIL.hexToBytes(ivs[i]); - var input = UTIL.hexToBytes(inputs[i]); - var output = UTIL.hexToBytes(outputs[i]); - - it('should aes-192-ofb encrypt: ' + inputs[i], function() { - // encrypt - var cipher = CIPHER.createCipher('AES-OFB', key); - cipher.start({iv: iv}); - cipher.update(UTIL.createBuffer(input)); - cipher.finish(); - ASSERT.equal(cipher.output.toHex(), outputs[i]); - }); - - it('should aes-192-ofb decrypt: ' + outputs[i], function() { - // decrypt - var cipher = CIPHER.createDecipher('AES-OFB', key); - cipher.start({iv: iv}); - cipher.update(UTIL.createBuffer(output)); - cipher.finish(); - var out = cipher.output.toHex(); - ASSERT.equal(out, inputs[i]); - }); - })(i); - } - })(); - - // AES-256-OFB - (function() { - var keys = [ - '603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4', - '603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4', - '603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4', - '603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4' - ]; - - var ivs = [ - '000102030405060708090A0B0C0D0E0F', - 'B7BF3A5DF43989DD97F0FA97EBCE2F4A', - 'E1C656305ED1A7A6563805746FE03EDC', - '41635BE625B48AFC1666DD42A09D96E7' - ]; - - var inputs = [ - '6bc1bee22e409f96e93d7e117393172a', - 'ae2d8a571e03ac9c9eb76fac45af8e51', - '30c81c46a35ce411e5fbc1191a0a52ef', - 'f69f2445df4f9b17ad2b417be66c3710' - ]; - - var outputs = [ - 'dc7e84bfda79164b7ecd8486985d3860', - '4febdc6740d20b3ac88f6ad82a4fb08d', - '71ab47a086e86eedf39d1c5bba97c408', - '0126141d67f37be8538f5a8be740e484' - ]; - - for(var i = 0; i < keys.length; ++i) { - (function(i) { - var key = UTIL.hexToBytes(keys[i]); - var iv = UTIL.hexToBytes(ivs[i]); - var input = UTIL.hexToBytes(inputs[i]); - var output = UTIL.hexToBytes(outputs[i]); - - it('should aes-256-ofb encrypt: ' + inputs[i], function() { - // encrypt - var cipher = CIPHER.createCipher('AES-OFB', key); - cipher.start({iv: iv}); - cipher.update(UTIL.createBuffer(input)); - cipher.finish(); - ASSERT.equal(cipher.output.toHex(), outputs[i]); - }); - - it('should aes-256-ofb decrypt: ' + outputs[i], function() { - // decrypt - var cipher = CIPHER.createDecipher('AES-OFB', key); - cipher.start({iv: iv}); - cipher.update(UTIL.createBuffer(output)); - cipher.finish(); - var out = cipher.output.toHex(); - ASSERT.equal(out, inputs[i]); - }); - })(i); - } - })(); - - // AES-128-CTR - (function() { - var keys = [ - '2b7e151628aed2a6abf7158809cf4f3c', - '00000000000000000000000000000000', - '2b7e151628aed2a6abf7158809cf4f3c' - ]; - - var ivs = [ - 'f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff', - '650cdb80ff9fc758342d2bd99ee2abcf', - 'f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff' - ]; - - var inputs = [ - '6bc1bee22e409f96e93d7e117393172a', - 'This is a 48-byte message (exactly 3 AES blocks)', - '6bc1be' - ]; - - var outputs = [ - '874d6191b620e3261bef6864990db6ce', - '5ede11d00e9a76ec1d5e7e811ea3dd1c' + - 'e09ee941210f825d35718d3282796f1c' + - '07c3f1cb424f2b365766ab5229f5b5a4', - '874d61' - ]; - - for(var i = 0; i < keys.length; ++i) { - (function(i) { - var key = UTIL.hexToBytes(keys[i]); - var iv = UTIL.hexToBytes(ivs[i]); - var input = (i !== 1) ? UTIL.hexToBytes(inputs[i]) : inputs[i]; - var output = UTIL.hexToBytes(outputs[i]); - - it('should aes-128-ctr encrypt: ' + inputs[i], function() { - // encrypt - var cipher = CIPHER.createCipher('AES-CTR', key); - cipher.start({iv: iv}); - cipher.update(UTIL.createBuffer(input)); - cipher.finish(); - ASSERT.equal(cipher.output.toHex(), outputs[i]); - }); - - it('should aes-128-ctr decrypt: ' + outputs[i], function() { - // decrypt - var cipher = CIPHER.createDecipher('AES-CTR', key); - cipher.start({iv: iv}); - cipher.update(UTIL.createBuffer(output)); - cipher.finish(); - var out = (i !== 1) ? - cipher.output.toHex() : cipher.output.getBytes(); - ASSERT.equal(out, inputs[i]); - }); - - it('should aes-128-ctr encrypt (one byte at a time): ' + inputs[i], function() { - // encrypt - var cipher = CIPHER.createCipher('AES-CTR', key); - cipher.start({iv: iv}); - var input_ = UTIL.createBuffer(input); - var out = UTIL.createBuffer(); - while(input_.length() > 0) { - cipher.update(UTIL.createBuffer(input_.getBytes(1))); - ASSERT.equal(cipher.output.length(), 1); - out.putByte(cipher.output.getByte()); - } - cipher.finish(); - ASSERT.equal(out.toHex(), outputs[i]); - }); - - it('should aes-128-ctr decrypt (one byte at a time): ' + outputs[i], function() { - // decrypt - var cipher = CIPHER.createDecipher('AES-CTR', key); - cipher.start({iv: iv}); - var output_ = UTIL.createBuffer(output); - var out = UTIL.createBuffer(); - while(output_.length() > 0) { - cipher.update(UTIL.createBuffer(output_.getBytes(1))); - ASSERT.equal(cipher.output.length(), 1); - out.putByte(cipher.output.getByte()); - } - cipher.finish(); - out = (i !== 1) ? out.toHex() : out.getBytes(); - ASSERT.equal(out, inputs[i]); - }); - })(i); - } - })(); - - // AES-192-CTR - (function() { - var keys = [ - '8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b' - ]; - - var ivs = [ - 'f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff' - ]; - - var inputs = [ - '6bc1bee22e409f96e93d7e117393172a' + - 'ae2d8a571e03ac9c9eb76fac45af8e51' + - '30c81c46a35ce411e5fbc1191a0a52ef' + - 'f69f2445df4f9b17ad2b417be66c3710' - ]; - - var outputs = [ - '1abc932417521ca24f2b0459fe7e6e0b' + - '090339ec0aa6faefd5ccc2c6f4ce8e94' + - '1e36b26bd1ebc670d1bd1d665620abf7' + - '4f78a7f6d29809585a97daec58c6b050' - ]; - - for(var i = 0; i < keys.length; ++i) { - (function(i) { - var key = UTIL.hexToBytes(keys[i]); - var iv = UTIL.hexToBytes(ivs[i]); - var input = UTIL.hexToBytes(inputs[i]); - var output = UTIL.hexToBytes(outputs[i]); - - it('should aes-192-ctr encrypt: ' + inputs[i], function() { - // encrypt - var cipher = CIPHER.createCipher('AES-CTR', key); - cipher.start({iv: iv}); - cipher.update(UTIL.createBuffer(input)); - cipher.finish(); - ASSERT.equal(cipher.output.toHex(), outputs[i]); - }); - - it('should aes-192-ctr decrypt: ' + outputs[i], function() { - // decrypt - var cipher = CIPHER.createDecipher('AES-CTR', key); - cipher.start({iv: iv}); - cipher.update(UTIL.createBuffer(output)); - cipher.finish(); - var out = cipher.output.toHex(); - ASSERT.equal(out, inputs[i]); - }); - })(i); - } - })(); - - // AES-256-CTR - (function() { - var keys = [ - '603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4' - ]; - - var ivs = [ - 'f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff' - ]; - - var inputs = [ - '6bc1bee22e409f96e93d7e117393172a' + - 'ae2d8a571e03ac9c9eb76fac45af8e51' + - '30c81c46a35ce411e5fbc1191a0a52ef' + - 'f69f2445df4f9b17ad2b417be66c3710' - ]; - - var outputs = [ - '601ec313775789a5b7a7f504bbf3d228' + - 'f443e3ca4d62b59aca84e990cacaf5c5' + - '2b0930daa23de94ce87017ba2d84988d' + - 'dfc9c58db67aada613c2dd08457941a6' - ]; - - for(var i = 0; i < keys.length; ++i) { - (function(i) { - var key = UTIL.hexToBytes(keys[i]); - var iv = UTIL.hexToBytes(ivs[i]); - var input = UTIL.hexToBytes(inputs[i]); - var output = UTIL.hexToBytes(outputs[i]); - - it('should aes-256-ctr encrypt: ' + inputs[i], function() { - // encrypt - var cipher = CIPHER.createCipher('AES-CTR', key); - cipher.start({iv: iv}); - cipher.update(UTIL.createBuffer(input)); - cipher.finish(); - ASSERT.equal(cipher.output.toHex(), outputs[i]); - }); - - it('should aes-256-ctr decrypt: ' + outputs[i], function() { - // decrypt - var cipher = CIPHER.createDecipher('AES-CTR', key); - cipher.start({iv: iv}); - cipher.update(UTIL.createBuffer(output)); - cipher.finish(); - var out = cipher.output.toHex(); - ASSERT.equal(out, inputs[i]); - }); - })(i); - } - })(); - - // AES-128-GCM - (function() { - var keys = [ - '00000000000000000000000000000000', - '00000000000000000000000000000000', - 'feffe9928665731c6d6a8f9467308308', - 'feffe9928665731c6d6a8f9467308308', - 'feffe9928665731c6d6a8f9467308308', - 'feffe9928665731c6d6a8f9467308308', - '00000000000000000000000000000000' - ]; - - var ivs = [ - '000000000000000000000000', - '000000000000000000000000', - 'cafebabefacedbaddecaf888', - 'cafebabefacedbaddecaf888', - 'cafebabefacedbad', - '9313225df88406e555909c5aff5269aa' + - '6a7a9538534f7da1e4c303d2a318a728' + - 'c3c0c95156809539fcf0e2429a6b5254' + - '16aedbf5a0de6a57a637b39b', - '000000000000000000000000' - ]; - - var adatas = [ - '', - '', - '', - 'feedfacedeadbeeffeedfacedeadbeef' + - 'abaddad2', - 'feedfacedeadbeeffeedfacedeadbeef' + - 'abaddad2', - 'feedfacedeadbeeffeedfacedeadbeef' + - 'abaddad2', - '' - ]; - - var inputs = [ - '', - '00000000000000000000000000000000', - 'd9313225f88406e5a55909c5aff5269a' + - '86a7a9531534f7da2e4c303d8a318a72' + - '1c3c0c95956809532fcf0e2449a6b525' + - 'b16aedf5aa0de657ba637b391aafd255', - 'd9313225f88406e5a55909c5aff5269a' + - '86a7a9531534f7da2e4c303d8a318a72' + - '1c3c0c95956809532fcf0e2449a6b525' + - 'b16aedf5aa0de657ba637b39', - 'd9313225f88406e5a55909c5aff5269a' + - '86a7a9531534f7da2e4c303d8a318a72' + - '1c3c0c95956809532fcf0e2449a6b525' + - 'b16aedf5aa0de657ba637b39', - 'd9313225f88406e5a55909c5aff5269a' + - '86a7a9531534f7da2e4c303d8a318a72' + - '1c3c0c95956809532fcf0e2449a6b525' + - 'b16aedf5aa0de657ba637b39', - '0000' - ]; - - var outputs = [ - '', - '0388dace60b6a392f328c2b971b2fe78', - '42831ec2217774244b7221b784d0d49c' + - 'e3aa212f2c02a4e035c17e2329aca12e' + - '21d514b25466931c7d8f6a5aac84aa05' + - '1ba30b396a0aac973d58e091473f5985', - '42831ec2217774244b7221b784d0d49c' + - 'e3aa212f2c02a4e035c17e2329aca12e' + - '21d514b25466931c7d8f6a5aac84aa05' + - '1ba30b396a0aac973d58e091', - '61353b4c2806934a777ff51fa22a4755' + - '699b2a714fcdc6f83766e5f97b6c7423' + - '73806900e49f24b22b097544d4896b42' + - '4989b5e1ebac0f07c23f4598', - '8ce24998625615b603a033aca13fb894' + - 'be9112a5c3a211a8ba262a3cca7e2ca7' + - '01e4a9a4fba43c90ccdcb281d48c7c6f' + - 'd62875d2aca417034c34aee5', - '0388' - ]; - - var tags = [ - '58e2fccefa7e3061367f1d57a4e7455a', - 'ab6e47d42cec13bdf53a67b21257bddf', - '4d5c2af327cd64a62cf35abd2ba6fab4', - '5bc94fbc3221a5db94fae95ae7121a47', - '3612d2e79e3b0785561be14aaca2fccb', - '619cc5aefffe0bfa462af43c1699d050', - '93dcdd26f79ec1dd9bff57204d9b33f5' - ]; - - for(var i = 0; i < keys.length; ++i) { - (function(i) { - var key = UTIL.hexToBytes(keys[i]); - var iv = UTIL.hexToBytes(ivs[i]); - var adata = UTIL.hexToBytes(adatas[i]); - var input = UTIL.hexToBytes(inputs[i]); - var output = UTIL.hexToBytes(outputs[i]); - - it('should aes-128-gcm encrypt: ' + inputs[i], function() { - // encrypt - var cipher = CIPHER.createCipher('AES-GCM', key); - cipher.start({iv: iv, additionalData: adata}); - cipher.update(UTIL.createBuffer(input)); - cipher.finish(); - ASSERT.equal(cipher.output.toHex(), outputs[i]); - ASSERT.equal(cipher.mode.tag.toHex(), tags[i]); - }); - - it('should aes-128-gcm decrypt: ' + outputs[i], function() { - // decrypt - var cipher = CIPHER.createDecipher('AES-GCM', key); - cipher.start({ - iv: iv, - additionalData: adata, - tag: UTIL.hexToBytes(tags[i]) - }); - cipher.update(UTIL.createBuffer(output)); - var pass = cipher.finish(); - ASSERT.equal(cipher.mode.tag.toHex(), tags[i]); - ASSERT.equal(pass, true); - ASSERT.equal(cipher.output.toHex(), inputs[i]); - }); - - it('should aes-128-gcm encrypt (one byte at a time): ' + inputs[i], function() { - // encrypt - var cipher = CIPHER.createCipher('AES-GCM', key); - cipher.start({iv: iv, additionalData: adata}); - var input_ = UTIL.createBuffer(input); - var out = UTIL.createBuffer(); - while(input_.length() > 0) { - cipher.update(UTIL.createBuffer(input_.getBytes(1))); - ASSERT.equal(cipher.output.length(), 1); - out.putByte(cipher.output.getByte()); - } - cipher.finish(); - ASSERT.equal(out.toHex(), outputs[i]); - ASSERT.equal(cipher.mode.tag.toHex(), tags[i]); - }); - })(i); - } - })(); - - // AES-192-GCM - (function() { - var keys = [ - '00000000000000000000000000000000' + - '0000000000000000', - '00000000000000000000000000000000' + - '0000000000000000', - 'feffe9928665731c6d6a8f9467308308' + - 'feffe9928665731c', - 'feffe9928665731c6d6a8f9467308308' + - 'feffe9928665731c', - 'feffe9928665731c6d6a8f9467308308' + - 'feffe9928665731c', - 'feffe9928665731c6d6a8f9467308308' + - 'feffe9928665731c' - ]; - - var ivs = [ - '000000000000000000000000', - '000000000000000000000000', - 'cafebabefacedbaddecaf888', - 'cafebabefacedbaddecaf888', - 'cafebabefacedbad', - '9313225df88406e555909c5aff5269aa' + - '6a7a9538534f7da1e4c303d2a318a728' + - 'c3c0c95156809539fcf0e2429a6b5254' + - '16aedbf5a0de6a57a637b39b' - ]; - - var adatas = [ - '', - '', - '', - 'feedfacedeadbeeffeedfacedeadbeef' + - 'abaddad2', - 'feedfacedeadbeeffeedfacedeadbeef' + - 'abaddad2', - 'feedfacedeadbeeffeedfacedeadbeef' + - 'abaddad2' - ]; - - var inputs = [ - '', - '00000000000000000000000000000000', - 'd9313225f88406e5a55909c5aff5269a' + - '86a7a9531534f7da2e4c303d8a318a72' + - '1c3c0c95956809532fcf0e2449a6b525' + - 'b16aedf5aa0de657ba637b391aafd255', - 'd9313225f88406e5a55909c5aff5269a' + - '86a7a9531534f7da2e4c303d8a318a72' + - '1c3c0c95956809532fcf0e2449a6b525' + - 'b16aedf5aa0de657ba637b39', - 'd9313225f88406e5a55909c5aff5269a' + - '86a7a9531534f7da2e4c303d8a318a72' + - '1c3c0c95956809532fcf0e2449a6b525' + - 'b16aedf5aa0de657ba637b39', - 'd9313225f88406e5a55909c5aff5269a' + - '86a7a9531534f7da2e4c303d8a318a72' + - '1c3c0c95956809532fcf0e2449a6b525' + - 'b16aedf5aa0de657ba637b39' - ]; - - var outputs = [ - '', - '98e7247c07f0fe411c267e4384b0f600', - '3980ca0b3c00e841eb06fac4872a2757' + - '859e1ceaa6efd984628593b40ca1e19c' + - '7d773d00c144c525ac619d18c84a3f47' + - '18e2448b2fe324d9ccda2710acade256', - '3980ca0b3c00e841eb06fac4872a2757' + - '859e1ceaa6efd984628593b40ca1e19c' + - '7d773d00c144c525ac619d18c84a3f47' + - '18e2448b2fe324d9ccda2710', - '0f10f599ae14a154ed24b36e25324db8' + - 'c566632ef2bbb34f8347280fc4507057' + - 'fddc29df9a471f75c66541d4d4dad1c9' + - 'e93a19a58e8b473fa0f062f7', - 'd27e88681ce3243c4830165a8fdcf9ff' + - '1de9a1d8e6b447ef6ef7b79828666e45' + - '81e79012af34ddd9e2f037589b292db3' + - 'e67c036745fa22e7e9b7373b' - ]; - - var tags = [ - 'cd33b28ac773f74ba00ed1f312572435', - '2ff58d80033927ab8ef4d4587514f0fb', - '9924a7c8587336bfb118024db8674a14', - '2519498e80f1478f37ba55bd6d27618c', - '65dcc57fcf623a24094fcca40d3533f8', - 'dcf566ff291c25bbb8568fc3d376a6d9' - ]; - - for(var i = 0; i < keys.length; ++i) { - (function(i) { - var key = UTIL.hexToBytes(keys[i]); - var iv = UTIL.hexToBytes(ivs[i]); - var adata = UTIL.hexToBytes(adatas[i]); - var input = UTIL.hexToBytes(inputs[i]); - var output = UTIL.hexToBytes(outputs[i]); - - it('should aes-128-gcm encrypt: ' + inputs[i], function() { - // encrypt - var cipher = CIPHER.createCipher('AES-GCM', key); - cipher.start({iv: iv, additionalData: adata}); - cipher.update(UTIL.createBuffer(input)); - cipher.finish(); - ASSERT.equal(cipher.output.toHex(), outputs[i]); - ASSERT.equal(cipher.mode.tag.toHex(), tags[i]); - }); - - it('should aes-128-gcm decrypt: ' + outputs[i], function() { - // decrypt - var cipher = CIPHER.createDecipher('AES-GCM', key); - cipher.start({ - iv: iv, - additionalData: adata, - tag: UTIL.hexToBytes(tags[i]) - }); - cipher.update(UTIL.createBuffer(output)); - var pass = cipher.finish(); - ASSERT.equal(cipher.mode.tag.toHex(), tags[i]); - ASSERT.equal(pass, true); - ASSERT.equal(cipher.output.toHex(), inputs[i]); - }); - })(i); - } - })(); - - // AES-256-GCM - (function() { - var keys = [ - '00000000000000000000000000000000' + - '00000000000000000000000000000000', - '00000000000000000000000000000000' + - '00000000000000000000000000000000', - 'feffe9928665731c6d6a8f9467308308' + - 'feffe9928665731c6d6a8f9467308308', - 'feffe9928665731c6d6a8f9467308308' + - 'feffe9928665731c6d6a8f9467308308', - 'feffe9928665731c6d6a8f9467308308' + - 'feffe9928665731c6d6a8f9467308308', - 'feffe9928665731c6d6a8f9467308308' + - 'feffe9928665731c6d6a8f9467308308' - ]; - - var ivs = [ - '000000000000000000000000', - '000000000000000000000000', - 'cafebabefacedbaddecaf888', - 'cafebabefacedbaddecaf888', - 'cafebabefacedbad', - '9313225df88406e555909c5aff5269aa' + - '6a7a9538534f7da1e4c303d2a318a728' + - 'c3c0c95156809539fcf0e2429a6b5254' + - '16aedbf5a0de6a57a637b39b' - ]; - - var adatas = [ - '', - '', - '', - 'feedfacedeadbeeffeedfacedeadbeef' + - 'abaddad2', - 'feedfacedeadbeeffeedfacedeadbeef' + - 'abaddad2', - 'feedfacedeadbeeffeedfacedeadbeef' + - 'abaddad2' - ]; - - var inputs = [ - '', - '00000000000000000000000000000000', - 'd9313225f88406e5a55909c5aff5269a' + - '86a7a9531534f7da2e4c303d8a318a72' + - '1c3c0c95956809532fcf0e2449a6b525' + - 'b16aedf5aa0de657ba637b391aafd255', - 'd9313225f88406e5a55909c5aff5269a' + - '86a7a9531534f7da2e4c303d8a318a72' + - '1c3c0c95956809532fcf0e2449a6b525' + - 'b16aedf5aa0de657ba637b39', - 'd9313225f88406e5a55909c5aff5269a' + - '86a7a9531534f7da2e4c303d8a318a72' + - '1c3c0c95956809532fcf0e2449a6b525' + - 'b16aedf5aa0de657ba637b39', - 'd9313225f88406e5a55909c5aff5269a' + - '86a7a9531534f7da2e4c303d8a318a72' + - '1c3c0c95956809532fcf0e2449a6b525' + - 'b16aedf5aa0de657ba637b39' - ]; - - var outputs = [ - '', - 'cea7403d4d606b6e074ec5d3baf39d18', - '522dc1f099567d07f47f37a32a84427d' + - '643a8cdcbfe5c0c97598a2bd2555d1aa' + - '8cb08e48590dbb3da7b08b1056828838' + - 'c5f61e6393ba7a0abcc9f662898015ad', - '522dc1f099567d07f47f37a32a84427d' + - '643a8cdcbfe5c0c97598a2bd2555d1aa' + - '8cb08e48590dbb3da7b08b1056828838' + - 'c5f61e6393ba7a0abcc9f662', - 'c3762df1ca787d32ae47c13bf19844cb' + - 'af1ae14d0b976afac52ff7d79bba9de0' + - 'feb582d33934a4f0954cc2363bc73f78' + - '62ac430e64abe499f47c9b1f', - '5a8def2f0c9e53f1f75d7853659e2a20' + - 'eeb2b22aafde6419a058ab4f6f746bf4' + - '0fc0c3b780f244452da3ebf1c5d82cde' + - 'a2418997200ef82e44ae7e3f' - ]; - - var tags = [ - '530f8afbc74536b9a963b4f1c4cb738b', - 'd0d1c8a799996bf0265b98b5d48ab919', - 'b094dac5d93471bdec1a502270e3cc6c', - '76fc6ece0f4e1768cddf8853bb2d551b', - '3a337dbf46a792c45e454913fe2ea8f2', - 'a44a8266ee1c8eb0c8b5d4cf5ae9f19a' - ]; - - for(var i = 0; i < keys.length; ++i) { - (function(i) { - var key = UTIL.hexToBytes(keys[i]); - var iv = UTIL.hexToBytes(ivs[i]); - var adata = UTIL.hexToBytes(adatas[i]); - var input = UTIL.hexToBytes(inputs[i]); - var output = UTIL.hexToBytes(outputs[i]); - - it('should aes-128-gcm encrypt: ' + inputs[i], function() { - // encrypt - var cipher = CIPHER.createCipher('AES-GCM', key); - cipher.start({iv: iv, additionalData: adata}); - cipher.update(UTIL.createBuffer(input)); - cipher.finish(); - ASSERT.equal(cipher.output.toHex(), outputs[i]); - ASSERT.equal(cipher.mode.tag.toHex(), tags[i]); - }); - - it('should aes-128-gcm decrypt: ' + outputs[i], function() { - // decrypt - var cipher = CIPHER.createDecipher('AES-GCM', key); - cipher.start({ - iv: iv, - additionalData: adata, - tag: UTIL.hexToBytes(tags[i]) - }); - cipher.update(UTIL.createBuffer(output)); - var pass = cipher.finish(); - ASSERT.equal(cipher.mode.tag.toHex(), tags[i]); - ASSERT.equal(pass, true); - ASSERT.equal(cipher.output.toHex(), inputs[i]); - }); - })(i); - } - })(); - }); -} - -// check for AMD -var forge = {}; -if(typeof define === 'function') { - define([ - 'forge/cipher', - 'forge/aes', - 'forge/util' - ], function(CIPHER, AES, UTIL) { - Tests( - // Global provided by test harness - ASSERT, - CIPHER(forge), - AES(forge), - UTIL(forge) - ); - }); -} else if(typeof module === 'object' && module.exports) { - // assume NodeJS - Tests( - require('assert'), - require('../../js/cipher')(forge), - require('../../js/aes')(forge), - require('../../js/util')(forge)); -} - -})(); diff --git a/alarm/node_modules/node-forge/nodejs/test/asn1.js b/alarm/node_modules/node-forge/nodejs/test/asn1.js deleted file mode 100644 index 7d0880e..0000000 --- a/alarm/node_modules/node-forge/nodejs/test/asn1.js +++ /dev/null @@ -1,262 +0,0 @@ -(function() { - -function Tests(ASSERT, ASN1, UTIL) { - describe('asn1', function() { - // TODO: add more ASN.1 coverage - - it('should convert an OID to DER', function() { - ASSERT.equal(ASN1.oidToDer('1.2.840.113549').toHex(), '2a864886f70d'); - }); - - it('should convert an OID from DER', function() { - var der = UTIL.hexToBytes('2a864886f70d'); - ASSERT.equal(ASN1.derToOid(der), '1.2.840.113549'); - }); - - it('should convert INTEGER 0 to DER', function() { - ASSERT.equal(ASN1.integerToDer(0).toHex(), '00'); - }); - - it('should convert INTEGER 1 to DER', function() { - ASSERT.equal(ASN1.integerToDer(1).toHex(), '01'); - }); - - it('should convert INTEGER 127 to DER', function() { - ASSERT.equal(ASN1.integerToDer(127).toHex(), '7f'); - }); - - it('should convert INTEGER 128 to DER', function() { - ASSERT.equal(ASN1.integerToDer(128).toHex(), '0080'); - }); - - it('should convert INTEGER 256 to DER', function() { - ASSERT.equal(ASN1.integerToDer(256).toHex(), '0100'); - }); - - it('should convert INTEGER -128 to DER', function() { - ASSERT.equal(ASN1.integerToDer(-128).toHex(), '80'); - }); - - it('should convert INTEGER -129 to DER', function() { - ASSERT.equal(ASN1.integerToDer(-129).toHex(), 'ff7f'); - }); - - it('should convert INTEGER 32768 to DER', function() { - ASSERT.equal(ASN1.integerToDer(32768).toHex(), '008000'); - }); - - it('should convert INTEGER -32768 to DER', function() { - ASSERT.equal(ASN1.integerToDer(-32768).toHex(), '8000'); - }); - - it('should convert INTEGER -32769 to DER', function() { - ASSERT.equal(ASN1.integerToDer(-32769).toHex(), 'ff7fff'); - }); - - it('should convert INTEGER 8388608 to DER', function() { - ASSERT.equal(ASN1.integerToDer(8388608).toHex(), '00800000'); - }); - - it('should convert INTEGER -8388608 to DER', function() { - ASSERT.equal(ASN1.integerToDer(-8388608).toHex(), '800000'); - }); - - it('should convert INTEGER -8388609 to DER', function() { - ASSERT.equal(ASN1.integerToDer(-8388609).toHex(), 'ff7fffff'); - }); - - it('should convert INTEGER 2147483647 to DER', function() { - ASSERT.equal(ASN1.integerToDer(2147483647).toHex(), '7fffffff'); - }); - - it('should convert INTEGER -2147483648 to DER', function() { - ASSERT.equal(ASN1.integerToDer(-2147483648).toHex(), '80000000'); - }); - - it('should convert INTEGER 0 from DER', function() { - var der = UTIL.hexToBytes('00'); - ASSERT.equal(ASN1.derToInteger(der), 0); - }); - - it('should convert INTEGER 1 from DER', function() { - var der = UTIL.hexToBytes('01'); - ASSERT.equal(ASN1.derToInteger(der), 1); - }); - - it('should convert INTEGER 127 from DER', function() { - var der = UTIL.hexToBytes('7f'); - ASSERT.equal(ASN1.derToInteger(der), 127); - }); - - it('should convert INTEGER 128 from DER', function() { - var der = UTIL.hexToBytes('0080'); - ASSERT.equal(ASN1.derToInteger(der), 128); - }); - - it('should convert INTEGER 256 from DER', function() { - var der = UTIL.hexToBytes('0100'); - ASSERT.equal(ASN1.derToInteger(der), 256); - }); - - it('should convert INTEGER -128 from DER', function() { - var der = UTIL.hexToBytes('80'); - ASSERT.equal(ASN1.derToInteger(der), -128); - }); - - it('should convert INTEGER -129 from DER', function() { - var der = UTIL.hexToBytes('ff7f'); - ASSERT.equal(ASN1.derToInteger(der), -129); - }); - - it('should convert INTEGER 32768 from DER', function() { - var der = UTIL.hexToBytes('008000'); - ASSERT.equal(ASN1.derToInteger(der), 32768); - }); - - it('should convert INTEGER -32768 from DER', function() { - var der = UTIL.hexToBytes('8000'); - ASSERT.equal(ASN1.derToInteger(der), -32768); - }); - - it('should convert INTEGER -32769 from DER', function() { - var der = UTIL.hexToBytes('ff7fff'); - ASSERT.equal(ASN1.derToInteger(der), -32769); - }); - - it('should convert INTEGER 8388608 from DER', function() { - var der = UTIL.hexToBytes('00800000'); - ASSERT.equal(ASN1.derToInteger(der), 8388608); - }); - - it('should convert INTEGER -8388608 from DER', function() { - var der = UTIL.hexToBytes('800000'); - ASSERT.equal(ASN1.derToInteger(der), -8388608); - }); - - it('should convert INTEGER -8388609 from DER', function() { - var der = UTIL.hexToBytes('ff7fffff'); - ASSERT.equal(ASN1.derToInteger(der), -8388609); - }); - - it('should convert INTEGER 2147483647 from DER', function() { - var der = UTIL.hexToBytes('7fffffff'); - ASSERT.equal(ASN1.derToInteger(der), 2147483647); - }); - - it('should convert INTEGER -2147483648 from DER', function() { - var der = UTIL.hexToBytes('80000000'); - ASSERT.equal(ASN1.derToInteger(der), -2147483648); - }); - - (function() { - var tests = [{ - in: '20110223123400', - out: 1298464440000 - }, { - in: '20110223123400.1', - out: 1298464440100 - }, { - in: '20110223123400.123', - out: 1298464440123 - }]; - for(var i = 0; i < tests.length; ++i) { - var test = tests[i]; - it('should convert local generalized time "' + test.in + '" to a Date', function() { - var d = ASN1.generalizedTimeToDate(test.in); - var localOffset = d.getTimezoneOffset() * 60000; - ASSERT.equal(d.getTime(), test.out + localOffset); - }); - } - })(); - - (function() { - var tests = [{ - in: '20110223123400Z', // Wed Feb 23 12:34:00.000 UTC 2011 - out: 1298464440000 - }, { - in: '20110223123400.1Z', // Wed Feb 23 12:34:00.100 UTC 2011 - out: 1298464440100 - }, { - in: '20110223123400.123Z', // Wed Feb 23 12:34:00.123 UTC 2011 - out: 1298464440123 - }, { - in: '20110223123400+0200', // Wed Feb 23 10:34:00.000 UTC 2011 - out: 1298457240000 - }, { - in: '20110223123400.1+0200', // Wed Feb 23 10:34:00.100 UTC 2011 - out: 1298457240100 - }, { - in: '20110223123400.123+0200', // Wed Feb 23 10:34:00.123 UTC 2011 - out: 1298457240123 - }, { - in: '20110223123400-0200', // Wed Feb 23 14:34:00.000 UTC 2011 - out: 1298471640000 - }, { - in: '20110223123400.1-0200', // Wed Feb 23 14:34:00.100 UTC 2011 - out: 1298471640100 - }, { - in: '20110223123400.123-0200', // Wed Feb 23 14:34:00.123 UTC 2011 - out: 1298471640123 - }]; - for(var i = 0; i < tests.length; ++i) { - var test = tests[i]; - it('should convert utc generalized time "' + test.in + '" to a Date', function() { - var d = ASN1.generalizedTimeToDate(test.in); - ASSERT.equal(d.getTime(), test.out); - }); - } - })(); - - (function() { - var tests = [{ - in: '1102231234Z', // Wed Feb 23 12:34:00 UTC 2011 - out: 1298464440000 - }, { - in: '1102231234+0200', // Wed Feb 23 10:34:00 UTC 2011 - out: 1298457240000 - }, { - in: '1102231234-0200', // Wed Feb 23 14:34:00 UTC 2011 - out: 1298471640000 - }, { - in: '110223123456Z', // Wed Feb 23 12:34:56 UTC 2011 - out: 1298464496000 - }, { - in: '110223123456+0200', // Wed Feb 23 10:34:56 UTC 2011 - out: 1298457296000 - }, { - in: '110223123456-0200', // Wed Feb 23 14:34:56 UTC 2011 - out: 1298471696000 - }]; - for(var i = 0; i < tests.length; ++i) { - var test = tests[i]; - it('should convert utc time "' + test.in + '" to a Date', function() { - var d = ASN1.utcTimeToDate(test.in); - ASSERT.equal(d.getTime(), test.out); - }); - } - })(); - }); -} - -// check for AMD -if(typeof define === 'function') { - define([ - 'forge/asn1', - 'forge/util' - ], function(ASN1, UTIL) { - Tests( - // Global provided by test harness - ASSERT, - ASN1(), - UTIL() - ); - }); -} else if(typeof module === 'object' && module.exports) { - // assume NodeJS - Tests( - require('assert'), - require('../../js/asn1')(), - require('../../js/util')()); -} - -})(); diff --git a/alarm/node_modules/node-forge/nodejs/test/browser.js b/alarm/node_modules/node-forge/nodejs/test/browser.js deleted file mode 100644 index a96b2d6..0000000 --- a/alarm/node_modules/node-forge/nodejs/test/browser.js +++ /dev/null @@ -1,41 +0,0 @@ -var server = require('../server'); -var grunt = require('grunt'); - -describe('browser', function() { - it('should run tests', function(done) { - this.timeout(60 * 1000 * 5); - - return server.main(function(err, info) { - if(err) { - return done(err); - } - - grunt.initConfig({ - mocha: { - all: { - options: { - reporter: 'List', - urls: ['http://localhost:' + info.port + '/index.html'] - } - } - } - }); - - grunt.loadNpmTasks('grunt-mocha'); - - grunt.registerInitTask('default', function() { - grunt.task.run(['mocha']); - }); - grunt.tasks(['default'], { - //debug: true - }, function() { - if(err) { - return done(err); - } - // finish immediately - done(null); - return info.server.close(); - }); - }); - }); -}); diff --git a/alarm/node_modules/node-forge/nodejs/test/csr.js b/alarm/node_modules/node-forge/nodejs/test/csr.js deleted file mode 100644 index 340c09f..0000000 --- a/alarm/node_modules/node-forge/nodejs/test/csr.js +++ /dev/null @@ -1,148 +0,0 @@ -(function() { - -function Tests(ASSERT, PKI) { - var _pem = { - privateKey: '-----BEGIN RSA PRIVATE KEY-----\r\n' + - 'MIICXQIBAAKBgQDL0EugUiNGMWscLAVM0VoMdhDZEJOqdsUMpx9U0YZI7szokJqQ\r\n' + - 'NIwokiQ6EonNnWSMlIvy46AhnlRYn+ezeTeU7eMGTkP3VF29vXBo+dLq5e+8VyAy\r\n' + - 'Q3FzM1wI4ts4hRACF8w6mqygXQ7i/SDu8/rXqRGtvnM+z0MYDdKo80efzwIDAQAB\r\n' + - 'AoGAIzkGONi5G+JifmXlLJdplom486p3upf4Ce2/7mqfaG9MnkyPSairKD/JXvfh\r\n' + - 'NNWkkN8DKKDKBcVVElPgORYT0qwrWc7ueLBMUCbRXb1ZyfEulimG0R3kjUh7NYau\r\n' + - 'DaIkVgfykXGSQMZx8FoaT6L080zd+0emKDDYRrb+/kgJNJECQQDoUZoiC2K/DWNY\r\n' + - 'h3/ppZ0ane2y4SBmJUHJVMPQ2CEgxsrJTxet668ckNCKaOP/3VFPoWC41f17DvKq\r\n' + - 'noYINNntAkEA4JbZBZBVUrQFhHlrpXT4jzqtO2RlKZzEq8qmFZfEErxOT1WMyyCi\r\n' + - 'lAQ5gUKardo1Kf0omC8Xq/uO9ZYdED55KwJBALs6cJ65UFaq4oLJiQPzLd7yokuE\r\n' + - 'dcj8g71PLBTW6jPxIiMFNA89nz3FU9wIVp+xbMNhSoMMKqIPVPC+m0Rn260CQQDA\r\n' + - 'I83fWK/mZWUjBM33a68KumRiH238v8XyQxj7+C8i6D8G2GXvkigFAehAkb7LZZd+\r\n' + - 'KLuGFyPlWv3fVWHf99KpAkBQFKk3MRMl6IGJZUEFQe4l5whm8LkGU4acSqv9B3xt\r\n' + - 'qROkCrsFrMPqjuuzEmyHoQZ64r2PLJg7FOuyhBnQUOt4\r\n' + - '-----END RSA PRIVATE KEY-----\r\n', - publicKey: '-----BEGIN PUBLIC KEY-----\r\n' + - 'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDL0EugUiNGMWscLAVM0VoMdhDZ\r\n' + - 'EJOqdsUMpx9U0YZI7szokJqQNIwokiQ6EonNnWSMlIvy46AhnlRYn+ezeTeU7eMG\r\n' + - 'TkP3VF29vXBo+dLq5e+8VyAyQ3FzM1wI4ts4hRACF8w6mqygXQ7i/SDu8/rXqRGt\r\n' + - 'vnM+z0MYDdKo80efzwIDAQAB\r\n' + - '-----END PUBLIC KEY-----\r\n' - }; - - describe('csr', function() { - it('should generate a certification request', function() { - var keys = { - privateKey: PKI.privateKeyFromPem(_pem.privateKey), - publicKey: PKI.publicKeyFromPem(_pem.publicKey) - }; - var csr = PKI.createCertificationRequest(); - csr.publicKey = keys.publicKey; - csr.setSubject([{ - name: 'commonName', - value: 'example.org' - }, { - name: 'countryName', - value: 'US' - }, { - shortName: 'ST', - value: 'Virginia' - }, { - name: 'localityName', - value: 'Blacksburg' - }, { - name: 'organizationName', - value: 'Test' - }, { - shortName: 'OU', - value: 'Test' - }]); - // add optional attributes - csr.setAttributes([{ - name: 'challengePassword', - value: 'password' - }, { - name: 'unstructuredName', - value: 'My company' - }, { - name: 'extensionRequest', - extensions: [{ - name: 'subjectAltName', - altNames: [{ - // type 2 is DNS - type: 2, - value: 'test.domain.com' - }, { - type: 2, - value: 'other.domain.com' - }, { - type: 2, - value: 'www.domain.net' - }] - }] - }]); - - // sign certification request - csr.sign(keys.privateKey); - - var pem = PKI.certificationRequestToPem(csr); - csr = PKI.certificationRequestFromPem(pem); - ASSERT.ok(csr.getAttribute({name: 'extensionRequest'})); - ASSERT.equal(csr.getAttribute({name: 'extensionRequest'}).extensions[0].name, 'subjectAltName'); - ASSERT.deepEqual(csr.getAttribute({name: 'extensionRequest'}).extensions[0].altNames, [{ - // type 2 is DNS - type: 2, - value: 'test.domain.com' - }, { - type: 2, - value: 'other.domain.com' - }, { - type: 2, - value: 'www.domain.net' - }]); - ASSERT.ok(csr.verify()); - }); - - it('should load an OpenSSL-generated certification request', function() { - var pem = '-----BEGIN CERTIFICATE REQUEST-----\r\n' + - 'MIICdTCCAV0CAQAwMDEVMBMGA1UEAwwMTXlDb21tb25OYW1lMRcwFQYDVQQKDA5N\r\n' + - 'eU9yZ2FuaXphdGlvbjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKRU\r\n' + - 'zrAMbiiSjAYYl3PWsOrNwY0VtemgRZc0t7+3FlWp1e8uIA3KxZFZY875wo0QOvD+\r\n' + - 'AdNv5+YnokgzOi83F3T4yewBSR0TiO3Pa4tL4C7CzWnhYliC/owk5bHCV0HLkYUW\r\n' + - 'F6z7Lx3HyhoxlKmrHySSPPZRLKp7KcwxbjFc2EfhQV21I73Z1mCG6MEp7cN2qBbQ\r\n' + - 'PyOMNjAUibOWs4JJEdUjWhm86EZm9+qfgpL5tlpZCe+kXySrKTp56mMsfSOQvlol\r\n' + - 'pRO8pP9AUjaEqRikCZ745I/9W7dHNPUoyxkWV5jRDwcT7s652+L6oxtoqVOXpg28\r\n' + - 'uAL0kUZQMa8wkYUKZiMCAwEAAaAAMA0GCSqGSIb3DQEBBQUAA4IBAQCXQH+ut6tr\r\n' + - 'Z/FdIDOljrc7uh8XpFRKS3GqC/PJsEwrV7d3CX5HuWPTuPc9FU5FQ88w6evXEA0o\r\n' + - 'ijxHuydeXmdjpy433vXWo1TaRSXh1WaBMG5pW/SlGZK9/Hr1P0v7KN/KCY5nXxoQ\r\n' + - 'k3Ndg9HzGrYnRoJVXzvdQeBGwCoJFk4FH+Rxa/F03VTUU5nwx66TsL9JUp9pnbI7\r\n' + - 'MR6DIA97LnTmut8Xp0Uurw+zsS5rif9iv0BKHd7eGpNNGl0RXu8E5dbT0zD90TSa\r\n' + - 'P5WjxjvY+Udg8XZU+UwT3kcyTEFpiQdkzTIKXg0dFurfUE9XG/9aic9oMZ/IBZz9\r\n' + - 'a535a7e9RkbJ\r\n' + - '-----END CERTIFICATE REQUEST-----\r\n'; - - var csr = PKI.certificationRequestFromPem(pem); - ASSERT.equal(csr.subject.getField('CN').value, 'MyCommonName'); - ASSERT.equal(csr.subject.getField('O').value, 'MyOrganization'); - ASSERT.equal(csr.signatureOid, PKI.oids.sha1WithRSAEncryption); - ASSERT.equal(csr.publicKey.e.toString(16), '10001'); - ASSERT.equal(csr.publicKey.n.toString(16).toUpperCase(), 'A454CEB00C6E28928C06189773D6B0EACDC18D15B5E9A0459734B7BFB71655A9D5EF2E200DCAC5915963CEF9C28D103AF0FE01D36FE7E627A248333A2F371774F8C9EC01491D1388EDCF6B8B4BE02EC2CD69E1625882FE8C24E5B1C25741CB91851617ACFB2F1DC7CA1A3194A9AB1F24923CF6512CAA7B29CC316E315CD847E1415DB523BDD9D66086E8C129EDC376A816D03F238C36301489B396B3824911D5235A19BCE84666F7EA9F8292F9B65A5909EFA45F24AB293A79EA632C7D2390BE5A25A513BCA4FF40523684A918A4099EF8E48FFD5BB74734F528CB19165798D10F0713EECEB9DBE2FAA31B68A95397A60DBCB802F491465031AF3091850A6623'); - ASSERT.ok(csr.verify()); - }); - }); -} - -// check for AMD -if(typeof define === 'function') { - define([ - 'forge/pki' - ], function(PKI) { - Tests( - // Global provided by test harness - ASSERT, - PKI() - ); - }); -} else if(typeof module === 'object' && module.exports) { - // assume NodeJS - Tests( - require('assert'), - require('../../js/pki')()); -} - -})(); diff --git a/alarm/node_modules/node-forge/nodejs/test/des.js b/alarm/node_modules/node-forge/nodejs/test/des.js deleted file mode 100644 index 8be2c68..0000000 --- a/alarm/node_modules/node-forge/nodejs/test/des.js +++ /dev/null @@ -1,155 +0,0 @@ -(function() { - -function Tests(ASSERT, CIPHER, DES, UTIL) { - describe('des', function() { - // OpenSSL equivalent: - // openssl enc -des-ecb -K a1c06b381adf3651 -nosalt - it('should des-ecb encrypt: foobar', function() { - var key = new UTIL.createBuffer( - UTIL.hexToBytes('a1c06b381adf3651')); - - var cipher = CIPHER.createCipher('DES-ECB', key); - cipher.start(); - cipher.update(UTIL.createBuffer('foobar')); - cipher.finish(); - ASSERT.equal(cipher.output.toHex(), 'b705ffcf3dff06b3'); - }); - - // OpenSSL equivalent: - // openssl enc -d -des-ecb -K a1c06b381adf3651 -nosalt - it('should des-ecb decrypt: b705ffcf3dff06b3', function() { - var key = new UTIL.createBuffer( - UTIL.hexToBytes('a1c06b381adf3651')); - - var decipher = CIPHER.createDecipher('DES-ECB', key); - decipher.start(); - decipher.update(UTIL.createBuffer(UTIL.hexToBytes('b705ffcf3dff06b3'))); - decipher.finish(); - ASSERT.equal(decipher.output.getBytes(), 'foobar'); - }); - - // OpenSSL equivalent: - // openssl enc -des -K a1c06b381adf3651 -iv 818bcf76efc59662 -nosalt - it('should des-cbc encrypt: foobar', function() { - var key = new UTIL.createBuffer( - UTIL.hexToBytes('a1c06b381adf3651')); - var iv = new UTIL.createBuffer( - UTIL.hexToBytes('818bcf76efc59662')); - - var cipher = CIPHER.createCipher('DES-CBC', key); - cipher.start({iv: iv}); - cipher.update(UTIL.createBuffer('foobar')); - cipher.finish(); - ASSERT.equal(cipher.output.toHex(), '3261e5839a990454'); - }); - - // OpenSSL equivalent: - // openssl enc -d -des -K a1c06b381adf3651 -iv 818bcf76efc59662 -nosalt - it('should des-cbc decrypt: 3261e5839a990454', function() { - var key = new UTIL.createBuffer( - UTIL.hexToBytes('a1c06b381adf3651')); - var iv = new UTIL.createBuffer( - UTIL.hexToBytes('818bcf76efc59662')); - - var decipher = CIPHER.createDecipher('DES-CBC', key); - decipher.start({iv: iv}); - decipher.update(UTIL.createBuffer(UTIL.hexToBytes('3261e5839a990454'))); - decipher.finish(); - ASSERT.equal(decipher.output.getBytes(), 'foobar'); - }); - - // OpenSSL equivalent: - // openssl enc -des-ede3 -K a1c06b381adf36517e84575552777779da5e3d9f994b05b5 -nosalt - it('should 3des-ecb encrypt: foobar', function() { - var key = new UTIL.createBuffer( - UTIL.hexToBytes('a1c06b381adf36517e84575552777779da5e3d9f994b05b5')); - - var cipher = CIPHER.createCipher('3DES-ECB', key); - cipher.start(); - cipher.update(UTIL.createBuffer('foobar')); - cipher.finish(); - ASSERT.equal(cipher.output.toHex(), 'fce8b1ee8c6440d1'); - }); - - // OpenSSL equivalent: - // openssl enc -d -des-ede3 -K a1c06b381adf36517e84575552777779da5e3d9f994b05b5 -nosalt - it('should 3des-ecb decrypt: fce8b1ee8c6440d1', function() { - var key = new UTIL.createBuffer( - UTIL.hexToBytes('a1c06b381adf36517e84575552777779da5e3d9f994b05b5')); - - var decipher = CIPHER.createDecipher('3DES-ECB', key); - decipher.start(); - decipher.update(UTIL.createBuffer(UTIL.hexToBytes('fce8b1ee8c6440d1'))); - decipher.finish(); - ASSERT.equal(decipher.output.getBytes(), 'foobar'); - }); - - // OpenSSL equivalent: - // openssl enc -des3 -K a1c06b381adf36517e84575552777779da5e3d9f994b05b5 -iv 818bcf76efc59662 -nosalt - it('should 3des-cbc encrypt "foobar", restart, and encrypt "foobar,,"', function() { - var key = new UTIL.createBuffer( - UTIL.hexToBytes('a1c06b381adf36517e84575552777779da5e3d9f994b05b5')); - var iv = new UTIL.createBuffer( - UTIL.hexToBytes('818bcf76efc59662')); - - var cipher = CIPHER.createCipher('3DES-CBC', key); - cipher.start({iv: iv.copy()}); - cipher.update(UTIL.createBuffer('foobar')); - cipher.finish(); - ASSERT.equal(cipher.output.toHex(), '209225f7687ca0b2'); - - cipher.start({iv: iv.copy()}); - cipher.update(UTIL.createBuffer('foobar,,')); - cipher.finish(); - ASSERT.equal(cipher.output.toHex(), '57156174c48dfc37293831bf192a6742'); - }); - - // OpenSSL equivalent: - // openssl enc -d -des3 -K a1c06b381adf36517e84575552777779da5e3d9f994b05b5 -iv 818bcf76efc59662 -nosalt - it('should 3des-cbc decrypt "209225f7687ca0b2", restart, and decrypt "57156174c48dfc37293831bf192a6742,,"', function() { - var key = new UTIL.createBuffer( - UTIL.hexToBytes('a1c06b381adf36517e84575552777779da5e3d9f994b05b5')); - var iv = new UTIL.createBuffer( - UTIL.hexToBytes('818bcf76efc59662')); - - var decipher = CIPHER.createDecipher('3DES-CBC', key); - decipher.start({iv: iv.copy()}); - decipher.update(UTIL.createBuffer(UTIL.hexToBytes('209225f7687ca0b2'))); - decipher.finish(); - ASSERT.equal(decipher.output.getBytes(), 'foobar'); - - decipher.start({iv: iv.copy()}); - decipher.update( - UTIL.createBuffer(UTIL.hexToBytes('57156174c48dfc37293831bf192a6742'))); - decipher.finish(); - ASSERT.equal(decipher.output.getBytes(), 'foobar,,'); - }); - }); -} - -// check for AMD -var forge = {}; -if(typeof define === 'function') { - define([ - 'forge/cipher', - 'forge/des', - 'forge/util' - ], function(CIPHER, DES, UTIL) { - Tests( - // Global provided by test harness - ASSERT, - CIPHER(forge), - DES(forge), - UTIL(forge) - ); - }); -} else if(typeof module === 'object' && module.exports) { - // assume NodeJS - Tests( - require('assert'), - require('../../js/cipher')(forge), - require('../../js/des')(forge), - require('../../js/util')(forge)); -} - -})(); diff --git a/alarm/node_modules/node-forge/nodejs/test/hmac.js b/alarm/node_modules/node-forge/nodejs/test/hmac.js deleted file mode 100644 index 404b36b..0000000 --- a/alarm/node_modules/node-forge/nodejs/test/hmac.js +++ /dev/null @@ -1,85 +0,0 @@ -(function() { - -function Tests(ASSERT, HMAC, UTIL) { - describe('hmac', function() { - it('should md5 hash "Hi There", 16-byte key', function() { - var key = UTIL.hexToBytes('0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b'); - var hmac = HMAC.create(); - hmac.start('MD5', key); - hmac.update('Hi There'); - ASSERT.equal(hmac.digest().toHex(), '9294727a3638bb1c13f48ef8158bfc9d'); - }); - - it('should md5 hash "what do ya want for nothing?", "Jefe" key', function() { - var hmac = HMAC.create(); - hmac.start('MD5', 'Jefe'); - hmac.update('what do ya want for nothing?'); - ASSERT.equal(hmac.digest().toHex(), '750c783e6ab0b503eaa86e310a5db738'); - }); - - it('should md5 hash "Test Using Larger Than Block-Size Key - Hash Key First", 80-byte key', function() { - var key = UTIL.hexToBytes( - 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + - 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + - 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + - 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'); - var hmac = HMAC.create(); - hmac.start('MD5', key); - hmac.update('Test Using Larger Than Block-Size Key - Hash Key First'); - ASSERT.equal(hmac.digest().toHex(), '6b1ab7fe4bd7bf8f0b62e6ce61b9d0cd'); - }); - - it('should sha1 hash "Hi There", 20-byte key', function() { - var key = UTIL.hexToBytes('0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b'); - var hmac = HMAC.create(); - hmac.start('SHA1', key); - hmac.update('Hi There'); - ASSERT.equal( - hmac.digest().toHex(), 'b617318655057264e28bc0b6fb378c8ef146be00'); - }); - - it('should sha1 hash "what do ya want for nothing?", "Jefe" key', function() { - var hmac = HMAC.create(); - hmac.start('SHA1', 'Jefe'); - hmac.update('what do ya want for nothing?'); - ASSERT.equal( - hmac.digest().toHex(), 'effcdf6ae5eb2fa2d27416d5f184df9c259a7c79'); - }); - - it('should sha1 hash "Test Using Larger Than Block-Size Key - Hash Key First", 80-byte key', function() { - var key = UTIL.hexToBytes( - 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + - 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + - 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + - 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'); - var hmac = HMAC.create(); - hmac.start('SHA1', key); - hmac.update('Test Using Larger Than Block-Size Key - Hash Key First'); - ASSERT.equal( - hmac.digest().toHex(), 'aa4ae5e15272d00e95705637ce8a3b55ed402112'); - }); - }); -} - -// check for AMD -if(typeof define === 'function') { - define([ - 'forge/hmac', - 'forge/util' - ], function(HMAC, UTIL) { - Tests( - // Global provided by test harness - ASSERT, - HMAC(), - UTIL() - ); - }); -} else if(typeof module === 'object' && module.exports) { - // assume NodeJS - Tests( - require('assert'), - require('../../js/hmac')(), - require('../../js/util')()); -} - -})(); diff --git a/alarm/node_modules/node-forge/nodejs/test/kem.js b/alarm/node_modules/node-forge/nodejs/test/kem.js deleted file mode 100644 index 0415abe..0000000 --- a/alarm/node_modules/node-forge/nodejs/test/kem.js +++ /dev/null @@ -1,198 +0,0 @@ -(function() { - -function Tests(ASSERT, KEM, MD, RSA, UTIL, JSBN, RANDOM) { - - function FixedSecureRandom(str) { - var bytes = UTIL.hexToBytes(str); - this.getBytesSync = function(count) { - // prepend zeros - return UTIL.fillString(String.fromCharCode(0), bytes.length - count) + - bytes; - }; - } - - describe('kem', function() { - it('should generate and encrypt a symmetric key and decrypt it 10x', function() { - for(var i = 0; i < 10; ++i) { - var kdf = new KEM.kdf1(MD.sha256.create()); - var kem = KEM.rsa.create(kdf); - - var pair = RSA.generateKeyPair(512); - - var result = kem.encrypt(pair.publicKey, 256); - var key1 = result.key; - var key2 = kem.decrypt(pair.privateKey, result.encapsulation, 256); - - ASSERT.equal(UTIL.bytesToHex(key1), UTIL.bytesToHex(key2)); - } - }); - }); - - /** - * According to section "C.6 Test vectors for RSA-KEM" from ISO-18033-2 final - * draft. - */ - describe('C.6 Test vectors for RSA-KEM from ISO-18033-2 final', function() { - it('should pass test vector C.6.1', function() { - var n = '5888113332502691251761936431009284884966640757179802337490546478326238537107326596800820237597139824869184990638749556269785797065508097452399642780486933'; - var e = '65537'; - var d = '3202313555859948186315374524474173995679783580392140237044349728046479396037520308981353808895461806395564474639124525446044708705259675840210989546479265'; - - var C0 = '4603e5324cab9cef8365c817052d954d44447b1667099edc69942d32cd594e4ffcf268ae3836e2c35744aaa53ae201fe499806b67dedaa26bf72ecbd117a6fc0'; - var K = '5f8de105b5e96b2e490ddecbd147dd1def7e3b8e0e6a26eb7b956ccb8b3bdc1ca975bc57c3989e8fbad31a224655d800c46954840ff32052cdf0d640562bdfadfa263cfccf3c52b29f2af4a1869959bc77f854cf15bd7a25192985a842dbff8e13efee5b7e7e55bbe4d389647c686a9a9ab3fb889b2d7767d3837eea4e0a2f04'; - - var kdf = new KEM.kdf1(MD.sha1.create()); - var rnd = new FixedSecureRandom('032e45326fa859a72ec235acff929b15d1372e30b207255f0611b8f785d764374152e0ac009e509e7ba30cd2f1778e113b64e135cf4e2292c75efe5288edfda4'); - var kem = KEM.rsa.create(kdf, {prng: rnd}); - - var rsaPublicKey = RSA.setPublicKey( - new JSBN.BigInteger(n), new JSBN.BigInteger(e)); - var rsaPrivateKey = RSA.setPrivateKey( - new JSBN.BigInteger(n), null, new JSBN.BigInteger(d)); - - var result = kem.encrypt(rsaPublicKey, 128); - ASSERT.equal(UTIL.bytesToHex(result.encapsulation), C0); - ASSERT.equal(UTIL.bytesToHex(result.key), K); - - var decryptedKey = kem.decrypt(rsaPrivateKey, result.encapsulation, 128); - ASSERT.equal(UTIL.bytesToHex(decryptedKey), K); - }); - - it('should pass test vector C.6.2', function() { - var n = '5888113332502691251761936431009284884966640757179802337490546478326238537107326596800820237597139824869184990638749556269785797065508097452399642780486933'; - var e = '65537'; - var d = '3202313555859948186315374524474173995679783580392140237044349728046479396037520308981353808895461806395564474639124525446044708705259675840210989546479265'; - - var C0 = '4603e5324cab9cef8365c817052d954d44447b1667099edc69942d32cd594e4ffcf268ae3836e2c35744aaa53ae201fe499806b67dedaa26bf72ecbd117a6fc0'; - var K = '0e6a26eb7b956ccb8b3bdc1ca975bc57c3989e8fbad31a224655d800c46954840ff32052cdf0d640562bdfadfa263cfccf3c52b29f2af4a1869959bc77f854cf15bd7a25192985a842dbff8e13efee5b7e7e55bbe4d389647c686a9a9ab3fb889b2d7767d3837eea4e0a2f04b53ca8f50fb31225c1be2d0126c8c7a4753b0807'; - - var kdf = new KEM.kdf2(MD.sha1.create()); - var rnd = new FixedSecureRandom('032e45326fa859a72ec235acff929b15d1372e30b207255f0611b8f785d764374152e0ac009e509e7ba30cd2f1778e113b64e135cf4e2292c75efe5288edfda4'); - var kem = KEM.rsa.create(kdf, {prng: rnd}); - - var rsaPublicKey = RSA.setPublicKey( - new JSBN.BigInteger(n), new JSBN.BigInteger(e)); - var rsaPrivateKey = RSA.setPrivateKey( - new JSBN.BigInteger(n), null, new JSBN.BigInteger(d)); - - var result = kem.encrypt(rsaPublicKey, 128); - ASSERT.equal(UTIL.bytesToHex(result.encapsulation), C0); - ASSERT.equal(UTIL.bytesToHex(result.key), K); - - var decryptedKey = kem.decrypt(rsaPrivateKey, result.encapsulation, 128); - ASSERT.equal(UTIL.bytesToHex(decryptedKey), K); - }); - - it('should pass test vector C.6.3', function() { - var n = '5888113332502691251761936431009284884966640757179802337490546478326238537107326596800820237597139824869184990638749556269785797065508097452399642780486933'; - var e = '65537'; - var d = '3202313555859948186315374524474173995679783580392140237044349728046479396037520308981353808895461806395564474639124525446044708705259675840210989546479265'; - - var C0 = '4603e5324cab9cef8365c817052d954d44447b1667099edc69942d32cd594e4ffcf268ae3836e2c35744aaa53ae201fe499806b67dedaa26bf72ecbd117a6fc0'; - var K = '09e2decf2a6e1666c2f6071ff4298305e2643fd510a2403db42a8743cb989de86e668d168cbe604611ac179f819a3d18412e9eb45668f2923c087c12fee0c5a0d2a8aa70185401fbbd99379ec76c663e875a60b4aacb1319fa11c3365a8b79a44669f26fb555c80391847b05eca1cb5cf8c2d531448d33fbaca19f6410ee1fcb'; - - var kdf = new KEM.kdf1(MD.sha256.create(), 20); - var rnd = new FixedSecureRandom('032e45326fa859a72ec235acff929b15d1372e30b207255f0611b8f785d764374152e0ac009e509e7ba30cd2f1778e113b64e135cf4e2292c75efe5288edfda4'); - var kem = KEM.rsa.create(kdf, {prng: rnd}); - - var rsaPublicKey = RSA.setPublicKey( - new JSBN.BigInteger(n), new JSBN.BigInteger(e)); - var rsaPrivateKey = RSA.setPrivateKey( - new JSBN.BigInteger(n), null, new JSBN.BigInteger(d)); - - var result = kem.encrypt(rsaPublicKey, 128); - ASSERT.equal(UTIL.bytesToHex(result.encapsulation), C0); - ASSERT.equal(UTIL.bytesToHex(result.key), K); - - var decryptedKey = kem.decrypt(rsaPrivateKey, result.encapsulation, 128); - ASSERT.equal(UTIL.bytesToHex(decryptedKey), K); - }); - - it('should pass test vector C.6.4', function() { - var n = '5888113332502691251761936431009284884966640757179802337490546478326238537107326596800820237597139824869184990638749556269785797065508097452399642780486933'; - var e = '65537'; - var d = '3202313555859948186315374524474173995679783580392140237044349728046479396037520308981353808895461806395564474639124525446044708705259675840210989546479265'; - - var C0 = '4603e5324cab9cef8365c817052d954d44447b1667099edc69942d32cd594e4ffcf268ae3836e2c35744aaa53ae201fe499806b67dedaa26bf72ecbd117a6fc0'; - var K = '10a2403db42a8743cb989de86e668d168cbe604611ac179f819a3d18412e9eb45668f2923c087c12fee0c5a0d2a8aa70185401fbbd99379ec76c663e875a60b4aacb1319fa11c3365a8b79a44669f26fb555c80391847b05eca1cb5cf8c2d531448d33fbaca19f6410ee1fcb260892670e0814c348664f6a7248aaf998a3acc6'; - - var kdf = new KEM.kdf2(MD.sha256.create(), 20); - var rnd = new FixedSecureRandom('00032e45326fa859a72ec235acff929b15d1372e30b207255f0611b8f785d764374152e0ac009e509e7ba30cd2f1778e113b64e135cf4e2292c75efe5288edfda4'); - var kem = KEM.rsa.create(kdf, {prng: rnd}); - - var rsaPublicKey = RSA.setPublicKey( - new JSBN.BigInteger(n), new JSBN.BigInteger(e)); - var rsaPrivateKey = RSA.setPrivateKey( - new JSBN.BigInteger(n), null, new JSBN.BigInteger(d)); - - var result = kem.encrypt(rsaPublicKey, 128); - ASSERT.equal(UTIL.bytesToHex(result.encapsulation), C0); - ASSERT.equal(UTIL.bytesToHex(result.key), K); - - var decryptedKey = kem.decrypt(rsaPrivateKey, result.encapsulation, 128); - ASSERT.equal(UTIL.bytesToHex(decryptedKey), K); - }); - }); - - describe('prepended zeros test', function() { - it('should pass when random has leading zeros', function() { - var n = '5888113332502691251761936431009284884966640757179802337490546478326238537107326596800820237597139824869184990638749556269785797065508097452399642780486933'; - var e = '65537'; - var d = '3202313555859948186315374524474173995679783580392140237044349728046479396037520308981353808895461806395564474639124525446044708705259675840210989546479265'; - - var C0 = '5f268a76c1aed04bc195a143d7ee768bee0aad308d16196274a02d9c1a72bbe10cbf718de323fc0135c5f8129f96ac8f504d9623960dc54cd87bddee94f5a0b2'; - var K = '8bf41e59dc1b83142ee32569a347a94539e48c98347c685a29e3aa8b7a3ea714d68c1a43c4a760c9d4a45149b0ce8b681e98076bdd4393394c7832a7fa71848257772ac38a4e7fbe96e8bb383becbb7242841946e82e35d9ef1667245fc82601e7edf53b897f5ce2b6bce8e1e3212abd5a8a99a0c9b99472e22a313dac396383'; - - var kdf = new KEM.kdf1(MD.sha1.create()); - var rnd = new FixedSecureRandom('000e45326fa859a72ec235acff929b15d1372e30b207255f0611b8f785d764374152e0ac009e509e7ba30cd2f1778e113b64e135cf4e2292c75efe5288edfda4'); - var kem = KEM.rsa.create(kdf, {prng: rnd}); - - var rsaPublicKey = RSA.setPublicKey( - new JSBN.BigInteger(n), new JSBN.BigInteger(e)); - var rsaPrivateKey = RSA.setPrivateKey( - new JSBN.BigInteger(n), null, new JSBN.BigInteger(d)); - - var result = kem.encrypt(rsaPublicKey, 128); - ASSERT.equal(UTIL.bytesToHex(result.encapsulation), C0); - ASSERT.equal(UTIL.bytesToHex(result.key), K); - - var decryptedKey = kem.decrypt(rsaPrivateKey, result.encapsulation, 128); - ASSERT.equal(UTIL.bytesToHex(decryptedKey), K); - }); - }); -} - -// check for AMD -if(typeof define === 'function') { - define([ - 'forge/kem', - 'forge/md', - 'forge/rsa', - 'forge/util', - 'forge/jsbn', - 'forge/random' - ], function(KEM, MD, RSA, UTIL, JSBN, RANDOM) { - Tests( - // Global provided by test harness - ASSERT, - KEM(), - MD(), - RSA(), - UTIL(), - JSBN(), - RANDOM() - ); - }); -} else if(typeof module === 'object' && module.exports) { - // assume NodeJS - Tests( - require('assert'), - require('../../js/kem')(), - require('../../js/md')(), - require('../../js/rsa')(), - require('../../js/util')(), - require('../../js/jsbn')(), - require('../../js/random')()); -} - -})(); diff --git a/alarm/node_modules/node-forge/nodejs/test/md5.js b/alarm/node_modules/node-forge/nodejs/test/md5.js deleted file mode 100644 index 5ab3d58..0000000 --- a/alarm/node_modules/node-forge/nodejs/test/md5.js +++ /dev/null @@ -1,117 +0,0 @@ -(function() { - -function Tests(ASSERT, MD5, UTIL) { - describe('md5', function() { - it('should digest the empty string', function() { - var md = MD5.create(); - ASSERT.equal(md.digest().toHex(), 'd41d8cd98f00b204e9800998ecf8427e'); - }); - - it('should digest "abc"', function() { - var md = MD5.create(); - md.update('abc'); - ASSERT.equal(md.digest().toHex(), '900150983cd24fb0d6963f7d28e17f72'); - }); - - it('should digest "The quick brown fox jumps over the lazy dog"', function() { - var md = MD5.create(); - md.update('The quick brown fox jumps over the lazy dog'); - ASSERT.equal(md.digest().toHex(), '9e107d9d372bb6826bd81d3542a419d6'); - }); - - it('should digest "c\'\u00e8"', function() { - var md = MD5.create(); - md.update("c\'\u00e8", 'utf8'); - ASSERT.equal(md.digest().toHex(), '8ef7c2941d78fe89f31e614437c9db59'); - }); - - it('should digest "THIS IS A MESSAGE"', function() { - var md = MD5.create(); - md.start(); - md.update('THIS IS '); - md.update('A MESSAGE'); - // do twice to check continuing digest - ASSERT.equal(md.digest().toHex(), '78eebfd9d42958e3f31244f116ab7bbe'); - ASSERT.equal(md.digest().toHex(), '78eebfd9d42958e3f31244f116ab7bbe'); - }); - - it('should digest a long message', function() { - var input = UTIL.hexToBytes( - '0100002903018d32e9c6dc423774c4c39a5a1b78f44cc2cab5f676d39' + - 'f703d29bfa27dfeb870000002002f01000200004603014c2c1e835d39' + - 'da71bc0857eb04c2b50fe90dbb2a8477fe7364598d6f0575999c20a6c' + - '7248c5174da6d03ac711888f762fc4ed54f7254b32273690de849c843' + - '073d002f000b0003d20003cf0003cc308203c8308202b0a0030201020' + - '20100300d06092a864886f70d0101050500308186310b300906035504' + - '0613025553311d301b060355040a13144469676974616c2042617a616' + - '1722c20496e632e31443042060355040b133b4269746d756e6b206c6f' + - '63616c686f73742d6f6e6c7920436572746966696361746573202d204' + - '17574686f72697a6174696f6e20766961204254503112301006035504' + - '0313096c6f63616c686f7374301e170d3130303231343137303931395' + - 'a170d3230303231333137303931395a308186310b3009060355040613' + - '025553311d301b060355040a13144469676974616c2042617a6161722' + - 'c20496e632e31443042060355040b133b4269746d756e6b206c6f6361' + - '6c686f73742d6f6e6c7920436572746966696361746573202d2041757' + - '4686f72697a6174696f6e207669612042545031123010060355040313' + - '096c6f63616c686f737430820122300d06092a864886f70d010101050' + - '00382010f003082010a0282010100dc436f17d6909d8a9d6186ea218e' + - 'b5c86b848bae02219bd56a71203daf07e81bc19e7e98134136bcb0128' + - '81864bf03b3774652ad5eab85dba411a5114ffeac09babce75f313143' + - '45512cd87c91318b2e77433270a52185fc16f428c3ca412ad6e9484bc' + - '2fb87abb4e8fb71bf0f619e31a42340b35967f06c24a741a31c979c0b' + - 'b8921a90a47025fbeb8adca576979e70a56830c61170c9647c18c0794' + - 'd68c0df38f3aac5fc3b530e016ea5659715339f3f3c209cdee9dbe794' + - 'b5af92530c5754c1d874b78974bfad994e0dfc582275e79feb522f6e4' + - 'bcc2b2945baedfb0dbdaebb605f9483ff0bea29ecd5f4d6f2769965d1' + - 'b3e04f8422716042680011ff676f0203010001a33f303d300c0603551' + - 'd130101ff04023000300e0603551d0f0101ff0404030204f0301d0603' + - '551d250416301406082b0601050507030106082b06010505070302300' + - 'd06092a864886f70d010105050003820101009c4562be3f2d8d8e3880' + - '85a697f2f106eaeff4992a43f198fe3dcf15c8229cf1043f061a38204' + - 'f73d86f4fb6348048cc5279ed719873aa10e3773d92b629c2c3fcce04' + - '012c81ba3b4ec451e9644ec5191078402d845e05d02c7b4d974b45882' + - '76e5037aba7ef26a8bddeb21e10698c82f425e767dc401adf722fa73a' + - 'b78cfa069bd69052d7ca6a75cc9225550e315d71c5f8764362ea4dbc6' + - 'ecb837a8471043c5a7f826a71af145a053090bd4bccca6a2c552841cd' + - 'b1908a8352f49283d2e641acdef667c7543af441a16f8294251e2ac37' + - '6fa507b53ae418dd038cd20cef1e7bfbf5ae03a7c88d93d843abaabbd' + - 'c5f3431132f3e559d2dd414c3eda38a210b80e0000001000010201002' + - '6a220b7be857402819b78d81080d01a682599bbd00902985cc64edf8e' + - '520e4111eb0e1729a14ffa3498ca259cc9ad6fc78fa130d968ebdb78d' + - 'c0b950c0aa44355f13ba678419185d7e4608fe178ca6b2cef33e41937' + - '78d1a70fe4d0dfcb110be4bbb4dbaa712177655728f914ab4c0f6c4ae' + - 'f79a46b3d996c82b2ebe9ed1748eb5cace7dc44fb67e73f452a047f2e' + - 'd199b3d50d5db960acf03244dc8efa4fc129faf8b65f9e52e62b55447' + - '22bd17d2358e817a777618a4265a3db277fc04851a82a91fe6cdcb812' + - '7f156e0b4a5d1f54ce2742eb70c895f5f8b85f5febe69bc73e891f928' + - '0826860a0c2ef94c7935e6215c3c4cd6b0e43e80cca396d913d36be'); - - var md = MD5.create(); - md.update(input); - ASSERT.equal(md.digest().toHex(), 'd15a2da0e92c3da55dc573f885b6e653'); - }); - }); -} - -// check for AMD -if(typeof define === 'function') { - define([ - 'forge/md5', - 'forge/util' - ], function(MD5, UTIL) { - Tests( - // Global provided by test harness - ASSERT, - MD5(), - UTIL() - ); - }); -} else if(typeof module === 'object' && module.exports) { - // assume NodeJS - Tests( - require('assert'), - require('../../js/md5')(), - require('../../js/util')()); -} - -})(); diff --git a/alarm/node_modules/node-forge/nodejs/test/mgf1.js b/alarm/node_modules/node-forge/nodejs/test/mgf1.js deleted file mode 100644 index 6c54ff1..0000000 --- a/alarm/node_modules/node-forge/nodejs/test/mgf1.js +++ /dev/null @@ -1,39 +0,0 @@ -(function() { - -function Tests(ASSERT, MGF, MD, UTIL) { - describe('mgf1', function() { - it('should digest the empty string', function() { - var seed = UTIL.hexToBytes('032e45326fa859a72ec235acff929b15d1372e30b207255f0611b8f785d764374152e0ac009e509e7ba30cd2f1778e113b64e135cf4e2292c75efe5288edfda4'); - var expect = UTIL.hexToBytes('5f8de105b5e96b2e490ddecbd147dd1def7e3b8e0e6a26eb7b956ccb8b3bdc1ca975bc57c3989e8fbad31a224655d800c46954840ff32052cdf0d640562bdfadfa263cfccf3c52b29f2af4a1869959bc77f854cf15bd7a25192985a842dbff8e13efee5b7e7e55bbe4d389647c686a9a9ab3fb889b2d7767d3837eea4e0a2f04'); - var mgf = MGF.mgf1.create(MD.sha1.create()); - var result = mgf.generate(seed, expect.length); - ASSERT.equal(result, expect); - }); - }); -} - -// check for AMD -if(typeof define === 'function') { - define([ - 'forge/mgf', - 'forge/md', - 'forge/util' - ], function(MGF, MD, UTIL) { - Tests( - // Global provided by test harness - ASSERT, - MGF(), - MD(), - UTIL() - ); - }); -} else if(typeof module === 'object' && module.exports) { - // assume NodeJS - Tests( - require('assert'), - require('../../js/mgf')(), - require('../../js/md')(), - require('../../js/util')()); -} - -})(); diff --git a/alarm/node_modules/node-forge/nodejs/test/pbkdf2.js b/alarm/node_modules/node-forge/nodejs/test/pbkdf2.js deleted file mode 100644 index 90e36f0..0000000 --- a/alarm/node_modules/node-forge/nodejs/test/pbkdf2.js +++ /dev/null @@ -1,140 +0,0 @@ -(function() { - -function Tests(ASSERT, PBKDF2, MD, UTIL) { - describe('pbkdf2', function() { - it('should derive a password with hmac-sha-1 c=1', function() { - var dkHex = UTIL.bytesToHex(PBKDF2('password', 'salt', 1, 20)); - ASSERT.equal(dkHex, '0c60c80f961f0e71f3a9b524af6012062fe037a6'); - }); - - it('should derive a password with hmac-sha-1 c=2', function() { - var dkHex = UTIL.bytesToHex(PBKDF2('password', 'salt', 2, 20)); - ASSERT.equal(dkHex, 'ea6c014dc72d6f8ccd1ed92ace1d41f0d8de8957'); - }); - - it('should derive a password with hmac-sha-1 c=5 keylen=8', function() { - var salt = UTIL.hexToBytes('1234567878563412'); - var dkHex = UTIL.bytesToHex(PBKDF2('password', salt, 5, 8)); - ASSERT.equal(dkHex, 'd1daa78615f287e6'); - }); - - it('should derive a password with hmac-sha-1 c=4096', function() { - // Note: might be too slow on old browsers - var dkHex = UTIL.bytesToHex(PBKDF2('password', 'salt', 4096, 20)); - ASSERT.equal(dkHex, '4b007901b765489abead49d926f721d065a429c1'); - }); - - /* - it('should derive a password with hmac-sha-1 c=16777216', function() { - // Note: too slow - var dkHex = UTIL.bytesToHex(PBKDF2('password', 'salt', 16777216, 20)); - ASSERT.equal(dkHex, 'eefe3d61cd4da4e4e9945b3d6ba2158c2634e984'); - });*/ - - it('should derive a password with hmac-sha-256 c=1000', function() { - // Note: might be too slow on old browsers - var salt = '4bcda0d1c689fe465c5b8a817f0ddf3d'; - var md = MD.sha256.create(); - var dkHex = UTIL.bytesToHex(PBKDF2('password', salt, 1000, 48, md)); - ASSERT.equal(dkHex, '9da8a5f4ae605f35e82e5beac5f362df15c4255d88f738d641466a4107f9970238e768e72af29ac89a1b16ff277b31d2'); - }); - - it('should derive a password with hmac-sha-256 (passed as an algorithm identifier) c=1000', function() { - // Note: might be too slow on old browsers - var salt = '4bcda0d1c689fe465c5b8a817f0ddf3d'; - var dkHex = UTIL.bytesToHex(PBKDF2('password', salt, 1000, 48, 'sha256')); - ASSERT.equal(dkHex, '9da8a5f4ae605f35e82e5beac5f362df15c4255d88f738d641466a4107f9970238e768e72af29ac89a1b16ff277b31d2'); - }); - - it('should asynchronously derive a password with hmac-sha-1 c=1', function(done) { - PBKDF2('password', 'salt', 1, 20, function(err, dk) { - var dkHex = UTIL.bytesToHex(dk); - ASSERT.equal(dkHex, '0c60c80f961f0e71f3a9b524af6012062fe037a6'); - done(); - }); - }); - - it('should asynchronously derive a password with hmac-sha-1 c=2', function(done) { - PBKDF2('password', 'salt', 2, 20, function(err, dk) { - var dkHex = UTIL.bytesToHex(dk); - ASSERT.equal(dkHex, 'ea6c014dc72d6f8ccd1ed92ace1d41f0d8de8957'); - done(); - }); - }); - - it('should asynchronously derive a password with hmac-sha-1 c=5 keylen=8', function(done) { - var salt = UTIL.hexToBytes('1234567878563412'); - PBKDF2('password', salt, 5, 8, function(err, dk) { - var dkHex = UTIL.bytesToHex(dk); - ASSERT.equal(dkHex, 'd1daa78615f287e6'); - done(); - }); - }); - - it('should asynchronously derive a password with hmac-sha-1 c=4096', function(done) { - // Note: might be too slow on old browsers - PBKDF2('password', 'salt', 4096, 20, function(err, dk) { - var dkHex = UTIL.bytesToHex(dk); - ASSERT.equal(dkHex, '4b007901b765489abead49d926f721d065a429c1'); - done(); - }); - }); - - /* - it('should asynchronously derive a password with hmac-sha-1 c=16777216', function(done) { - // Note: too slow - PBKDF2('password', 'salt', 16777216, 20, function(err, dk) { - var dkHex = UTIL.bytesToHex(dk); - ASSERT.equal(dkHex, 'eefe3d61cd4da4e4e9945b3d6ba2158c2634e984'); - done(); - }); - });*/ - - it('should asynchronously derive a password with hmac-sha-256 c=1000', function(done) { - // Note: might be too slow on old browsers - var salt = '4bcda0d1c689fe465c5b8a817f0ddf3d'; - var md = MD.sha256.create(); - PBKDF2('password', salt, 1000, 48, md, function(err, dk) { - var dkHex = UTIL.bytesToHex(dk); - ASSERT.equal(dkHex, '9da8a5f4ae605f35e82e5beac5f362df15c4255d88f738d641466a4107f9970238e768e72af29ac89a1b16ff277b31d2'); - done(); - }); - }); - - it('should asynchronously derive a password with hmac-sha-256 (passed as an algorithm identifier) c=1000', function(done) { - // Note: might be too slow on old browsers - var salt = '4bcda0d1c689fe465c5b8a817f0ddf3d'; - PBKDF2('password', salt, 1000, 48, 'sha256', function(err, dk) { - var dkHex = UTIL.bytesToHex(dk); - ASSERT.equal(dkHex, '9da8a5f4ae605f35e82e5beac5f362df15c4255d88f738d641466a4107f9970238e768e72af29ac89a1b16ff277b31d2'); - done(); - }); - }); - }); -} - -// check for AMD -if(typeof define === 'function') { - define([ - 'forge/pbkdf2', - 'forge/md', - 'forge/util' - ], function(PBKDF2, MD, UTIL) { - Tests( - // Global provided by test harness - ASSERT, - PBKDF2(), - MD(), - UTIL() - ); - }); -} else if(typeof module === 'object' && module.exports) { - // assume NodeJS - Tests( - require('assert'), - require('../../js/pbkdf2')(), - require('../../js/md')(), - require('../../js/util')()); -} - -})(); diff --git a/alarm/node_modules/node-forge/nodejs/test/pem.js b/alarm/node_modules/node-forge/nodejs/test/pem.js deleted file mode 100644 index 6b405cb..0000000 --- a/alarm/node_modules/node-forge/nodejs/test/pem.js +++ /dev/null @@ -1,104 +0,0 @@ -(function() { - -function Tests(ASSERT, PEM) { - var _input = '-----BEGIN PRIVACY-ENHANCED MESSAGE-----\r\n' + - 'Proc-Type: 4,ENCRYPTED\r\n' + - 'Content-Domain: RFC822\r\n' + - 'DEK-Info: DES-CBC,F8143EDE5960C597\r\n' + - 'Originator-ID-Symmetric: linn@zendia.enet.dec.com,,\r\n' + - 'Recipient-ID-Symmetric: linn@zendia.enet.dec.com,ptf-kmc,3\r\n' + - 'Key-Info: DES-ECB,RSA-MD2,9FD3AAD2F2691B9A,\r\n' + - ' B70665BB9BF7CBCDA60195DB94F727D3\r\n' + - 'Recipient-ID-Symmetric: pem-dev@tis.com,ptf-kmc,4\r\n' + - 'Key-Info: DES-ECB,RSA-MD2,161A3F75DC82EF26,\r\n' + - ' E2EF532C65CBCFF79F83A2658132DB47\r\n' + - '\r\n' + - 'LLrHB0eJzyhP+/fSStdW8okeEnv47jxe7SJ/iN72ohNcUk2jHEUSoH1nvNSIWL9M\r\n' + - '8tEjmF/zxB+bATMtPjCUWbz8Lr9wloXIkjHUlBLpvXR0UrUzYbkNpk0agV2IzUpk\r\n' + - 'J6UiRRGcDSvzrsoK+oNvqu6z7Xs5Xfz5rDqUcMlK1Z6720dcBWGGsDLpTpSCnpot\r\n' + - 'dXd/H5LMDWnonNvPCwQUHg==\r\n' + - '-----END PRIVACY-ENHANCED MESSAGE-----\r\n' + - '-----BEGIN PRIVACY-ENHANCED MESSAGE-----\r\n' + - 'Proc-Type: 4,ENCRYPTED\r\n' + - 'Content-Domain: RFC822\r\n' + - 'DEK-Info: DES-CBC,BFF968AA74691AC1\r\n' + - 'Originator-Certificate:\r\n' + - ' MIIBlTCCAScCAWUwDQYJKoZIhvcNAQECBQAwUTELMAkGA1UEBhMCVVMxIDAeBgNV\r\n' + - ' BAoTF1JTQSBEYXRhIFNlY3VyaXR5LCBJbmMuMQ8wDQYDVQQLEwZCZXRhIDExDzAN\r\n' + - ' BgNVBAsTBk5PVEFSWTAeFw05MTA5MDQxODM4MTdaFw05MzA5MDMxODM4MTZaMEUx\r\n' + - ' CzAJBgNVBAYTAlVTMSAwHgYDVQQKExdSU0EgRGF0YSBTZWN1cml0eSwgSW5jLjEU\r\n' + - ' MBIGA1UEAxMLVGVzdCBVc2VyIDEwWTAKBgRVCAEBAgICAANLADBIAkEAwHZHl7i+\r\n' + - ' yJcqDtjJCowzTdBJrdAiLAnSC+CnnjOJELyuQiBgkGrgIh3j8/x0fM+YrsyF1u3F\r\n' + - ' LZPVtzlndhYFJQIDAQABMA0GCSqGSIb3DQEBAgUAA1kACKr0PqphJYw1j+YPtcIq\r\n' + - ' iWlFPuN5jJ79Khfg7ASFxskYkEMjRNZV/HZDZQEhtVaU7Jxfzs2wfX5byMp2X3U/\r\n' + - ' 5XUXGx7qusDgHQGs7Jk9W8CW1fuSWUgN4w==\r\n' + - 'Key-Info: RSA,\r\n' + - ' I3rRIGXUGWAF8js5wCzRTkdhO34PTHdRZY9Tuvm03M+NM7fx6qc5udixps2Lng0+\r\n' + - ' wGrtiUm/ovtKdinz6ZQ/aQ==\r\n' + - 'Issuer-Certificate:\r\n' + - ' MIIB3DCCAUgCAQowDQYJKoZIhvcNAQECBQAwTzELMAkGA1UEBhMCVVMxIDAeBgNV\r\n' + - ' BAoTF1JTQSBEYXRhIFNlY3VyaXR5LCBJbmMuMQ8wDQYDVQQLEwZCZXRhIDExDTAL\r\n' + - ' BgNVBAsTBFRMQ0EwHhcNOTEwOTAxMDgwMDAwWhcNOTIwOTAxMDc1OTU5WjBRMQsw\r\n' + - ' CQYDVQQGEwJVUzEgMB4GA1UEChMXUlNBIERhdGEgU2VjdXJpdHksIEluYy4xDzAN\r\n' + - ' BgNVBAsTBkJldGEgMTEPMA0GA1UECxMGTk9UQVJZMHAwCgYEVQgBAQICArwDYgAw\r\n' + - ' XwJYCsnp6lQCxYykNlODwutF/jMJ3kL+3PjYyHOwk+/9rLg6X65B/LD4bJHtO5XW\r\n' + - ' cqAz/7R7XhjYCm0PcqbdzoACZtIlETrKrcJiDYoP+DkZ8k1gCk7hQHpbIwIDAQAB\r\n' + - ' MA0GCSqGSIb3DQEBAgUAA38AAICPv4f9Gx/tY4+p+4DB7MV+tKZnvBoy8zgoMGOx\r\n' + - ' dD2jMZ/3HsyWKWgSF0eH/AJB3qr9zosG47pyMnTf3aSy2nBO7CMxpUWRBcXUpE+x\r\n' + - ' EREZd9++32ofGBIXaialnOgVUn0OzSYgugiQ077nJLDUj0hQehCizEs5wUJ35a5h\r\n' + - 'MIC-Info: RSA-MD5,RSA,\r\n' + - ' UdFJR8u/TIGhfH65ieewe2lOW4tooa3vZCvVNGBZirf/7nrgzWDABz8w9NsXSexv\r\n' + - ' AjRFbHoNPzBuxwmOAFeA0HJszL4yBvhG\r\n' + - 'Recipient-ID-Asymmetric:\r\n' + - ' MFExCzAJBgNVBAYTAlVTMSAwHgYDVQQKExdSU0EgRGF0YSBTZWN1cml0eSwgSW5j\r\n' + - ' LjEPMA0GA1UECxMGQmV0YSAxMQ8wDQYDVQQLEwZOT1RBUlk=,66\r\n' + - 'Key-Info: RSA,\r\n' + - ' O6BS1ww9CTyHPtS3bMLD+L0hejdvX6Qv1HK2ds2sQPEaXhX8EhvVphHYTjwekdWv\r\n' + - ' 7x0Z3Jx2vTAhOYHMcqqCjA==\r\n' + - '\r\n' + - 'qeWlj/YJ2Uf5ng9yznPbtD0mYloSwIuV9FRYx+gzY+8iXd/NQrXHfi6/MhPfPF3d\r\n' + - 'jIqCJAxvld2xgqQimUzoS1a4r7kQQ5c/Iua4LqKeq3ciFzEv/MbZhA==\r\n' + - '-----END PRIVACY-ENHANCED MESSAGE-----\r\n' + - '-----BEGIN RSA PRIVATE KEY-----\r\n' + - 'MIIBPAIBAAJBALjXU+IdHkSkdBscgXf+EBoa55ruAIsU50uDFjFBkp+rWFt5AOGF\r\n' + - '9xL1/HNIby5M64BCw021nJTZKEOmXKdmzYsCAwEAAQJBAApyYRNOgf9vLAC8Q7T8\r\n' + - 'bvyKuLxQ50b1D319EywFgLv1Yn0s/F9F+Rew6c04Q0pIqmuOGUM7z94ul/y5OlNJ\r\n' + - '2cECIQDveEW1ib2+787l7Y0tMeDzf/HQl4MAWdcxXWOeUFK+7QIhAMWZsukutEn9\r\n' + - '9/yqFMt8bL/dclfNn1IAgUL4+dMJ7zdXAiEAhaxGhVKxN28XuCOFhe/s2R/XdQ/O\r\n' + - 'UZjU1bqCzDGcLvUCIGYmxu71Tg7SVFkyM/3eHPozKOFrU2m5CRnuTHhlMl2RAiEA\r\n' + - '0vhM5TEmmNWz0anPVabqDj9TA0z5MsDJQcn5NmO9xnw=\r\n' + - '-----END RSA PRIVATE KEY-----\r\n'; - - describe('pem', function() { - it('should decode and re-encode PEM messages', function() { - var msgs = PEM.decode(_input); - - var output = ''; - for(var i = 0; i < msgs.length; ++i) { - output += PEM.encode(msgs[i]); - } - - ASSERT.equal(output, _input); - }); - }); -} - -// check for AMD -if(typeof define === 'function') { - define([ - 'forge/pem' - ], function(PEM) { - Tests( - // Global provided by test harness - ASSERT, - PEM() - ); - }); -} else if(typeof module === 'object' && module.exports) { - // assume NodeJS - Tests( - require('assert'), - require('../../js/pem')()); -} - -})(); diff --git a/alarm/node_modules/node-forge/nodejs/test/pkcs1.js b/alarm/node_modules/node-forge/nodejs/test/pkcs1.js deleted file mode 100644 index 889eb6d..0000000 --- a/alarm/node_modules/node-forge/nodejs/test/pkcs1.js +++ /dev/null @@ -1,1105 +0,0 @@ -(function() { - -function Tests(ASSERT, PKI, PKCS1, MD, JSBN, UTIL) { - var BigInteger = JSBN.BigInteger; - - // RSA's test vectors for Forge's RSA-OAEP implementation: - // http://www.rsa.com/rsalabs/node.asp?id=2125 - describe('pkcs1', function() { - it('should detect invalid RSAES-OAEP padding', function() { - var keys = makeKey(); - - // provide the seed to test the same input each time - var seed = UTIL.decode64('JRTfRpV1WmeyiOr0kFw27sZv0v0='); - - // test decrypting corrupted data: flip every bit (skip first byte to - // avoid triggering other invalid encryption error) in the message this - // tests the padding error handling - var encoded = PKCS1.encode_rsa_oaep( - keys.publicKey, 'datadatadatadata', {seed: seed}); - var encrypted = keys.publicKey.encrypt(encoded, null); - var bitLength = encrypted.length * 8; - // FIXME: test it too slow to run all the time -- temporary - // change only does partial checks, need a longer term fix - bitLength /= 8; - for(var bit = 8; bit < bitLength; ++bit) { - var byteIndex = bit / 8; - var bitInByte = bit % 8; - - var out = encrypted.substring(0, byteIndex); - var mask = 0x1 << bitInByte; - out += String.fromCharCode(encrypted.charCodeAt(byteIndex) ^ mask); - out += encrypted.substring(byteIndex + 1); - - try { - var decrypted = keys.privateKey.decrypt(out, null); - PKCS1.decode_rsa_oaep(keys.privateKey, decrypted); - throw { - message: 'Expected an exception.' - }; - } catch(e) { - ASSERT.equal(e.message, 'Invalid RSAES-OAEP padding.'); - } - } - }); - - it('should detect leading zero bytes', function() { - var keys = makeKey(); - var message = UTIL.fillString('\x00', 80); - var encoded = PKCS1.encode_rsa_oaep(keys.publicKey, message); - var ciphertext = keys.publicKey.encrypt(encoded, null); - var decrypted = keys.privateKey.decrypt(ciphertext, null); - var decoded = PKCS1.decode_rsa_oaep(keys.privateKey, decrypted); - ASSERT.equal(message, decoded); - }); - - testOAEP(); - testOAEPSHA256(); - - function testOAEP() { - var modulus, exponent, d, p, q, dP, dQ, qInv, pubkey, privateKey; - var examples; - - // Example 1: A 1024-bit RSA Key Pair - // Components of the RSA Key Pair - modulus = 'qLOyhK+OtQs4cDSoYPFGxJGfMYdjzWxVmMiuSBGh4KvEx+CwgtaTpef87Wdc9GaFEncsDLxkp0LGxjD1M8jMcvYq6DPEC/JYQumEu3i9v5fAEH1VvbZi9cTg+rmEXLUUjvc5LdOq/5OuHmtme7PUJHYW1PW6ENTP0ibeiNOfFvs='; - exponent = 'AQAB'; - d = 'UzOc/befyEZqZVxzFqyoXFX9j23YmP2vEZUX709S6P2OJY35P+4YD6DkqylpPNg7FSpVPUrE0YEri5+lrw5/Vf5zBN9BVwkm8zEfFcTWWnMsSDEW7j09LQrzVJrZv3y/t4rYhPhNW+sEck3HNpsx3vN9DPU56c/N095lNynq1dE='; - p = '0yc35yZ//hNBstXA0VCoG1hvsxMr7S+NUmKGSpy58wrzi+RIWY1BOhcu+4AsIazxwRxSDC8mpHHcrSEurHyjnQ=='; - q = 'zIhT0dVNpjD6wAT0cfKBx7iYLYIkpJDtvrM9Pj1cyTxHZXA9HdeRZC8fEWoN2FK+JBmyr3K/6aAw6GCwKItddw=='; - dP = 'DhK/FxjpzvVZm6HDiC/oBGqQh07vzo8szCDk8nQfsKM6OEiuyckwX77L0tdoGZZ9RnGsxkMeQDeWjbN4eOaVwQ=='; - dQ = 'lSl7D5Wi+mfQBwfWCd/U/AXIna/C721upVvsdx6jM3NNklHnkILs2oZu/vE8RZ4aYxOGt+NUyJn18RLKhdcVgw=='; - qInv = 'T0VsUCSTvcDtKrdWo6btTWc1Kml9QhbpMhKxJ6Y9VBHOb6mNXb79cyY+NygUJ0OBgWbtfdY2h90qjKHS9PvY4Q=='; - pubkey = decodeBase64PublicKey(modulus, exponent); - privateKey = decodeBase64PrivateKey(modulus, exponent, d, p, q, dP, dQ, qInv); - - examples = [{ - title: 'RSAES-OAEP Encryption Example 1.1', - message: 'ZigZThIHPbA7qUzanvlTI5fVDbp5uYcASv7+NA==', - seed: 'GLd26iEGnWl3ajPpa61I4d2gpe8=', - encrypted: 'NU/me0oSbV01/jbHd3kaP3uhPe9ITi05CK/3IvrUaPshaW3pXQvpEcLTF0+K/MIBA197bY5pQC3lRRYYwhpTX6nXv8W43Z/CQ/jPkn2zEyLW6IHqqRqZYXDmV6BaJmQm2YyIAD+Ed8EicJSg2foejEAkMJzh7My1IQA11HrHLoo=' - }, { - title: 'RSAES-OAEP Encryption Example 1.2', - message: 'dQxAR/VH6OQUEYVlIymKybriRe+vE5f75W+d1Q==', - seed: 'DMdCzkqbfzL5UbyyUe/ZJf5P418=', - encrypted: 'ZA2xrMWOBWj+VAfl+bcB3/jDyR5xbFNvx/zsbLW3HBFlmI1KJ54Vd9cw/Hopky4/AMgVFSNtjY4xAXp6Cd9DUtkEzet5qlg63MMeppikwFKD2rqQib5UkfZ8Gk7kjcdLu+ZkOu+EZnm0yzlaNS1e0RWRLfaW/+BwKTKUbXFJK0Q=' - }, { - title: 'RSAES-OAEP Encryption Example 1.3', - message: '2Urggy5kRc5CMxywbVMagrHbS6rTD3RtyRbfJNTjwkUf/1mmQj6w4dAtT+ZGz2md/YGMbpewUQ==', - seed: 'JRTfRpV1WmeyiOr0kFw27sZv0v0=', - encrypted: 'Qjc27QNfYCavJ2w1wLN0GzZeX3bKCRtOjCni8L7+5gNZWqgyLWAtLmJeleuBsvHJck6CLsp224YYzwnFNDUDpDYINbWQO8Y344efsF4O8yaF1a7FBnzXzJb+SyZwturDBmsfz1aGtoWJqvt9YpsC2PhiXKODNiTUgA+wgbHPlOs=' - }, { - title: 'RSAES-OAEP Encryption Example 1.4', - message: 'UuZQ2Y5/KgSLT4aFIVO5fgHdMW80ahn2eoU=', - seed: 'xENaPhoYpotoIENikKN877hds/s=', - encrypted: 'RerUylUeZiyYAPGsqCg7BSXmq64wvktKunYvpA/T044iq+/Gl5T267vAXduxEhYkfS9BL9D7qHxuOs2IiBNkb9DkjnhSBPnD9z1tgjlWJyLd3Ydx/sSLg6Me5vWSxM/UvIgXTzsToRKq47n3uA4PxvclW6iA3H2AIeIq1qhfB1U=' - }, { - title: 'RSAES-OAEP Encryption Example 1.5', - message: 'jaif2eX5dKKf7/tGK0kYD2z56AI=', - seed: 'sxjELfO+D4P+qCP1p7R+1eQlo7U=', - encrypted: 'NvbjTZSo002qy6M6ITnQCthak0WoYFHnMHFiAFa5IOIZAFhVohOg8jiXzc1zG0UlfHd/6QggK+/dC1g4axJE6gz1OaBdXRAynaROEwMP12Dc1kTP7yCU0ZENP0M+HHxt0YvB8t9/ZD1mL7ndN+rZBZGQ9PpmyjnoacTrRJy9xDk=' - }, { - title: 'RSAES-OAEP Encryption Example 1.6', - message: 'JlIQUIRCcQ==', - seed: '5OwJgsIzbzpnf2o1YXTrDOiHq8I=', - encrypted: 'Qs7iYXsezqTbP0gpOG+9Ydr78DjhgNg3yWNm3yTAl7SrD6xr31kNghyfEGQuaBrQW414s3jA9Gzi+tY/dOCtPfBrB11+tfVjb41AO5BZynYbXGK7UqpFAC6nC6rOCN7SQ7nYy9YqaK3iZYMrVlZOQ6b6Qu0ZmgmXaXQt8VOeglU=' - }]; - checkOAEPEncryptExamples(pubkey, privateKey, 'sha1', examples); - - // Example 2: A 1025-bit RSA Key Pair - // Components of the RSA Key Pair - modulus = 'AZR8f86QQl9HJ55whR8l1eYjFv6KHfGTcePmKOJgVD5JAe9ggfaMC4FBGQ0q6Nq6fRJQ7G22NulE7Dcih3x8HQpn8UsWlMXwN5RRpD5Joy3eg2cLc9qRocmbwjtDamAFXGEPC6+ZwaB5VluVo/FSZjLR1Npg8g7aJeZTxPACdm9F'; - exponent = 'AQAB'; - d = 'CCPyD6212okIip0AiT4h+kobEfvJPGSjvguq6pf7O5PD/3E3BMGcljwdEHqumQVHOfeeAuGG3ob4em3e/qbYzNHTyBpHv6clW+IGAaSksvCKFnteJ51xWxtFW91+qyRZQdl2i5rO+zzNpZUto87nJSW0UBZjqO4VyemS2SRi/jk='; - p = 'AVnb3gSjPvBvtgi4CxkPTT4ivME6yOSggQM6v6QW7bCzOKoItXMJ6lpSQOfcblQ3jGlBTDHZfdsfQG2zdpzEGkM='; - q = 'AStlLzBAOzi0CZX9b/QaGsyK2nA3Mja3IC05su4wz7RtsJUR9vMHzGHMIWBsGKdbimL4It8DG6DfDa/VUG9Wi9c='; - dP = 'Q271CN5zZRnC2kxYDZjILLdFKj+1763Ducd4mhvGWE95Wt270yQ5x0aGVS7LbCwwek069/U57sFXJIx7MfGiVQ=='; - dQ = 'ASsVqJ89+ys5Bz5z8CvdDBp7N53UNfBc3eLv+eRilIt87GLukFDV4IFuB4WoVrSRCNy3XzaDh00cpjKaGQEwZv8='; - qInv = 'AnDbF9WRSwGNdhGLJDiac1Dsg2sAY6IXISNv2O222JtR5+64e2EbcTLLfqc1bCMVHB53UVB8eG2e4XlBcKjI6A=='; - pubkey = decodeBase64PublicKey(modulus, exponent); - privateKey = decodeBase64PrivateKey(modulus, exponent, d, p, q, dP, dQ, qInv); - - examples = [{ - title: 'RSAES-OAEP Encryption Example 2.1', - message: 'j/AMqmBccCgwY02abD1CxlK1jPHZL+xXC+7n', - seed: 'jEB7XsKJnlCZxT6M55O/lOcbF4I=', - encrypted: 'AYGviSK5/LTXnZLr4ZgVmS/AwUOdi81JE5ig9K06Mppb2ThVYNtTJoPIt9oE5LEq7Wqs30ccNMnNqJGt3MLfNFZlOqY4Lprlm1RFUlfrCZ1WK74QRT8rbRPFnALhDx+Ku12g0FcJMtrPLQkB23KdD+/MBU5wlo6lQMgbBLyu/nIO' - }, { - title: 'RSAES-OAEP Encryption Example 2.2', - message: 'LQ==', - seed: 'tgDPPC5QbX8Wd4yRDTqLAD7uYdU=', - encrypted: 'AYdZ/x32OyeSQQViMUQWqK6vKsY0tG+UCrgtZNvxZe7jMBHadJ1Lq24vzRgSnJ5JJ32EUxErQpoiKoRxsHCZOZjnWIYcTT9tdJ2RxCkNMyx6SrP36jX/OgfUl8lV/w/8lQBrYsbSloENm/qwJBlseTQBLC35eO8pmrojmUDLoQJF' - }, { - title: 'RSAES-OAEP Encryption Example 2.3', - message: 'dPyIxRvJD3evnV6aSnATPUtOCzTaPDfH744=', - seed: 'pzdoruqpH52MHtb50rY0Z/B8yuM=', - encrypted: 'AYgCurBMYDJegcSWIxHyvnwq3OkwQaAHGciPlXV18sefG3vIztEVxwazEcCKLZhso7apM2sUfCnG8ilAnd7GUb0f3VoLf2EMmTf9tKOnYjZLizIGtOpIX9CY0I9j1KqLsml9Ant1DDLX906vUYDS6bZrF8svpVUjvCgNoQ0UviBT' - }, { - title: 'RSAES-OAEP Encryption Example 2.4', - message: 'p+sqUDaTHSfU6JEybZlpL/rdqb9+/T405iLErcCF9yHf6IUHLHiiA7FRc5vlQPqMFToQ8Ao=', - seed: 'mns7DnCL2W+BkOyrT7mys4BagVY=', - encrypted: 'AKRXjLwXYximOPun0B3xV0avRNT2zZbX58SVy/QlsJxknTK/iG2kj7r5iaIRcYfK+x+1gDF2kOPM1EaSC3r4KzHbWATYfQFRSsv6kVbngvhn9r7ZRJ4OmiwJvOzGqgh2NpZeNLPsdm8v4uQwGKL93rFAYWoOnYLlMxAk7gZS/HZB' - }, { - title: 'RSAES-OAEP Encryption Example 2.5', - message: 'LvKwZvhUwz873LtZlKQ15z1sbA==', - seed: '6zzrvErcFrtI6IyK7A40r39Cf9M=', - encrypted: 'AOvF9f2nfP2tPINkGpAl531y2Kb7M6gQ9ZUPjXTHPo2THoY02GqxJGJWrge2AFtxt/L7mDUSGDMc5puP+9ydoIu8nHBPh23rnfn8LsBlyth/kJCweswXqn+ZeyespIgG6Jf3cdlRQf5FJtilMBtnhifvq3B/1A++vW55KiVhPnrs' - }, { - title: 'RSAES-OAEP Encryption Example 2.6', - message: 'in+zRMi2yyzy7x9kP5oyGPbhm7qJwA==', - seed: 'TEXPTVfJjj1tIJWtxRxInrUN/4Q=', - encrypted: 'AQg57CDCe5BS5Vvvubd+b8JukHXXpUN4xkar31HkRb1XFd6BeJ9W8YA9kXB2Sp6Ty3h5hpQCPuc5POBLxdj4xaUsFx1Dg346ymL2CesKpf+wlg7wQZjddU9X9/vmq/dlzxGLTKRDsjtaqyZvlSMmrEWBEAZEMl+LchrNXQT/FO86' - }]; - checkOAEPEncryptExamples(pubkey, privateKey, 'sha1', examples); - - // Example 3: A 1026-bit RSA Key Pair - // Components of the RSA Key Pair - modulus = 'ArWP7AOahgcApNe2Ri+T5s3UkRYd3XT06BC0DjwWUgBqXCd7J3TBEwWky6taeO+lfheobfej+jb8Sx0iSfIux8LdakYyMqzOqQbWbr6AtXBLEHKdpvgzI0q7Xv3UopLL+tM7TTP6ehS4w5e1bjrNISA0KLd836M6bacGs9iw/EPp'; - exponent = 'AQAB'; - d = 'FbSKW1aDqUZw4jtXGPgU+g4T+FA49QcRGCy6YVEFgfPSLH4jLvk34i5VHWi4bi+MsarYvi5Ij13379J54/Vo1Orzb4DPcUGs5g/MkRP7bEqEH9ULvHxRL/y+/yFIeqgR6zyoxiAFNGqG3oa/odipSP0/NIwi6q3zM8PObOEyCP0='; - p = 'Ab8B0hbXNZXPAnDCvreNQKDYRH0x2pGamD9+6ngbd9hf43Gz6Tc+e2khfTFQoC2JWN5/rZ1VUWCVi0RUEn4Ofq8='; - q = 'AY0zmWWBZts4KYFteylUFnWenJGYf1stiuzWOwS0i9ey/PIpu3+KbciLoT3S45rVW20aBhYHCPlwC+gLj9N0TOc='; - dP = 'BsCiSdIKby7nXIi0lNU/aq6ZqkJ8iMKLFjp2lEXl85DPQMJ0/W6mMppc58fOA6IVg5buKnhFeG4J4ohalyjk5Q=='; - dQ = '0dJ8Kf7dkthsNI7dDMv6wU90bgUc4dGBHfNdYfLuHJfUvygEgC9kJxh7qOkKivRCQ7QHmwNEXmAuKfpRk+ZP6Q=='; - qInv = 'jLL3Vr2JQbHTt3DlrTHuNzsorNpp/5tvQP5Xi58a+4WDb5Yn03rP9zwneeY0uyYBHCyPfzNhriqepl7WieNjmg=='; - pubkey = decodeBase64PublicKey(modulus, exponent); - privateKey = decodeBase64PrivateKey(modulus, exponent, d, p, q, dP, dQ, qInv); - - examples = [{ - title: 'RSAES-OAEP Encryption Example 3.1', - message: 'CHggtWno+o0=', - seed: 'jO1rGWKQgFeQ6QkHQBXmogsMSJQ=', - encrypted: 'AmoEhdlq69lrQ4IIUJm5Yuaivew9kMjbYl4UNy3oXi1be6q2XI+vkbtVBPtJWvzlyYiz9qUuIOHWy9NWbFzR8rgxi7VCzA6iXEqrmTKvogdg6t3seEOWoH6g7yTU5vTTflBSp6MeFGqkgKERu+kmQBMH4A9BADOEK22C/lzk366A' - }, { - title: 'RSAES-OAEP Encryption Example 3.2', - message: 'RlOsrxcZYLAfUqe+Y6OrIdw2jsQ7UNguw3geBA==', - seed: 'tCkdZWdVCEjMFWlnyAm6q2ylB/A=', - encrypted: 'Ak24nHgCmJvgeDhHhjCElBvyCddhmH44+Xy19vG8iNpypQtz668RyHnE+V3ze4ULj2XXYi4lsbiJ6A/oC6yiBp1uDh2CmVP8RZBp3pjql5i0UeVX6Zq/j+PZzPkJbrvz5SVdO04cbS7K3wZ6NZ7qhkBazUfV4WVRfMr9R9bb7kv1' - }, { - title: 'RSAES-OAEP Encryption Example 3.3', - message: '2UzQ4I+kBO2J', - seed: 'zoko9gWVWCVACLrdl5T63NL9H2U=', - encrypted: 'Ajm85oEDJEFSiHfW0ci7KKo7yX8d9YRWNhiZV5doOETKhmZHMvS+16CqsIOqq/tyOPWC4wlYwgJOROVwQ7l5UP1UPal3yQzd5TN9YYRC+Z5g13g6tZzm3Z1pxHrR6WK+wi0FiVz/jT9k7VJh2SsmeFEDk0hJkLo/fwaBiub/zoo6' - }, { - title: 'RSAES-OAEP Encryption Example 3.4', - message: 'bMZBtrYeb5Y5dNrSOpATKE7x', - seed: 'bil59S1oFKV9g7CQBUiI8RmluaM=', - encrypted: 'AplMYq/Xb0mLof0s9kKFf8qB9Dc8sI8cuu5vAlw7UStCw+h3kRNHZkgDnb4Ek/kkYpL6wolQYA58DzLt+cgbnexFw73gzI2IR1kBaZB7fcWZHOspuwcU1hPZbfDxLsXY01B8jueueN2D8hb6Yd4QA2OspIp+kUrp9C3fvpQ7Cdmg' - }, { - title: 'RSAES-OAEP Encryption Example 3.5', - message: '31FRgyth9PJYkftBcvMo0u3fg3H/z9vpl5OSlfMOymkYAXz9oRU796avh1kyIw==', - seed: 'LXYL/jjFneNM3IuMeKOOZihKLSc=', - encrypted: 'AWIEL/aWlZKmFnAxgRojmDTOY4q/VP7IuZR4Eir+LuZ/jFsYsDOYBb/bxaTmcgs3xZz7qUJGTFl/9TKhGYIVRf0uWbEU5h2vcYIFKfUCnPUklUMnw07F5vW6fvzE3pQ6uK1O14exRUMp9w23mKOo9NkvgnTispSK3mJ86O4z5Dxg' - }, { - title: 'RSAES-OAEP Encryption Example 3.6', - message: 'PDutiTxUSm1SCrAiMZGIyNUEt6eIuFCQO4WXLqoYVS4RNKetYJiCYlT/erZys9jrMVj6xtTLrvE=', - seed: '8XR3nF/Tz+AHuty3o2ybVb/Pvw4=', - encrypted: 'ABEgUeddBklDvER4B15DSC/VnO4Ged5ok+7DqUPapJC5aRyT38BGS2YjufPb0+cAgyZPA0s3T3QWThoAdjcl5XR0S6C524NDTzHflvbiom9tjro0i9RobCI4rAfDeqw3hdHH7qL4Gf2RSReY7Y6c715Dt4Gw4CduN8Q/+UktAFcw' - }]; - checkOAEPEncryptExamples(pubkey, privateKey, 'sha1', examples); - - // Example 4: A 1027-bit RSA Key Pair - // Components of the RSA Key Pair - modulus = 'BRJAtswABPpI0BNGccB4x8jew7Pi8lvCVkRnM52ziFPQa4XupbLeNTv/QqwuRryX+uaslhjalTelyPVTweNXYlmR1hCNzXiF+zolQT9T78rZSMs1zZua6cHGdibRE9V93kxb6na7W7felsANBzculoWm11z50jn6FI1wkxtfP7A5'; - exponent = 'AQAB'; - d = 'BBH/yjt8penpvn/jioUQXjU4ltsFxXlq7NKnJRYes2UchimpuGK5BNewx7N/jLWhwrVAAQGKAKHrLK/k7k6UksNIvCvtq0ueu/Bk6O/zIrkAn47sZTkF9A34ijzcSdRWf3VifUGspiQSm0agt8aY5eZfK3uhAsdJoQE1tlQNBAE='; - p = 'AnRYwZ7BY2kZ5zbJryXWCaUbj1YdGca/aUPdHuGriko/IyEAvUC4jezGuiNVSLbveSoRyd6CPQp5IscJW266VwE='; - q = 'AhDumzOrYXFuJ9JRvUZfSzWhojLi2gCQHClL8iNQzkkNCZ9kK1N1YS22O6HyA4ZJK/BNNLPCK865CdE0QbU7UTk='; - dP = 'OfoCi4JuiMESG3UKiyQvqaNcW2a9/R+mN9PMSKhKT0V6GU53J+Sfe8xuWlpBJlf8RwxzIuvDdBbvRYwweowJAQ=='; - dQ = 'AV2ZqEGVlDl5+p4b4sPBtp9DL0b9A+R9W++7v9ax0Tcdg++zMKPgIJQrL+0RXl0CviT9kskBnRzs1t1M8eVMyJk='; - qInv = 'AfC3AVFws/XkIiO6MDAcQabYfLtw4wy308Z9JUc9sfbL8D4/kSbj6XloJ5qGWywrQmUkz8UqaD0x7TDrmEvkEro='; - pubkey = decodeBase64PublicKey(modulus, exponent); - privateKey = decodeBase64PrivateKey(modulus, exponent, d, p, q, dP, dQ, qInv); - - examples = [{ - title: 'RSAES-OAEP Encryption Example 4.1', - message: 'SoZglTTuQ0psvKP36WLnbUVeMmTBn2Bfbl/2E3xlxW1/s0TNUryTN089FmyfDG+cUGutGTMJctI=', - seed: 'HKwZzpk971X5ggP2hSiWyVzMofM=', - encrypted: 'BMzhlhSEXglBUqP+GOVOMzDETl77xkrhaIbLGGkBTMV4Gx+PngRThNARKhNcoNEunIio5AY0Ft6q44RPYNbpb+FVFF9FJbmjRDHKN2YYD3DhWl5djosaUW/4cGCfE/iWk1ztGIJ5pY7RPQcRQnfXXGVoYH4KsJL9gDoiPkqO4LGo' - }, { - title: 'RSAES-OAEP Encryption Example 4.2', - message: 'sK3E8/4R2lnOmSdz2QWZQ8AwRkl+6dn5oG3xFm20bZj1jSfsB0wC7ubL4kSci5/FCAxcP0QzCSUS7EaqeTdDyA==', - seed: '9UXViXWF49txqgy42nbFHQMq6WM=', - encrypted: 'AJe2mMYWVkWzA0hvv1oqRHnA7oWIm1QabwuFjWtll7E7hU60+DmvAzmagNeb2mV4yEH5DWRXFbKA03FDmS3RhsgLlJt3XK6XNw5OyXRDE2xtpITpcP/bEyOiCEeCHTsYOB3hO7SarqZlMMSkuCcfPq4XLNNm4H5mNvEBnSoortFe' - }, { - title: 'RSAES-OAEP Encryption Example 4.3', - message: 'v21C5wFwex0CBrDItFoccmQf8SiJIZqCveqWW155qWsNAWPtnVeOya2iDy+88eo8QInYNBm6gbDGDzYG2pk=', - seed: 'rZl/7vcw1up75g0NxS5y6sv90nU=', - encrypted: 'AwH5NenEery0isu+CYldn1lxrxSDnaT/lUF+5FPR/XcxkHK7cpfhtV11Yc2dG7JMGpo3xhmGQwgkKASHnYbr0AHc5Rg5deFQaYm3DlqDQ0FU1cv9aiR4fmDrDGWNKsGTMC0RksbmItShKtS1OSO8okbfMcY5XjdwLGp4rggfudBl' - }, { - title: 'RSAES-OAEP Encryption Example 4.4', - message: '+y7xEvXnZuuUAZKXk0eU974vb8HFjg==', - seed: 'E2RU31cw9zyAen5A2MGjEqxbndM=', - encrypted: 'AtEQrTCvtye+tpHdDPF9CvGh5/oMwEDsGkuiakLFnQp5ai4iyPNXzMmLZRms62gulF5iy3NGFKUpQHzUUr7j5E/s6EI8wZ5VVIuLmUuEnH7N5JM+dgN+HQzkQnWwhxDGjkMBMLkpcw7XfgmwFWQsVZPwTk/7lBB5gQKo6W/9/hHk' - }, { - title: 'RSAES-OAEP Encryption Example 4.5', - message: 'KMzUR7uehRZtq7nlt9GtrcS5058gTpbV5EDOmtkovBwihA==', - seed: 'vKgFf4JLLqJX8oYUB+72PTMghoE=', - encrypted: 'ANu4p0OdkO/ZGaN3xU+uj+EexYw7hYNi4jrRuKRDEHmQZrmTR6pSVpHSrcWNmwbjTyiMFwOQxfDhHAqjZFlZ8Y7nno8r6NesXCPQYfGN10uMXypY/LXrDFT5nwGoMkdWgpJTZYM0CUjXqMl8Ss0emNHincMg6XomBTKoqnp1ih7C' - }, { - title: 'RSAES-OAEP Encryption Example 4.6', - message: '8iJCdR7GsQ==', - seed: 'Ln4eF/ZHtd3QM+FUcvkPaBLzrE4=', - encrypted: 'AKX/pHaMi77K7i23fo8u7JlZWTNUVSCDXlun25ST0+F83e/mpfVnYkRxkI204tg6D77mBgj8hASVA7IjSgfcg7J7IoR62JIP9C9nTvebdigLACM9K1G4yycDqdQr+8glDJbsMsBR5X8bS6Uo24nDfkxU4n5uZKxpY1roh9lUFhmp' - }]; - checkOAEPEncryptExamples(pubkey, privateKey, 'sha1', examples); - - // Example 5: A 1028-bit RSA Key Pair - // Components of the RSA Key Pair - modulus = 'Cq3z+cEl5diR8xrESOmT3v5YD4ArRfnX8iulAh6cR1drWh5oAxup205tq+TZah1vPSZyaM/0CABfEY78rbmYiNHCNEZxZrKiuEmgWoicBgrA2gxfrotV8wm6YucDdC+gMm8tELARAhSJ/0l3cBkNiV/Tn1IpPDnv1zppi9q58Q7Z'; - exponent = 'AQAB'; - d = 'AlbrTLpwZ/LSvlQNzf9FgqNrfTHRyQmbshS3mEhGaiaPgPWKSawEwONkiTSgIGwEU3wZsjZkOmCCcyFE33X6IXWI95RoK+iRaCdtxybFwMvbhNMbvybQpDr0lXF/fVKKz+40FWH2/zyuBcV4+EcNloL5wNBy+fYGi1bViA9oK+LF'; - p = 'A7DTli9tF1Scv8oRKUNI3PDn45+MK8aCTyFktgbWh4YNrh5jI5PP7fUTIoIpBp4vYOSs1+YzpDYGP4I4X0iZNwc='; - q = 'AuTDLi9Rcmm3ByMJ8AwOMTZffOKLI2uCkS3yOavzlXLPDtYEsCmC5TVkxS1qBTl95cBSov3cFB73GJg2NGrrMx8='; - dP = 'AehLEZ0lFh+mewAlalvZtkXSsjLssFsBUYACmohiKtw/CbOurN5hYat83iLCrSbneX31TgcsvTsmc4ALPkM429U='; - dQ = '65CqGkATW0zqBxl87ciBm+Hny/8lR2YhFvRlpKn0h6sS87pP7xOCImWmUpfZi3ve2TcuP/6Bo4s+lgD+0FV1Tw=='; - qInv = 'AS9/gTj5QEBi64WkKSRSCzj1u4hqAZb0i7jc6mD9kswCfxjngVijSlxdX4YKD2wEBxp9ATEsBlBi8etIt50cg8s='; - pubkey = decodeBase64PublicKey(modulus, exponent); - privateKey = decodeBase64PrivateKey(modulus, exponent, d, p, q, dP, dQ, qInv); - - examples = [{ - title: 'RSAES-OAEP Encryption Example 5.1', - message: 'r3GpAeOmHTEy8Pwf20dPnqZXklf/wk0WQXAUWz296A==', - seed: 'RMkuKD93uUmcYD2WNmDIfS+TlGE=', - encrypted: 'A2BGpKR9ntO6mokTnBBQOOt0krBaXWi/1TrM/0WX96aGUbR7SkYn2Sfkhe7XtFZkIOi0CYeeXWBuriUdIqXfeZ95IL/BF7mSVypTsSYxRrzqAzhcxehTyaEByMPhvaMaUZgHSWxsteXvtAiCOjUrj6BmH7Zk763Vk965n/9e0ADl' - }, { - title: 'RSAES-OAEP Encryption Example 5.2', - message: 'o7hEoII5qKxBYFrxemz9pNNQE2WFkDpBenkmh2BRmktKwzA+xz8Ph8+zI5k=', - seed: 'yyj1hgZZ/O7knD7q/OYlpwgDvTI=', - encrypted: 'A9brZU7c5hW8WfRVJl7U5aGCI8u5vk5AabRzgE1d6W9U3KqmA9BJxdlKoUcN/NIlQGa3x7Yf8fb2dw4yFcUTmf1ONOxQgrxI8ImECtBDVK5m3A8b0Y5GGjPMEli0Q6KDem3yZ1mqIwIzSYb4c4DJzJ1Tvp+ZYF0smpfaewkVpKet' - }, { - title: 'RSAES-OAEP Encryption Example 5.3', - message: 'MIsOy9LHbLd/xvcMXt0jP9LyCSnWKfAmlTu2Ko9KOjFL3hld6FtfgW2iqrB00my2rN3zI647nGeKw88S+93n', - seed: 'IoX0DXcEgvmp76LHLLOsVXFtwMo=', - encrypted: 'B3CVIYFkn5+fB/9ib/OiLDXEYkQ9kF1Fap/Qv/Q8rCynqfVU6UeLmsw6yDiwIED/0+GEfeLkJTkp+d2e5ARDJamwXKu4CLLuhA004V0QWj8feydpWhoHotc/4I7KqjycnU1aif+JDVRyfXrkDA7BqN2GFl2O4sY2gUEBaki1W2ln' - }, { - title: 'RSAES-OAEP Encryption Example 5.4', - message: 'FcW57hGF', - seed: 'SfpF06eN0Q39V3OZ0esAr37tVRM=', - encrypted: 'CBK3Z2jry2QtBAJY5fREGgGFIb2WaH5sXomfzWwXWI/1moLMiuA6S0WzEpmvF4jDKffc0oX4z0ztgmBrl2EmcaRb7coTNEIUTRYX0RT4AoV/D51zl1HFej+e5ACRLGHi5pkr4DGkPdSPproU7vfEIrXtxOevoE/dOPQC0ci7cZq/' - }, { - title: 'RSAES-OAEP Encryption Example 5.5', - message: 'IQJuaADH+nKPyqug0ZauKNeirE/9irznlPCYX2DIpnNydzZdP+oR24kjogKa', - seed: '8Ch0EyNMxQNHJKCUxFhrh6/xM/w=', - encrypted: 'B7YOFOyVS/0p5g0AR+eJ9R1XGGxjWJkDMGeTztP2gkHHQ1KaumpjdPkuGeAWPvozaX4Zb3Zh36qkeqxr3l5R3rUHxyxYmiyhaT2WsUYDgSSbLNuerER2nySJxdPS+Z8O48fuW/ZKWsecQr1DPxSb6MtZVINhZAWVUTyXr3vCUJcj' - }, { - title: 'RSAES-OAEP Encryption Example 5.6', - message: 'VB43totsiHK4TAI=', - seed: '2fukXJbyHm4m0p6yzctlhb6cs0E=', - encrypted: 'CMNtTdozQjsu1oMNhfZBG6Hc9HCh+uDr7+58CJ8lbO90y5bqacOPYPOavuRBKby0yS3n95diOyAHTj2cKJlwHtkHHh76C92E1MPlEwMC2PAkC6ukuEpxzAMvIjWl/w+uJ3w+j5ESvvRMmuINF1/JpAWL/JMLoxsC4uT0REg3EPJK' - }]; - checkOAEPEncryptExamples(pubkey, privateKey, 'sha1', examples); - - // Example 6: A 1029-bit RSA Key Pair - // Components of the RSA Key Pair - modulus = 'ErF/ba0uzRn/RtwT94YPCeDgz7Z3s4pSWSMFzq8CLBZtuQ0ErCnjP33RLZ+vZuCBa7Y+rSZ8x9RsF8N74hS8oqItcjpk5EQHQ2tvyWVymu/CVU83bNXc6mgpN4CmK/OdAClIWhYLu55dwJctIaUE9S5e4CiqQWMy9RCy6c/19yKv'; - exponent = 'AQAB'; - d = 'ApXso1YGGDaVWc7NMDqpz9r8HZ8GlZ33X/75KaqJaWG80ZDcaZftp/WWPnJNB7TcEfMGXlrpfZaDURIoC5CEuxTyoh69ToidQbnEEy7BlW/KuLsv7QV1iEk2Uixf99MyYZBIJOfK3uTguzctJFfPeOK9EoYij/g/EHMc5jyQz/P5'; - p = 'BKbOi3NY36ab3PdCYXAFr7U4X186WKJO90oiqMBct8w469TMnZqdeJpizQ9g8MuUHTQjyWku+k/jrf8pDEdJo4s='; - q = 'BATJqAM3H+20xb4588ALAJ5eCKY74eQANc2spQEcxwHPfuvLmfD/4Xz9Ckv3vv0t1TaslG23l/28Sr6PKTSbke0='; - dP = 'A5Ycj3YKor1RVMeq/XciWzus0BOa57WUjqMxH8zYb7lcda+nZyhLmy3lWVcvFdjQRMfrg6G+X63yzDd8DYR1KUs='; - dQ = 'AiGX4GZ0IZaqvAP6L+605wsVy3h9YXrNMbt1x7wjStcG98SNIYLR8P+cIo3PQZZ7bAum0sCtEQobhXgx7CReLLE='; - qInv = 'BAHEwMU9RdvbXp2W0P7PQnXfCXS8Sgc2tKdMMmkFPvtoas4kBuIsngWN20rlQGJ64v2wgmHo5+S8vJlNqvowXEU='; - pubkey = decodeBase64PublicKey(modulus, exponent); - privateKey = decodeBase64PrivateKey(modulus, exponent, d, p, q, dP, dQ, qInv); - - examples = [{ - title: 'RSAES-OAEP Encryption Example 6.1', - message: 'QEbKi6ozR8on9J4NgfnMHXG+m6UX1A==', - seed: '3Q9s/kFeiOWkaaUfu6bf1ArbQ4Q=', - encrypted: 'BjDuvNKFbCT3mIBuQfnmc0Xtqc7aOGrMn6yuoe7tBqzlg3CXGNnRafrfQU1cdvkploM+8wW3Wx5LlfZiog+u3DuuDEgnqL+KiO29V+wgOieoQfAuQ6YVurGoysBwHeNN6972KgiAibVew26nUi/T7I0GtqBz5t+DMVO8Cu/ZO9Gj' - }, { - title: 'RSAES-OAEP Encryption Example 6.2', - message: 'XMcsYCMd8Ds9QPm1eTG8MRCflyUn8osZ50gMcojLPJKyJRIhTkvmyRR5Ldq99X+qiqc=', - seed: 'jRS9lGoTURSPXK4u2aDGU+hevYU=', - encrypted: 'Drw3N2FzpP0vicxVwspismsR1Rw8fOSeiEX3TnYHMXxDa8jSO5Zn3+udCHI0tHvGg3F1rlwFWfa4HX0iQW0+UPSsUz2PCBLy2555H+nHdayLatD1Na2c6yOkoCAUxYqz+NMWFJmiYPOTSOcUriodNEMgj9i3Isz9+zk+mAEfmeY/' - }, { - title: 'RSAES-OAEP Encryption Example 6.3', - message: 'sg5lEwMJL0vMtDBwwPhtIwSTYu2WZC/FYywn20pS49gx8qsGiyOxSYecAC9r8/7ul1kRElYs', - seed: 'bAdbxFUg8WXAv16kxd8ZG8nvDkQ=', - encrypted: 'Cpi/EJNhk5RDbPaNjzji8Vj96OpU80NfI5uNBrgyGEQgJHau7ZYAlJJIDOOo1wVJjEyMaPAVAdyB22CPYAhzUMjDsL0unvaoFFi3yAG4ny5P6Z1JALpqS15althl3Gdsd1WSh5QTDWKAqBYKGQ8t8+p8+aoCcdiOnmkF7PHFFS1l' - }, { - title: 'RSAES-OAEP Encryption Example 6.4', - message: 'aE4wOMXAQfc=', - seed: 'O7w71mN9/hKEaQECm/WwwHEDQ5w=', - encrypted: 'AI56Z8rPtcTiS+x97hSRF/GVmM6MRYCP74jGCP+c1uaVJjuaPArUuLpMlSOOlqhCK4U1YpyNU4I3RHmtE/o5l0skL5p1nur5yDrVqMoYlAoBYrp1WHbfJj9L1QxlJcVgkCZ8Hw4JzgiZoM81nogSCr2b+JNEWzyud9Ngc1mumlL4' - }, { - title: 'RSAES-OAEP Encryption Example 6.5', - message: 'MkiMsmLQQdbk3TX5h788ppbbHwasKaRGkw==', - seed: 'tGtBiT6L7zJvZ1k4OoMHHa5/yrw=', - encrypted: 'AAA0dEFse2i9+WHDhXN5RNfx9AyzlTQ8aTzAtP5jsx/t8erurJzMBnizHcMuCXdIlRTE8JCF9imKllPwGupARf9YLuiHviauV1tz7vfzd0kh43Wj0ZrdoMoxqhhJiHwfQsrJZ396L06SP25ahos4wITvGHWU3J9/BI/qLgKVU4Sr' - }, { - title: 'RSAES-OAEP Encryption Example 6.6', - message: 'ULoUvoRicgJ5wwa6', - seed: 'CiQDMSpB49UvBg+8E6Z95c92Cac=', - encrypted: 'CgJt2l/IeF972b91Mntj6F4sD97l2ttl69ysmuHelcksZyq0M6p6jmnOam2Il/rErEpU3oQa5eW7znaHh515Y0zqejBoQGXHFNUkCbkoJWu/U+q81SMetyWVBFNzmb0pFktybTOkbacBNgpBaKCRzKty1Epi/tJGwP/qWxNIq1Rw' - }]; - checkOAEPEncryptExamples(pubkey, privateKey, 'sha1', examples); - - // Example 7: A 1030-bit RSA Key Pair - // Components of the RSA Key Pair - modulus = 'MRF58Lz8m508oxXQDvMNe906LPrpkRv+3LlIs6R4LQcytqtEqkvwN0GmRNwBvsPmmwGgM+Z12KzXxJJcaxrsMRkFHf2Jdi0hXUVHX/y1n5CBSGI/NxdxVvauht16fF9D3B4fkIJUBYooSl8GwAIXk6h/GsX+/33K7mnF5Ro3ieNz'; - exponent = 'AQAB'; - d = 'Bwz8/y/rgnbidDLEXf7kj0m3kX1lMOHwyjRg8y4CdhdEh8VuIqRdJQDXd1SVIZ19Flqc872Swyr5qY2NycwpaACtyUoKVPtA80KRv4TujqErbxCTWcbTVCpQ+cdn9c//BaaBwuZW+3fKqttL6UaNirzU35j1jobSBT+hNJ90jiGx'; - p = 'B0kmLBEc1HDsJWbms3MvwJMpRpqhkHHTucAZBlFMbx0muqFL6rCXHIt+YRpPeQCdb+p3aSjKJShbDeNkPRo/jHE='; - q = 'BrweUOlsAr9jbp7qi4mbvr92Ud533UdMPpvCO62BgrYZBMfZffvr+x4AEIh4tuZ+QVOR1nlCwrK/m0Q1+IsMsCM='; - dP = 'A7x+p/CqsUOrxs6LlxGGNqMBcuTP4CyPoN2jt7qvkPgJKYKYVSX0iL38tL1ybiJjmsZKMJKrf/y/HVM0z6ULW/E='; - dQ = 'AmKmqinCo8Z9xTRsBjga/Zh6o8yTz7/s9U/dn514fX9ZpSPTmJedoTei9jgf6UgB98lNohUY3DTLQIcMRpeZStk='; - qInv = 'ZJ1MF7buFyHnctA4mlWcPTzflVDUV8RrA3t0ZBsdUhZq+KITyDliBs37pEIvGNb2Hby10hTJcb9IKuuXanNwwg=='; - pubkey = decodeBase64PublicKey(modulus, exponent); - privateKey = decodeBase64PrivateKey(modulus, exponent, d, p, q, dP, dQ, qInv); - - examples = [{ - title: 'RSAES-OAEP Encryption Example 7.1', - message: 'R6rpCQ==', - seed: 'Q90JoH/0ysccqkYy7l4cHa7kzY8=', - encrypted: 'FojkzneUu6bLcBQWns1VnO3iowtWpSto2f4Yzxlz75eyoDFTlRx1X2KUqkmtvbVYRatodfs5hsk+z5J5YoQNKC+eVM6LaQ98DLi71zRA2VcdGxbNkmD56rR4PMSC5SI9xglzhxeD7Cewrg/UdzLLwoahc/ySsA+0umgkZHzZPIXB' - }, { - title: 'RSAES-OAEP Encryption Example 7.2', - message: 'HZsuIiPZvBO/ufFiznNdtIunxo9oIqChp7auFlg05w==', - seed: 'Opw87HuE+b063svGc+yZ1UsivJs=', - encrypted: 'EFLtOXsuAeHQ7hxQvyQ2P5XlBPSgNDSgj9giV07WuXNu27XzkNsQMhR5qKE5NQ4r1Jd8N3jvMx8+eK4RiyaEUfIKLwHUcfXVPFZpNxcbLbwtS95FmleZ8DctZXQjmyMj0kXQu4HChrY8iaNhAXM35JAviKRn9MfyRL/Vq0ZDf/O2' - }, { - title: 'RSAES-OAEP Encryption Example 7.3', - message: '2Xb8', - seed: 'dqdeW2FXpVbPiIS7LkXCk91UXPU=', - encrypted: 'IVXNhD/ySk7outt2lCYAKKSQgTuos2mky/EG7BSOUphwf1llvn0QHBBJ6oWEwkzWNFWtnBBNaGKC0/uAOkwRwcLpuRxxeIAdG2ZA8AP1co3wB7ikzMkrzgXkGicnjXyFAYxSQUMTpQd3iQAdTwGRC3Kq0F0iCqFKWHM6dIm8VFVr' - }, { - title: 'RSAES-OAEP Encryption Example 7.4', - message: '1HOGI98iOqQ4Q9+EZ1NMQdAT4MgDxiTiY2ZrI5veQKXymuuN5549qmHdA3D0m9SwE4NLmCEq72scXuNzs8s=', - seed: 'eGYxSmrW8rJQo1lB2yj1hktYWFk=', - encrypted: 'CrFMNzrrfUMo0KqtjAlNiLnrCYuV8hBUopCCUivnwnoxKHi2N5F+PYGebDxWjbXYQ4ArBtUdnpiivgv0DAMUI7AO37/4Mg77kXG9IERlOky5xRIvbGXoPNouw8EmAnqcGla6h00P6iPzgLgs8kC4z1QABHWMTHfZNBV6dPP8Er+s' - }, { - title: 'RSAES-OAEP Encryption Example 7.5', - message: 'u0cjHKXqHTrUbJk0XZqKYQ==', - seed: 'shZu1HLVjbEMqyxrAAzM8Qp9xQk=', - encrypted: 'AoOHoxgndDR5i02X9GAGjfUpj6ulBBuhF2Ghy3MWskGEEU7FACV+JYntO2B6HrvpemzC4CvxtoH0IxKjO3p32OeFXEpt4D48BGQ/eGuRomSg1oBeLOqR5oF363pk2SVeTyfnE7fM7ADcIA69IcLqK7iQ/q5JQt+UHcP5eJDtNHR4' - }, { - title: 'RSAES-OAEP Encryption Example 7.6', - message: 'IYSCcJXTXD+G9gDo5ZdUATKW', - seed: 'Umc73iyhZsKqRhMawdyAjWfX07E=', - encrypted: 'FMZ4qUrWBSXvOelZsvO6XAl6lP+RK2fbrOgFNcGHq9R9B1QgsYchUrugj3/DHzE7v5JzyRL8TAFJqbDPt5gH40brMyBpYRvsD/m80Wjx98M+dzE86kVLlOJUnuzwAuKs9/by0oRdT+CqsuWpLd9oxICuESR5NdH2JXSEIhauZ0EV' - }]; - checkOAEPEncryptExamples(pubkey, privateKey, 'sha1', examples); - - // Example 8: A 1031-bit RSA Key Pair - // Components of the RSA Key Pair - modulus = 'W98OMNMh3aUUf4gkCPppGVSA34+A0/bov1gYUE82QnypsfVUC5xlqPaXTPhEeiRNkoAgG7Sfy75jeNGUTNIn4jD5bj0Q+Bnc7ydsZKALKktnAefQHeX6veOx6aDfgvRjE1nNImaWR/uxcXJGE07XtJfP/73EK1nHOpbtkBZiEt/3'; - exponent = 'AQAB'; - d = 'D30enlqqJf0T5KBmOuFE4NFfXNGLzbCd8sx+ZOPF6RWtYmRTBBYdCYxxW7eri9AdB+rz/tfH7QivKopi70SrFrMg4Ur3Kkj5av4mKgrkz2XmNekQeQzU7lzqdopLJjn35vZ3s/C7a+MrdXR9iQkDbwJk9Y1AHNuhMXFhV6dez2Mx'; - p = 'CgLvhEjZ+ti70NAEyMKql1HvlyHBsNAyNqVLDflHy67VolXuno4g1JHqFyP+CUcEqXYuiK/RbrtZlEEsqWbcT58='; - q = 'CS02Ln7ToL/Z6f0ObAMBtt8pFZz1DMg7mwz01u6nGmHgArRuCuny3mLSW110UtSYuByaxvxYWT1MP7T11y37sKk='; - dP = 'B8cUEK8QOWLbNnQE43roULqk6cKd2SFFgVKUpnx9HG3tJjqgMKm2M65QMD4UA10a8BQSPrpoeCAwjY68hbaVfX0='; - dQ = 'rix1OAwCwBatBYkbMwHeiB8orhFxGCtrLIO+p8UV7KnKKYx7HKtYF6WXBo/IUGDeTaigFjeKrkPH+We8w3kEuQ=='; - qInv = 'BZjRBZ462k9jIHUsCdgF/30fGuDQF67u6c76DX3X/3deRLV4Mi9kBdYhHaGVGWZqqH/cTNjIj2tuPWfpYdy7o9A='; - pubkey = decodeBase64PublicKey(modulus, exponent); - privateKey = decodeBase64PrivateKey(modulus, exponent, d, p, q, dP, dQ, qInv); - - examples = [{ - title: 'RSAES-OAEP Encryption Example 8.1', - message: 'BQt1Xl5ogPe56daSp0w3quRJsxv+pt7/g3R6iX9sLIJbsa2/hQo8lplLXeWzPLx9SheROnln', - seed: 'dwb/yh7PsevuKlXlxuJM0nl6QSU=', - encrypted: 'CbNoPYousPspW2LtH7kpC3FEV7eCUxn0ZHhyr4ibMECUcgIK0SkSvxmxHUgZ9JYUgk/9hNCcChfn0XMJ0SkZeQQQqimVaZ9qhtvjJCtazCOvRWkQgNaxroEPs+MFcIfwlwCSzgC+lWL/QFO2Jizgyqk+E3I9LjpboHXUXw1htUth' - }, { - title: 'RSAES-OAEP Encryption Example 8.2', - message: 'TraNzZPKmxnfERvUNgj1VwJv5KodXPrCJ6PrWrlUjBigbd7SP4GCWYay/NcRCezvfv+Ihz8HXCqgxGn2nJK8', - seed: 'o3F9oUO03P+8dCZlqPqVBYVUg0M=', - encrypted: 'Ls8VyXxaFbFHaumGs3G1eiQoT0oWKo0MgYLnkF55IlbxgSul+D8fehMOQtzAIjKETtwUoxpo7peuVko4OjQRZWQkxfYt22Rgk8Nnvh/NpCbPAKBtist+V3dvu9hVrD31BvwWsdfD8hEPPYBo6R4YY2ODHIQJaA2NqezYzx+iDuOd' - }, { - title: 'RSAES-OAEP Encryption Example 8.3', - message: 'hgSsVjKMGrWtkXhh', - seed: '7gYgkHPMoCa7Jk5Rhb+MaLdzn4Y=', - encrypted: 'S8iRMKWy2rt8L8+Q610Or55oG3FGo48xc6PZz+xS6p4KQZMuZIqdaTRMUNp2P1GgPJV2ITHoBSJU3NIkjLpA/TFmd4bOBaK3tTGsnaye1YSlm2d8GortjF0V1owFVp4r54C/fbY4/Sv9KoWrJ2hg83dzOPypif/XQ9E+4I4MqYk/' - }, { - title: 'RSAES-OAEP Encryption Example 8.4', - message: '/dpfv27DYanZpKxoryFqBob0OLHg5cNrlV904QfznA3dzA==', - seed: 'mQrVc9xIqXMjW22CVDYY8ulVEF0=', - encrypted: 'LkVoR9j8Nv8BR9aZNZS5OXIn1Xd1LHnQ+QT8sDnU2BL+pgWntXTdgsp4b5N1I0hDjun1tUVJhdXw4WmePnrRdaMuFfA96wQquf4d2dsbuG+MCJzLRefvDF7nyptykMprFb7UcDl4ioqT/4Pg6NYkTHEAY2Le72m29Bb7PGhDg/vQ' - }, { - title: 'RSAES-OAEP Encryption Example 8.5', - message: 'Sl9JFL7iXePGk0HeBw==', - seed: '7MY7KPB1byL1Ksjm7BJRpuwwRxg=', - encrypted: 'H7k1b9XEsXltsuv30NOTzIEK32FF3vwvznFPedk4ANXirCEeqLvsyktlS5TDsYsw3Vds403JVDbvV6CUFWRZIzWaXXtBce8iwkZw8bIp02A+kfdmcbffl+cxfJdzRHbV89F9Ic+Ctbqfg98uWI02mE/RtYRGi9I7LodfMvaJU/ey' - }, { - title: 'RSAES-OAEP Encryption Example 8.6', - message: 'jgfWb3uICnJWOrzT81CSvDNAn7f4jyRyvg==', - seed: 'OSXHGzYtQKCm3kIUVXm6Hn3UWfw=', - encrypted: 'Ov2cZgAUeyF5jYGMZVoPTJIS2ybQsN/cKnWUzLPSL1vx18PhEs1z/H1QnHqLr908J00TmQCflgnsS+ZHfkU/B1qjPbOChwwcNAmu85LXOGrjppa5mpS02gWJRH6VXRbJixdgKlm9c2J5/Nj7KAxEYtWQv6m/E/7VcOr96XMwosIQ' - }]; - checkOAEPEncryptExamples(pubkey, privateKey, 'sha1', examples); - - // Example 9: A 1536-bit RSA Key Pair - // Components of the RSA Key Pair - modulus = 'zyzUHjTKOnKOpcuK/2TDbSe971Nk4zb9aNMSPFoZaowocBPoU9UVbVjRUZVFIPtPbXsXq7aBd2WQnFdhGWWdkCsZBu2KKxDBVcJNEkUo2rnurjeb6sZuSkEXhty4/QBi68Aw3hIZoEwqjBt90xMeTWtsruLjGl7UGsFQmy7x7iqxg2S+VoypQcJezIT/nWQ7XsGqrhAqINc/R5t4D9bakQdSEtnqwDoGdNiZ66LkMfTES2Fba6IjK9SzO67XPWJd'; - exponent = 'AQAB'; - d = 'GYwUHiNxWpK8z2oRmlvBE4lGjSgR9UjXJ+F7SrDrmG1vIR77U7cffMvqh+5px17mFQCMUzLetSvzkKvfv+N9cgU2gVmyY4wd4ybiHSIlHw+1hIs78VAF0qdDMPCv6RbuYszBNE0dg6cJ5gZ2JzhA9/N3QkpeCk2nXwGzH/doGc+cv90hUkPDkXwD7zgZkxLlZ7O/eu06tFfzce+KFCP0W2jG4oLsERu6KDO5h/1p+tg7wbjGE8Xh6hbBHtEl6n7B'; - p = '/I1sBL7E65qBksp5AMvlNuLotRnezzOyRZeYxpCd9PF2230jGQ/HK4hlpxiviV8bzZFFKYAnQjtgXnCkfPWDkKjD6I/IxI6LMuPaIQ374+iB6lZ0tqNIwh6T+eVepl79'; - q = '0gDUXniKrOpgakAdBGD4fdXBAn4S3BoNdYbok52c94m0D1GsBEKWHefSHMIeBcgxVcHyqpGTOHz9+VbLSNFTuicEBvm7ulN9SYfZ4vmULXoUy//+p0/s3ako0j4ln17h'; - dP = '2xaAL3mi8NRfNY1p/TPkS4H66ChiLpOlQlPpl9AbB0N1naDoErSqTmyL6rIyjVQxlVpBimf/JqjFyAel2jVOBe8xzIz3WPRjcylQsD4mVyb7lOOdalcqJiRKsI23V1Kt'; - dQ = 'oKMXz+ffFCP4em3uhFH04rSmflSX8ptPHk6DC5+t2UARZwJvVZblo5yXgX4PXxbifhnsmQLgHX6m+5qjx2Cv7h44G2neasnAdYWgatnEugC/dcitL6iYpHnoCuKU/tKh'; - qInv = 'CyHzNcNTNC60TDqiREV4DC1lW5QBdMrjjHyKTmSTwLqf0wN0gmewg7mnpsth5C2zYrjJiW23Bk4CrVrmFYfaFbRknJBZSQn+s328tlS+tyaOyAHlqLSqORG+vYhULwW+'; - pubkey = decodeBase64PublicKey(modulus, exponent); - privateKey = decodeBase64PrivateKey(modulus, exponent, d, p, q, dP, dQ, qInv); - - examples = [{ - title: 'RSAES-OAEP Encryption Example 9.1', - message: '9zX9VbqSWSw7Urj5xPaaqhy++P6IrdCVWVQSRn+c9OwLiWxZ7aFiEOdUnIq7EM28IaEuyba1uP0vEDmetg==', - seed: 'jsll8TSj7Jkx6SocoNyBadXqcFw=', - encrypted: 'JnvNEYrKsfyLqByF1zADy4YQ+lXB2X2o1Ip8fwaJak23UaooQlW502rWXzdlPYKfGzf5e4ABlCVFsvwsVac3bKehvksXYMjgWjPlqiUmuNmOMXCI54NMdVsqWbEmMaGCwF1dQ6sXeSZPhFb1Fc5X399RLVST2re3M43Et9eNucCRrDuvU3pp/H9UnZefDv+alP2kFpvU0dGaacmeM8O1VJDVAbObHtrhGP9nk6FTJhWE06Xzn25oLj0XyM0SYfpy' - }, { - title: 'RSAES-OAEP Encryption Example 9.2', - message: 'gbkGYFAVpjqr5C3fEeGXiRL1QEx0dLJtzj7Ugr+WHsyBi/QgxUZZ', - seed: '7LG4sl+lDNqwjlYEKGf0r1gm0Ww=', - encrypted: 'k6yfBnHsKay7RE7/waV0E1HWD9sOOT+/dUrPDeSXYaFIQd93cum8gnc5ZqFYTE1yuuoAEY+D81zKblN8vU2BH1WDspeD2KbZTNMb5w1vUmwQ/wnG+nzgaXlaP80FEf1fy1ZLzIDqnHjzi4ABJTnYpN32/oHpzdt/UNu7vMfl2GCXzPTsSRifuL8xi+bVoHFdUWtJrxkSWM0y3IM85utGc8A6Gbus6IzFSJX2NswMHsiQltEc4jWiZcoXZCMqaJro' - }, { - title: 'RSAES-OAEP Encryption Example 9.3', - message: '/TJkKd+biQ4JtUsYuPNPHiQ=', - seed: '6JuwMsbOYiy9tTvJRmAU6nf3d8A=', - encrypted: 'gevdlQVLDIIu+a12k/Woet+0tMTOcN8t+E7UnATaWLpfwgoZ4abot6OQCyJ5bcToae5rQnktFajs61bAnGmRToE86o9pMeS47W9CGvKY1ZXJf0eJx8qmEsfvNgmEwhuT7cVAEGi1r0x4qHcbmE1TuOqK3y9qfUoLp2x14d2fZY8g3tSkYHHUbXeRtWgD2P6n8LD45Brj8JODpvlYX+d1Pqr/0r+UVjEIvuzCB7u1NfX8xwXw3en3CMYvSanJA3HT' - }, { - title: 'RSAES-OAEP Encryption Example 9.4', - message: '8UWbXwyS8BoPcjouVmJITY+MCiD8KdrWrNQ7tfPv/fThtj4H/f5mKNDXTKGb8taeSgq/htKTklp5Z3L4CI4=', - seed: 'YG87mcC5zNdx6qKeoOTIhPMYnMw=', - encrypted: 'vMNflM3mbLETZiXWJblEMqNbIvPS+hGmE/8PylvVf4e5AszcHNCuvLBxXuhp0dH+OV9nkwA/XspGUFnIhmDURv9fCBhVICJVfjjAimfq2ZEmIlTxBoKXXsVjl3aFN/SXevbV9qrOt/sl3sWTcjAjH9iXivSRGaKfKeQkq4JytHVieS1clPd0uIKdCw2fGoye3fN1dNX6JI7vqcUnH8XsJXnIG91htBD6Yf425CQiHBE63bJ1ZkyAHTTKjGNR5KhY' - }, { - title: 'RSAES-OAEP Encryption Example 9.5', - message: 'U+boxynW+cMZ3TF+dLDbjkzMol88gwV0bhN6xjpj7zc557WVq7lujVXlT3vUGrQzN4/7kR0=', - seed: '/LxCFALp7KvGCCr6QLpfJlIshA4=', - encrypted: 'Iyr7ySf6CML2onuH1KXLCcB9wm+uc9c6kFWIOfT9ZtKBuH7HNLziN7oWZpjtgpEGp95pQs1s3OeP7Y0uTYFCjmZJDQNiZM75KvlB0+NQVf45geFNKcu5pPZ0cwY7rseaEXn1oXycGDLyg4/X1eWbuWWdVtzooBnt7xuzrMxpfMbMenePYKBkx/b11SnGIQJi4APeWD6B4xZ7iZcfuMDhXUT//vibU9jWTdeX0Vm1bSsI6lMH6hLCQb1Y1O4nih8u' - }, { - title: 'RSAES-OAEP Encryption Example 9.6', - message: 'trKOohmNDBAIvGQ=', - seed: 'I6reDh4Iu5uaeNIwKlL5whsuG6I=', - encrypted: 'Q4zH3AimjaJJ5CUF+Fc7pg4sJ3PVspD0z53/cY6EIIHDg+ZwJKDylZTqmHudJeS3OPKFlw0ZWrs6jIBU49eda5yagye6WW8SWeJxJmdHZpB9jVgv86hHYVSSmtsebRI1ssy07I9mO6nMZwqSvr2FPI2/acZDbQFvYa3YNulHMkUENCB/n9TEPewqEqlY76Ae/iZpiZteYEwlXFX7cWbeVYnjaVl7sJFowG3V2xd+BqF0DrLVyC+uym2S/O6ZMbqf' - }]; - checkOAEPEncryptExamples(pubkey, privateKey, 'sha1', examples); - - // Example 10: A 2048-bit RSA Key Pair - // Components of the RSA Key Pair - modulus = 'rkXtVgHOxrjMBfgDk1xnTdvg11xMCf15UfxrDK7DE6jfOZcMUYv/ul7Wjz8NfyKkAp1BPxrgfk6+nkF3ziPn9UBLVp5O4b3PPB+wPvETgC1PhV65tRNLWnyAha3K5vovoUF+w3Y74XGwxit2Dt4jwSrZK5gIhMZB9aj6wmva1KAzgaIv4bdUiFCUyCUG1AGaU1ooav6ycbubpZLeGNz2AMKu6uVuAvfPefwUzzvcfNhP67v5UMqQMEsiGaeqBjrvosPBmA5WDNZK/neVhbYQdle5V4V+/eYBCYirfeQX/IjY84TE5ucsP5Q+DDHAxKXMNvh52KOsnX1Zhg6q2muDuw=='; - exponent = 'AQAB'; - d = 'BWsEIW/l81SsdyUKS2sMhSWoXFmwvYDFZFCiLV9DjllqMzqodeKR3UP0jLiLnV/A1Jn5/NHDl/mvwHDNnjmMjRnmHbfHQQprJnXfv100W4BNIBrdUC1c4t/LCRzpmXu+vlcwbzg+TViBA/A29+hdGTTRUqMj5KjbRR1vSlsbDxAswVDgL+7iuI3qStTBusyyTYQHLRTh0kpncfdAjuMFZPuG1Dk6NLzwt4hQHRkzA/E6IoSwAfD2Ser3kyjUrFxDCrRBSSCpRg7Rt7xA7GU+h20Jq8UJrkW1JRkBFqDCYQGEgphQnBw786SD5ydAVOFelwdQNumJ9gkygHtSV3UeeQ=='; - p = '7PWuzR5VFf/6y9daKBbG6/SQGM37RjjhhdZqc5a2+AkPgBjH/ZXMNLhX3BfwzGUWuxNGq01YLK2te0EDNSOHtwM40IQEfJ2VObZJYgSz3W6kQkmSB77AH5ZCh/9jNsOYRlgzaEb1bkaGGIHBAjPSF2vxWl6W3ceAvIaKp30852k='; - q = 'vEbEZPxqxMp4Ow6wijyEG3cvfpsvKLq9WIroheGgxh5IWKD7JawpmZDzW+hRZMJZuhF1zdcZJwcTUYSZK2wpt0bdDSyr4UKDX30UjMFhUktKCZRtSLgoRz8c52tstohsNFwD4F9B1RtcOpCj8kBzx9dKT+JdnPIcdZYPP8OGMYM='; - dP = 'xzVkVx0A+xXQij3plXpQkV1xJulELaz0K8guhi5Wc/9qAI7U0uN0YX34nxehYLQ7f9qctra3QhhgmBX31FyiY8FZqjLSctEn+vS8jKLXc3jorrGbCtfaPLPeCucxSYD2K21LCoddHfA8G645zNgz72zX4tlSi/CE0flp55Tp9sE='; - dQ = 'Jlizf235wQML4dtoEX+p2H456itpO35tOi9wlHQT7sYULhj7jfy2rFRdfIagrUj4RXFw8O+ya8SBJsU+/R0WkgGY3CoRB9woLbaoDNMGI2C6P6E/cOQxL/GmzWuPxM2cXD2xfG1qVyEvc64p9hkye61ZsVOFhYW6Tii2CmKkXkk='; - qInv = 'bzhSazklCFU07z5BWoNu3ouGFYosfL/sywvYNDBP7Gg7qNT0ecQz1DQW5jJpYjzqEAd22Fr/QB0//2EO5lQRzjsTY9Y6lwnu3kJkfOpWFJPVRXCoecGGgs2XcQuWIF7DERfXO182Ij+t1ui6kN18DuYdROFjJR4gx/ZuswURfLg='; - pubkey = decodeBase64PublicKey(modulus, exponent); - privateKey = decodeBase64PrivateKey(modulus, exponent, d, p, q, dP, dQ, qInv); - - examples = [{ - title: 'RSAES-OAEP Encryption Example 10.1', - message: 'i7pr+CpsD4bV8XVul5VocLCJU7BrTrIFvBaU7g==', - seed: 'R+GrcRn+5WyV7l6q2G9A0KpjvTM=', - encrypted: 'U+pdwIzSYPs7hYVnKH+pFVLDCy/r+6IT8K6HcC0GjRm6sH/ldFI9+0ITnWjDxa/u4L/ky3lpy/OCuATW5hOWFE4tDmB0H4mTwwFLWLmxlXqLq80jr4VPTDVvsWYqpyv8x+WGVZ3EKA0WDBJnhacj6+6+/3HxFZRECq74fRB5Ood0ojnUoEyH/hRnudr4UgjsbHJVeUqWzCkUL5qL1Bjjwf1nNEsM0IKd87K+xgJTGWKTxrNNP3XTLyE91Fxic9UFrfTM7RBXy3WPwmru+kQSVe1OZMGZ7gdefxZkYYL9tGRzm2irXa/w5j6VUgFoJPBUv008jJCpe7a2VTKE60KfzA==' - }, { - title: 'RSAES-OAEP Encryption Example 10.2', - message: '5q0YHwU7WKkE8kV1EDc+Vw==', - seed: 'bRf1tMH/rDUdGVv3sJ0J8JpAec8=', - encrypted: 'orGkMKnWV+L6HCu17UP/slwFowj+kJPAEDF5X1h0QAEQgorlj7m1gc6d3dPlSa4EoJhUWb3mxiZZTnsF3EJ4sqFGXBNoQIgjyF6W3GbDowmDxjlmT8RWmjf+IeWhlbV3bu0t+NjTYa9obnUCKbvWY/FhhopQYV4MM3vsDKNf7AuxnDbrLgu8wFgvodk6rNsGEGP1nyzh7kNgXl2J7KGD0qzf6fgQEQIq07Q6PdQX2slLThHqgbGSlm6WaxgggucZZGB7T4AC82KZhEoR8q4PrqwurnD49PmAiKzc0KxVbp/MxRFSGQj60m8ExkIBRQMFd4dYsFOL+LW7FEqCjmKXlQ==' - }, { - title: 'RSAES-OAEP Encryption Example 10.3', - message: 'UQos9g6Gb6I0BVPJTqOfvCVjEeg+lEVLQSQ=', - seed: 'OFOHUU3szHx0DdjN+druSaHL/VQ=', - encrypted: 'mIbD5nZKi5qE6EFI69jDsaqAUDgaePZocUwW2c/Spu3FaXnFNdne47RLhcGL6JKJkjcXEUciFtld2pjS7oNHybFN/9/4SqSNJawG99fmU5islnsc6Qkl9n3OBJt/gS2wdCmXp01E/oHb4Oej/q8uXECviI1VDdu+O8IGV6KVQ/j8KRO5vRphsqsiVuxAm719wNF3F+olxD9C7Sffhzi/SvxnZv96/whZVV7ig5IPTIpjxKc0DLr93DOezbSwUVAC+WyTK1t5Fnr2mcCtP8z98PROhacCYr8uGP40uFBYmXXoZ/+WnUjqvyEicVRs3AWmnstSblKHDINvMHvXmHgO3g==' - }, { - title: 'RSAES-OAEP Encryption Example 10.4', - message: 'vN0ZDaO30wDfmgbiLKrip18QyR/2Z7fBa96LUwZKJkmpQEXJ', - seed: 'XKymoPdkFhqWhPhdkrbg7zfKi2U=', - encrypted: 'Yxjp+1wNBeUwfhaDQ26QMpOsRkI1iqoiPXFjATq6h+Lf2o5gxoYOKaHpJoYWPqC5F18ynKOxMaHt06d3Wai5e61qT49DlvKM9vOcpYES5IFg1uID2qWFbzrKX/7Vd69JlAjj39Iz4+YE2+NKnEyQgt5lUnysYzHSncgOBQig+nEi5/Mp9sylz6NNTR2kF4BUV+AIvsVJ5Hj/nhKnY8R30Vu7ePW2m9V4MPwsTtaG15vHKpXYX4gTTGsK/laozPvIVYKLszm9F5Cc8dcN4zNa4HA5CT5gbWVTZd5lULhyzW3h1EDuAxthlF9imtijU7DUCTnpajxFDSqNXu6fZ4CTyA==' - }, { - title: 'RSAES-OAEP Encryption Example 10.5', - message: 'p91sfcJLRvndXx6RraTDs9+UfodyMqk=', - seed: 'lbyp44WYlLPdhp+n7NW7xkAb8+Q=', - encrypted: 'dSkIcsz9SkUFZg1lH1babaoJyhMB2JBjL2qZLz1WXO5GSv3tQO07W+k1ZxTqWqdlX0oTZsLxfHKPbyxaXR+OKEKbxOb48s/42o3A4KmAjkX9CeovpAyyts5v//XA4VnRG2jZCoX3uE4QOwnmgmZkgMZXUFwJKSWUaKMUeG106rExVzzyNL9X232eZsxnSBkuAC3A3uqTBYXwgx/c2bwz1R957S/8Frz01ZgS/OvKo/kGmw5EVobWRMJcz2O0Vu5fpv/pbxnN91H+2erzWVd1Tb9L/qUhaqGETcUHyy0IDnIuuhUDCMK1/xGTYg8XZuz0SBuvuUO9KSh38hNspJSroA==' - }, { - title: 'RSAES-OAEP Encryption Example 10.6', - message: '6vGnOhsMRglTfeac2SKLvPuajKjGw++vBW/kp/RjTtALfDnsaSLXuOosBOus', - seed: 'n0fd9C6X7qhWqb28cU6zrCL26zI=', - encrypted: 'LSB6c0Mqj7TAMFGz9zsophdkCY36NMR6IJlfgRWqaBZnm1V+gtvuWEkIxuaXgtfes029Za8GPVf8p2pf0GlJL9YGjZmE0gk1BWWmLlx38jA4wSyxDGY0cJtUfEb2tKcJvYXKEi10Rl75d2LCl2Pgbbx6nnOMeL/KAQLcXnnWW5c/KCQMqrLhYaeLV9JiRX7YGV1T48eunaAhiDxtt8JK/dIyLqyXKtPDVMX87x4UbDoCkPtnrfAHBm4AQo0s7BjOWPkyhpje/vSy617HaRj94cGYy7OLevxnYmqa7+xDIr/ZDSVjSByaIh94yCcsgtG2KrkU4cafavbvMMpSYNtKRg==' - }]; - checkOAEPEncryptExamples(pubkey, privateKey, 'sha1', examples); - } - - function testOAEPSHA256() { - var modulus, exponent, d, p, q, dP, dQ, qInv, pubkey, privateKey; - var examples; - - // Example 1: A 1024-bit RSA Key Pair - // Components of the RSA Key Pair - modulus = 'qLOyhK+OtQs4cDSoYPFGxJGfMYdjzWxVmMiuSBGh4KvEx+CwgtaTpef87Wdc9GaFEncsDLxkp0LGxjD1M8jMcvYq6DPEC/JYQumEu3i9v5fAEH1VvbZi9cTg+rmEXLUUjvc5LdOq/5OuHmtme7PUJHYW1PW6ENTP0ibeiNOfFvs='; - exponent = 'AQAB'; - d = 'UzOc/befyEZqZVxzFqyoXFX9j23YmP2vEZUX709S6P2OJY35P+4YD6DkqylpPNg7FSpVPUrE0YEri5+lrw5/Vf5zBN9BVwkm8zEfFcTWWnMsSDEW7j09LQrzVJrZv3y/t4rYhPhNW+sEck3HNpsx3vN9DPU56c/N095lNynq1dE='; - p = '0yc35yZ//hNBstXA0VCoG1hvsxMr7S+NUmKGSpy58wrzi+RIWY1BOhcu+4AsIazxwRxSDC8mpHHcrSEurHyjnQ=='; - q = 'zIhT0dVNpjD6wAT0cfKBx7iYLYIkpJDtvrM9Pj1cyTxHZXA9HdeRZC8fEWoN2FK+JBmyr3K/6aAw6GCwKItddw=='; - dP = 'DhK/FxjpzvVZm6HDiC/oBGqQh07vzo8szCDk8nQfsKM6OEiuyckwX77L0tdoGZZ9RnGsxkMeQDeWjbN4eOaVwQ=='; - dQ = 'lSl7D5Wi+mfQBwfWCd/U/AXIna/C721upVvsdx6jM3NNklHnkILs2oZu/vE8RZ4aYxOGt+NUyJn18RLKhdcVgw=='; - qInv = 'T0VsUCSTvcDtKrdWo6btTWc1Kml9QhbpMhKxJ6Y9VBHOb6mNXb79cyY+NygUJ0OBgWbtfdY2h90qjKHS9PvY4Q=='; - pubkey = decodeBase64PublicKey(modulus, exponent); - privateKey = decodeBase64PrivateKey(modulus, exponent, d, p, q, dP, dQ, qInv); - - examples = [{ - title: 'RSAES-OAEP Encryption Example 1.1', - message: 'ZigZThIHPbA7qUzanvlTI5fVDbp5uYcASv7+NA==', - seed: 'GLd26iEGnWl3ajPpa61I4d2gpe8Yt3bqIQadaXdqM+k=', - encrypted: 'W1QN+A1CKWotV6aZW7NYnUy7SmZd34SiX0jiPiLj9+8sZW6O/L7793+IFFSO3VKbPWhrjJPyR3ZmZ+yHDCzTDkRth+s5FN3nuFtlD3XQmmh0+x60PvAUiXJnAMcwxV96wHKjsUNPSnE1fsrCPBpIO5ZRaJ1pIF6R25IeuMwDujo=' - }, { - title: 'RSAES-OAEP Encryption Example 1.2', - message: 'dQxAR/VH6OQUEYVlIymKybriRe+vE5f75W+d1Q==', - seed: 'DMdCzkqbfzL5UbyyUe/ZJf5P418Mx0LOSpt/MvlRvLI=', - encrypted: 'jsKSyOW1BkucnZpnt9fS72P/lamWQqexXEDPVs8uzGlFj24Rj+cqGYVlt7i9nTmOGj2YrvM8swUTJQCYIF+QBiKbkcA7WBTBXfiUlkHvpWQD0bLwOkp1CmwfpF4sq2gTsCuSaGzZAc50ZAIOvpldizU7uOCwNNGOlERcFkvhfEE=' - }, { - title: 'RSAES-OAEP Encryption Example 1.3', - message: '2Urggy5kRc5CMxywbVMagrHbS6rTD3RtyRbfJNTjwkUf/1mmQj6w4dAtT+ZGz2md/YGMbpewUQ==', - seed: 'JRTfRpV1WmeyiOr0kFw27sZv0v0lFN9GlXVaZ7KI6vQ=', - encrypted: 'LcQ1BhOH4Vs0XX8/QJ6q/L0vSs9BUXfA20lQ6mwAt/gvUaUOvKJWBujoxt1QgpRnU6WuH7cSCFWXuKNnrhofpFF3CBTLIUbHZFoou0A4Roi4vFGFvYYu96Boy+oWivwB9/BKs1QMQeHADgNwUgqVD15+q27yHdfIH7kGp+DiGas=' - }, { - title: 'RSAES-OAEP Encryption Example 1.4', - message: 'UuZQ2Y5/KgSLT4aFIVO5fgHdMW80ahn2eoU=', - seed: 'xENaPhoYpotoIENikKN877hds/vEQ1o+Ghimi2ggQ2I=', - encrypted: 'ZMkqw9CM3SuY2zPBr8/9QbgXaVon4O4AKIufl3i7RVPD07fiTOnXF0aSWKUcdXNhE6ZcXc0Ha97/S5aw6mQKYfbmjaSq/H45s2nfZYTNIa74OgsV1DTDDLSF6/3J2UKhsG0LGIFaV9cNjfucDA5KbfQbzTq8u/+WN06J6nbInrI=' - }, { - title: 'RSAES-OAEP Encryption Example 1.5', - message: 'jaif2eX5dKKf7/tGK0kYD2z56AI=', - seed: 'sxjELfO+D4P+qCP1p7R+1eQlo7WzGMQt874Pg/6oI/U=', - encrypted: 'NzKEr8KhWRbX/VHniUE8ap0HzdDEWOyfl7dfNHXjL4h/320dmK633rGUvlA7sE4z9yuMj/xF++9ZeBzN6oSPLhVJV/aivUfcC8J99lwwp49W7phnvkUA4WUSmUeX+XRhwj8cR27mf5lu/6kKKbgasdt4BHqXcc5jOZICnld6vdE=' - }, { - title: 'RSAES-OAEP Encryption Example 1.6', - message: 'JlIQUIRCcQ==', - seed: '5OwJgsIzbzpnf2o1YXTrDOiHq8Lk7AmCwjNvOmd/ajU=', - encrypted: 'nfQEzsDY2gS9UYXF85t+u0Tm7HrOmmf+LqxCD+6N4XD36NoQ96PE9Squ83PvxKy8Bj8Q0N2L8E5Z5/9AWxLPCBqOkqkqIqO7ZDQMmpHml3H1yz82rpAzAQi6acZDSFQAW8NKhg4nEEwfwKdaGQcI0JZm6FrTQUuXskOqFUT0NJc=' - }]; - checkOAEPEncryptExamples(pubkey, privateKey, 'sha256', examples); - - // Example 2: A 1025-bit RSA Key Pair - // Components of the RSA Key Pair - modulus = 'AZR8f86QQl9HJ55whR8l1eYjFv6KHfGTcePmKOJgVD5JAe9ggfaMC4FBGQ0q6Nq6fRJQ7G22NulE7Dcih3x8HQpn8UsWlMXwN5RRpD5Joy3eg2cLc9qRocmbwjtDamAFXGEPC6+ZwaB5VluVo/FSZjLR1Npg8g7aJeZTxPACdm9F'; - exponent = 'AQAB'; - d = 'CCPyD6212okIip0AiT4h+kobEfvJPGSjvguq6pf7O5PD/3E3BMGcljwdEHqumQVHOfeeAuGG3ob4em3e/qbYzNHTyBpHv6clW+IGAaSksvCKFnteJ51xWxtFW91+qyRZQdl2i5rO+zzNpZUto87nJSW0UBZjqO4VyemS2SRi/jk='; - p = 'AVnb3gSjPvBvtgi4CxkPTT4ivME6yOSggQM6v6QW7bCzOKoItXMJ6lpSQOfcblQ3jGlBTDHZfdsfQG2zdpzEGkM='; - q = 'AStlLzBAOzi0CZX9b/QaGsyK2nA3Mja3IC05su4wz7RtsJUR9vMHzGHMIWBsGKdbimL4It8DG6DfDa/VUG9Wi9c='; - dP = 'Q271CN5zZRnC2kxYDZjILLdFKj+1763Ducd4mhvGWE95Wt270yQ5x0aGVS7LbCwwek069/U57sFXJIx7MfGiVQ=='; - dQ = 'ASsVqJ89+ys5Bz5z8CvdDBp7N53UNfBc3eLv+eRilIt87GLukFDV4IFuB4WoVrSRCNy3XzaDh00cpjKaGQEwZv8='; - qInv = 'AnDbF9WRSwGNdhGLJDiac1Dsg2sAY6IXISNv2O222JtR5+64e2EbcTLLfqc1bCMVHB53UVB8eG2e4XlBcKjI6A=='; - pubkey = decodeBase64PublicKey(modulus, exponent); - privateKey = decodeBase64PrivateKey(modulus, exponent, d, p, q, dP, dQ, qInv); - - examples = [{ - title: 'RSAES-OAEP Encryption Example 2.1', - message: 'j/AMqmBccCgwY02abD1CxlK1jPHZL+xXC+7n', - seed: 'jEB7XsKJnlCZxT6M55O/lOcbF4KMQHtewomeUJnFPow=', - encrypted: 'AR3o2JwhHLKUfOLZ26KXD9INUK1/fWJzdZix7E545qladDYdpHRaE5zBP9nf6IPmZvBUPq75n1E4suxm+Bom7crf9be1HXCFZnmR/wo92CKg4D1zRlBwr/3Gitr3h9rU6N+tid2x9yOYj955rf3Bq4j6wmjYQpWphbhBIBMoliyJ' - }, { - title: 'RSAES-OAEP Encryption Example 2.2', - message: 'LQ==', - seed: 'tgDPPC5QbX8Wd4yRDTqLAD7uYdW2AM88LlBtfxZ3jJE=', - encrypted: 'AIeYuAD2aYZYnEu1YK+INur95FfP2pTz8/k4r3xwL4bVMufgvzWFLdVK24fP96jTteLkrX6HjmebBVeUhSWG3ahebh3LH5yVS9yx+xHzM1Jxc8X1rS+kYgdCGWFbszMF/vP0ogisy5XthHqcoHNEM4Rzln7ugrXuS+dNuuPEjIAf' - }, { - title: 'RSAES-OAEP Encryption Example 2.3', - message: 'dPyIxRvJD3evnV6aSnATPUtOCzTaPDfH744=', - seed: 'pzdoruqpH52MHtb50rY0Z/B8yuOnN2iu6qkfnYwe1vk=', - encrypted: 'AMkW9IJHAFs0JbfwRZhrRITtj1bQVDLcjFCwYxHMDBlSHIqpDzSAL8aMxiUq41Feo9S2O/1ZTXIiK8baJpWs9y+BPqgi1lABB6JJIvU2QZYMzWK0XgjkWk12g6HSPFhuK4yf+LQ1UYpbKVquUdZ9POOCR8S7yS+tdful6qP8Wpkm' - }, { - title: 'RSAES-OAEP Encryption Example 2.4', - message: 'p+sqUDaTHSfU6JEybZlpL/rdqb9+/T405iLErcCF9yHf6IUHLHiiA7FRc5vlQPqMFToQ8Ao=', - seed: 'mns7DnCL2W+BkOyrT7mys4BagVaaezsOcIvZb4GQ7Ks=', - encrypted: 'AJ6YQ3DNjd7YXZzjHASKxPmwFbHKwoEpof+P+Li3+o6Xa95C21XyWZF0iCXc5USp5jwLt66T6G3aYQkEpoyFGvSPA3NV6tOUabopdmslYCkOwuOIsFLiuzkJc4Hu6nWXeJtTVtHn7FmzQgzQOMjuty1YConfe78YuQvyE3IAKkr2' - }, { - title: 'RSAES-OAEP Encryption Example 2.5', - message: 'LvKwZvhUwz873LtZlKQ15z1sbA==', - seed: '6zzrvErcFrtI6IyK7A40r39Cf9PrPOu8StwWu0jojIo=', - encrypted: 'AMv457W0EOt8RH+LAEoMQ7dKjZamzOdwTHJepDkaGGoQHi2z8coCiVemL5XYZ+ctjPBdw3y3nlMn1sif9i3WCzY26ram8PL5eVYk7Bm3XBjv9wuhw1RZmLFzKfJS+3vi+RTFhwjyyeaJrc07f5E7Cu7CVWNh3Oe3lvSF3TB2HUI8' - }, { - title: 'RSAES-OAEP Encryption Example 2.6', - message: 'in+zRMi2yyzy7x9kP5oyGPbhm7qJwA==', - seed: 'TEXPTVfJjj1tIJWtxRxInrUN/4RMRc9NV8mOPW0gla0=', - encrypted: 'AJ5iMVr3Q6ZZlqLj/x8wWewQBcUMnRoaS2lrejzqRk12Bw120fXolT6pgo20OtM6/ZpZSN7vCpmPOYgCf93MOqKpN1pqumUH33+iP1a+tos5351SidwwNb2hLy3JfhkapvjB+c9JvbIolIgr+xeWhWPmMDam/Du/y+EsBOdZrbYc' - }]; - checkOAEPEncryptExamples(pubkey, privateKey, 'sha256', examples); - - // Example 3: A 1026-bit RSA Key Pair - // Components of the RSA Key Pair - modulus = 'ArWP7AOahgcApNe2Ri+T5s3UkRYd3XT06BC0DjwWUgBqXCd7J3TBEwWky6taeO+lfheobfej+jb8Sx0iSfIux8LdakYyMqzOqQbWbr6AtXBLEHKdpvgzI0q7Xv3UopLL+tM7TTP6ehS4w5e1bjrNISA0KLd836M6bacGs9iw/EPp'; - exponent = 'AQAB'; - d = 'FbSKW1aDqUZw4jtXGPgU+g4T+FA49QcRGCy6YVEFgfPSLH4jLvk34i5VHWi4bi+MsarYvi5Ij13379J54/Vo1Orzb4DPcUGs5g/MkRP7bEqEH9ULvHxRL/y+/yFIeqgR6zyoxiAFNGqG3oa/odipSP0/NIwi6q3zM8PObOEyCP0='; - p = 'Ab8B0hbXNZXPAnDCvreNQKDYRH0x2pGamD9+6ngbd9hf43Gz6Tc+e2khfTFQoC2JWN5/rZ1VUWCVi0RUEn4Ofq8='; - q = 'AY0zmWWBZts4KYFteylUFnWenJGYf1stiuzWOwS0i9ey/PIpu3+KbciLoT3S45rVW20aBhYHCPlwC+gLj9N0TOc='; - dP = 'BsCiSdIKby7nXIi0lNU/aq6ZqkJ8iMKLFjp2lEXl85DPQMJ0/W6mMppc58fOA6IVg5buKnhFeG4J4ohalyjk5Q=='; - dQ = '0dJ8Kf7dkthsNI7dDMv6wU90bgUc4dGBHfNdYfLuHJfUvygEgC9kJxh7qOkKivRCQ7QHmwNEXmAuKfpRk+ZP6Q=='; - qInv = 'jLL3Vr2JQbHTt3DlrTHuNzsorNpp/5tvQP5Xi58a+4WDb5Yn03rP9zwneeY0uyYBHCyPfzNhriqepl7WieNjmg=='; - pubkey = decodeBase64PublicKey(modulus, exponent); - privateKey = decodeBase64PrivateKey(modulus, exponent, d, p, q, dP, dQ, qInv); - - examples = [{ - title: 'RSAES-OAEP Encryption Example 3.1', - message: 'CHggtWno+o0=', - seed: 'jO1rGWKQgFeQ6QkHQBXmogsMSJSM7WsZYpCAV5DpCQc=', - encrypted: 'AJqBCgTJGSHjv2OR0lObiDY2gZmWdutHfVeadCdFr2W4mS3ZHwet283wbtY/bsM8w0rVxNAPh3NZNrcRt56NhoT0NzD2IK3WNy39Im/CfbicvC6Vq2PyXUh1iza+90PUM3jECPP5NsOx658MzEnYyFZFb9izZIna6YLsXwkWoHVO' - }, { - title: 'RSAES-OAEP Encryption Example 3.2', - message: 'RlOsrxcZYLAfUqe+Y6OrIdw2jsQ7UNguw3geBA==', - seed: 'tCkdZWdVCEjMFWlnyAm6q2ylB/C0KR1lZ1UISMwVaWc=', - encrypted: 'ARCj8j/hSsscyXtuINlyU0HuC+d7wZc7bSekF60BJFWKeKa1p28d4KsJXmdqI22sxha7PgkI9bgpfgdBd8KHp12g5y68uXiwRyPOvv8s6YDKmJFhbW13LHbE3iZHch2YG1eHi/20M/IrsAqCuk/W5Q/dP5eSVM1hLT9LBVsX3rIH' - }, { - title: 'RSAES-OAEP Encryption Example 3.3', - message: '2UzQ4I+kBO2J', - seed: 'zoko9gWVWCVACLrdl5T63NL9H2XOiSj2BZVYJUAIut0=', - encrypted: 'Anfa/o/QML7UxLCHcSUWFPUWhcp955u97b5wLqXuLnWqoeQ3POhwasFh3/ow2lkzjjIdU47jkYJEk6A0dNgYiBuDg57/KN5yS2Px/QOSV+2nYEzPgSUHGyZacrHVkj/ZVyZ+ni7Iyf/QkNTfvPGxqmZtX6cq095jgdG1ELgYsTdr' - }, { - title: 'RSAES-OAEP Encryption Example 3.4', - message: 'bMZBtrYeb5Y5dNrSOpATKE7x', - seed: 'bil59S1oFKV9g7CQBUiI8RmluaNuKXn1LWgUpX2DsJA=', - encrypted: 'AalUnNYX91mP0FrqphpfhU22832WgnjDNRU1pkpSrd5eD7t7Q1YhYE+pKds6glA8i1AE/li216hJs2IbCJMddyaXrDzT8V9/UfIUaSkLfcRYBrTn9DEDOTjY1Xnn38poLOFykpZbAz5hdbOh0qG39qFgl5QZG0+aTBd1tmlMZBfO' - }, { - title: 'RSAES-OAEP Encryption Example 3.5', - message: '31FRgyth9PJYkftBcvMo0u3fg3H/z9vpl5OSlfMOymkYAXz9oRU796avh1kyIw==', - seed: 'LXYL/jjFneNM3IuMeKOOZihKLSctdgv+OMWd40zci4w=', - encrypted: 'AGgQQYTuy9dW6e3SwV5UFYbEtqQD7TDtxcrMYOmYlTPgTwIFpo4GbQbtgD9BMFAW7a1lIzLxKEld49jH6m95Xgtq/BAVFl/gXin5MMbiZfRTOl38miBTg5a6IS9w6tcrWIBeY5Z5n4iCuUqF9r/m9TqvxWF0aMP2VGVKZn+LHMVj' - }, { - title: 'RSAES-OAEP Encryption Example 3.6', - message: 'PDutiTxUSm1SCrAiMZGIyNUEt6eIuFCQO4WXLqoYVS4RNKetYJiCYlT/erZys9jrMVj6xtTLrvE=', - seed: '8XR3nF/Tz+AHuty3o2ybVb/Pvw7xdHecX9PP4Ae63Lc=', - encrypted: 'Aps8BQrRkPPwpNIjHw3NBznsDvp1hIHmlbG5wRERr9+Ar4ervO2GA/MMUVNijdZEtFnCGjbLwpM6RKzCk96jJX1bIgzq7hnmIzwKmq2Ue4qqO29rQL39jpCS87BBo/YKMbkYsPc2yYSDMBMOe9VDG63pvDgFGrlk/3Yfz1km3+/Y' - }]; - checkOAEPEncryptExamples(pubkey, privateKey, 'sha256', examples); - - // Example 4: A 1027-bit RSA Key Pair - // Components of the RSA Key Pair - modulus = 'BRJAtswABPpI0BNGccB4x8jew7Pi8lvCVkRnM52ziFPQa4XupbLeNTv/QqwuRryX+uaslhjalTelyPVTweNXYlmR1hCNzXiF+zolQT9T78rZSMs1zZua6cHGdibRE9V93kxb6na7W7felsANBzculoWm11z50jn6FI1wkxtfP7A5'; - exponent = 'AQAB'; - d = 'BBH/yjt8penpvn/jioUQXjU4ltsFxXlq7NKnJRYes2UchimpuGK5BNewx7N/jLWhwrVAAQGKAKHrLK/k7k6UksNIvCvtq0ueu/Bk6O/zIrkAn47sZTkF9A34ijzcSdRWf3VifUGspiQSm0agt8aY5eZfK3uhAsdJoQE1tlQNBAE='; - p = 'AnRYwZ7BY2kZ5zbJryXWCaUbj1YdGca/aUPdHuGriko/IyEAvUC4jezGuiNVSLbveSoRyd6CPQp5IscJW266VwE='; - q = 'AhDumzOrYXFuJ9JRvUZfSzWhojLi2gCQHClL8iNQzkkNCZ9kK1N1YS22O6HyA4ZJK/BNNLPCK865CdE0QbU7UTk='; - dP = 'OfoCi4JuiMESG3UKiyQvqaNcW2a9/R+mN9PMSKhKT0V6GU53J+Sfe8xuWlpBJlf8RwxzIuvDdBbvRYwweowJAQ=='; - dQ = 'AV2ZqEGVlDl5+p4b4sPBtp9DL0b9A+R9W++7v9ax0Tcdg++zMKPgIJQrL+0RXl0CviT9kskBnRzs1t1M8eVMyJk='; - qInv = 'AfC3AVFws/XkIiO6MDAcQabYfLtw4wy308Z9JUc9sfbL8D4/kSbj6XloJ5qGWywrQmUkz8UqaD0x7TDrmEvkEro='; - pubkey = decodeBase64PublicKey(modulus, exponent); - privateKey = decodeBase64PrivateKey(modulus, exponent, d, p, q, dP, dQ, qInv); - - examples = [{ - title: 'RSAES-OAEP Encryption Example 4.1', - message: 'SoZglTTuQ0psvKP36WLnbUVeMmTBn2Bfbl/2E3xlxW1/s0TNUryTN089FmyfDG+cUGutGTMJctI=', - seed: 'HKwZzpk971X5ggP2hSiWyVzMofMcrBnOmT3vVfmCA/Y=', - encrypted: 'AooWJVOiXRikAgxb8XW7nkDMKIcrCgZNTV0sY352+QatjTq4go6/DtieHvIgUgb/QYBYlOPOZkdiMWXtOFdapIMRFraGeq4mKhEVmSM8G5mpVgc62nVR0jX49AXeuw7kMGxnKTV4whJanPYYQRoOb0L4Mf+8uJ5QdqBE03Ohupsp' - /* FIXME: could not convert 4.2', to SHA-256, message too long - }, { - title: 'RSAES-OAEP Encryption Example 4.2', - message: 'sK3E8/4R2lnOmSdz2QWZQ8AwRkl+6dn5oG3xFm20bZj1jSfsB0wC7ubL4kSci5/FCAxcP0QzCSUS7EaqeTdDyA==', - seed: '9UXViXWF49txqgy42nbFHQMq6WM=', - encrypted: 'AJe2mMYWVkWzA0hvv1oqRHnA7oWIm1QabwuFjWtll7E7hU60+DmvAzmagNeb2mV4yEH5DWRXFbKA03FDmS3RhsgLlJt3XK6XNw5OyXRDE2xtpITpcP/bEyOiCEeCHTsYOB3hO7SarqZlMMSkuCcfPq4XLNNm4H5mNvEBnSoortFe' - */ - }, { - title: 'RSAES-OAEP Encryption Example 4.3', - message: 'v21C5wFwex0CBrDItFoccmQf8SiJIZqCveqWW155qWsNAWPtnVeOya2iDy+88eo8QInYNBm6gbDGDzYG2pk=', - seed: 'rZl/7vcw1up75g0NxS5y6sv90nWtmX/u9zDW6nvmDQ0=', - encrypted: 'AtYYko32Vmzn3ZtrsDQH9Mw/cSQk9pePdwQZJ6my7gYXWYpBdhbEN/fH7LMmvjtHnKLLTDazfF1HT0tTG6E+TY002cy+fMUvdRn0rfmFkNeHeqVOABP2EmI4eXFCBbbIlpshLxbA3vDTzPPZZqwMN+KPG4O11wmS9DcyHYtpsIOU' - }, { - title: 'RSAES-OAEP Encryption Example 4.4', - message: '+y7xEvXnZuuUAZKXk0eU974vb8HFjg==', - seed: 'E2RU31cw9zyAen5A2MGjEqxbndMTZFTfVzD3PIB6fkA=', - encrypted: 'AZX8z/njjTP/ApNNF+BNGUjlczSK/7iKULnZhiAKo4LJ0XaTzTtvL9jacr+OkRxSPUCpQeK36wXdi9qjsl3SO9D7APyzN1nNE5Nu5YstiAfEMVNpdRYGdgpUasEZ4jshBRGXYW28uTMcFWRtzrlol9Lc7IhIkldTXZsR9zg11KFn' - }, { - title: 'RSAES-OAEP Encryption Example 4.5', - message: 'KMzUR7uehRZtq7nlt9GtrcS5058gTpbV5EDOmtkovBwihA==', - seed: 'vKgFf4JLLqJX8oYUB+72PTMghoG8qAV/gksuolfyhhQ=', - encrypted: 'A8GIo5X2qOS6MdKjYJg+h3hi2endxxeb3F5A8v+MbC7/8WbBJnzOvKLb6YMukOfAqutJiGGzdPQM9fopdhbRwS/Ovw4ksvmNBVM+Q26CFPqvdhV8P0WxmeYTxGFGrLgma+fwxpe7L6mj300Jq6Y/5kfTEJSXNdKuLRn0JsIg8LSD' - }, { - title: 'RSAES-OAEP Encryption Example 4.6', - message: '8iJCdR7GsQ==', - seed: 'Ln4eF/ZHtd3QM+FUcvkPaBLzrE4ufh4X9ke13dAz4VQ=', - encrypted: 'AM9cnO14EVBadGQYTnkkbm/vYwqmnYvnAutrc4bZR3XC0DNhhuUlzFosUSmaC1LrjKcFfcqZOwzlev5uZycR7tUlLihC6lf4o0khAjUb03Dj+ubNsDKNCOA6vP63N3p6jSVIak7EPu0KtBLuNpIyW5mdkMuwssV7CNLOQ6qG7zxZ' - }]; - checkOAEPEncryptExamples(pubkey, privateKey, 'sha256', examples); - - // Example 5: A 1028-bit RSA Key Pair - // Components of the RSA Key Pair - modulus = 'Cq3z+cEl5diR8xrESOmT3v5YD4ArRfnX8iulAh6cR1drWh5oAxup205tq+TZah1vPSZyaM/0CABfEY78rbmYiNHCNEZxZrKiuEmgWoicBgrA2gxfrotV8wm6YucDdC+gMm8tELARAhSJ/0l3cBkNiV/Tn1IpPDnv1zppi9q58Q7Z'; - exponent = 'AQAB'; - d = 'AlbrTLpwZ/LSvlQNzf9FgqNrfTHRyQmbshS3mEhGaiaPgPWKSawEwONkiTSgIGwEU3wZsjZkOmCCcyFE33X6IXWI95RoK+iRaCdtxybFwMvbhNMbvybQpDr0lXF/fVKKz+40FWH2/zyuBcV4+EcNloL5wNBy+fYGi1bViA9oK+LF'; - p = 'A7DTli9tF1Scv8oRKUNI3PDn45+MK8aCTyFktgbWh4YNrh5jI5PP7fUTIoIpBp4vYOSs1+YzpDYGP4I4X0iZNwc='; - q = 'AuTDLi9Rcmm3ByMJ8AwOMTZffOKLI2uCkS3yOavzlXLPDtYEsCmC5TVkxS1qBTl95cBSov3cFB73GJg2NGrrMx8='; - dP = 'AehLEZ0lFh+mewAlalvZtkXSsjLssFsBUYACmohiKtw/CbOurN5hYat83iLCrSbneX31TgcsvTsmc4ALPkM429U='; - dQ = '65CqGkATW0zqBxl87ciBm+Hny/8lR2YhFvRlpKn0h6sS87pP7xOCImWmUpfZi3ve2TcuP/6Bo4s+lgD+0FV1Tw=='; - qInv = 'AS9/gTj5QEBi64WkKSRSCzj1u4hqAZb0i7jc6mD9kswCfxjngVijSlxdX4YKD2wEBxp9ATEsBlBi8etIt50cg8s='; - pubkey = decodeBase64PublicKey(modulus, exponent); - privateKey = decodeBase64PrivateKey(modulus, exponent, d, p, q, dP, dQ, qInv); - - examples = [{ - title: 'RSAES-OAEP Encryption Example 5.1', - message: 'r3GpAeOmHTEy8Pwf20dPnqZXklf/wk0WQXAUWz296A==', - seed: 'RMkuKD93uUmcYD2WNmDIfS+TlGFEyS4oP3e5SZxgPZY=', - encrypted: 'BOGyBDRo+2G7OC79yDEzJwwLMPuhIduDVaaBdb5svHj/ZAkVlyGVnH0j+ECliT42Nhvp4kZts+9cJ0W+ui7Q9KXbjmX033MpxrvSV1Ik//kHhX6xTn51UGpaOTiqofjM3QTTi9DVzRtAarWd/c8oAldrGok1vs+tJEDbcA5KvZz7' - }, { - title: 'RSAES-OAEP Encryption Example 5.2', - message: 'o7hEoII5qKxBYFrxemz9pNNQE2WFkDpBenkmh2BRmktKwzA+xz8Ph8+zI5k=', - seed: 'yyj1hgZZ/O7knD7q/OYlpwgDvTLLKPWGBln87uScPuo=', - encrypted: 'AeleoSbRCOqBTpyWGLCrZ2G3mfjCYzMvupBy+q+sOKAfBzaLCjCehEUmIZFhe+CvtmVvyKGFqOwHUWgvks9vFU7Gfi580aZm7d4FtaGGVHBO6Q32/6IS7a+KSk7L6rPWwBTI+kyxb5SW12HTEowheKkFTda06tU0l4Ji45xP2tyh' - }, { - title: 'RSAES-OAEP Encryption Example 5.3', - message: 'MIsOy9LHbLd/xvcMXt0jP9LyCSnWKfAmlTu2Ko9KOjFL3hld6FtfgW2iqrB00my2rN3zI647nGeKw88S+93n', - seed: 'IoX0DXcEgvmp76LHLLOsVXFtwMoihfQNdwSC+anvosc=', - encrypted: 'Ci3TBMV4P0o59ap6Wztb9LQHfJzYSOAaYaiXjk85Q9FYhAREaeS5YXhegKbbphMIS5i1SYJShmwpYu/t8SGHiX/72v6NnRgafDKzttROuF/HJoFkTBKH6C9NKke+mxoDy/YVZ9qYzFY6PwzB4pTDwku9s5Ha4DmRBlFdA/z713a4' - }, { - title: 'RSAES-OAEP Encryption Example 5.4', - message: 'FcW57hGF', - seed: 'SfpF06eN0Q39V3OZ0esAr37tVRNJ+kXTp43RDf1Xc5k=', - encrypted: 'AcMQiclY0MMdT9K4kPqZ7JYHTaSolc8B3huHcQ4U5mG11/9XjzWjTLha8Liy0w909aaPbaB7+ZQTebg7x3F4yeWFRmnAJMaIFGBW/oA952mEaJ+FR2HO0xfRPzCRCaaU7cyOxy0gnR8d9FMunt9fhbffM9TvOfR6YDE5Duz6Jg0W' - }, { - title: 'RSAES-OAEP Encryption Example 5.5', - message: 'IQJuaADH+nKPyqug0ZauKNeirE/9irznlPCYX2DIpnNydzZdP+oR24kjogKa', - seed: '8Ch0EyNMxQNHJKCUxFhrh6/xM/zwKHQTI0zFA0ckoJQ=', - encrypted: 'A/gvyZ/MNHUG3JGcisvAw/h1bhviZsqIsEM5+gBpLfj7d8iq28yZa6z5cnS4cJWywHxyQMgt9BAd37im/f5WcIcB+TZS9uegFSdgaetpYf4ft/1wMlcdc1ReCrTrCKPFHLLczeifyrnJSVvQD84kQY21b4fW9uLbSiGO0Ly94il1' - }, { - title: 'RSAES-OAEP Encryption Example 5.6', - message: 'VB43totsiHK4TAI=', - seed: '2fukXJbyHm4m0p6yzctlhb6cs0HZ+6RclvIebibSnrI=', - encrypted: 'AWmTYpBHOqRBGy1h5mF88hMmBVNLN++kXAqQr4PKszqorigNQZbvwbOdWYNLsXydyvKi55ds8tTvXf4rRBswyuNmbtT0t2FVCTnTjNzA1cMSahInbdKfL/1wib3CjyQmC0TbbIa3kkAdXkiYytSafDxwNyan1OWtJcMLkJ6l8WRm' - }]; - checkOAEPEncryptExamples(pubkey, privateKey, 'sha256', examples); - - // Example 6: A 1029-bit RSA Key Pair - // Components of the RSA Key Pair - modulus = 'ErF/ba0uzRn/RtwT94YPCeDgz7Z3s4pSWSMFzq8CLBZtuQ0ErCnjP33RLZ+vZuCBa7Y+rSZ8x9RsF8N74hS8oqItcjpk5EQHQ2tvyWVymu/CVU83bNXc6mgpN4CmK/OdAClIWhYLu55dwJctIaUE9S5e4CiqQWMy9RCy6c/19yKv'; - exponent = 'AQAB'; - d = 'ApXso1YGGDaVWc7NMDqpz9r8HZ8GlZ33X/75KaqJaWG80ZDcaZftp/WWPnJNB7TcEfMGXlrpfZaDURIoC5CEuxTyoh69ToidQbnEEy7BlW/KuLsv7QV1iEk2Uixf99MyYZBIJOfK3uTguzctJFfPeOK9EoYij/g/EHMc5jyQz/P5'; - p = 'BKbOi3NY36ab3PdCYXAFr7U4X186WKJO90oiqMBct8w469TMnZqdeJpizQ9g8MuUHTQjyWku+k/jrf8pDEdJo4s='; - q = 'BATJqAM3H+20xb4588ALAJ5eCKY74eQANc2spQEcxwHPfuvLmfD/4Xz9Ckv3vv0t1TaslG23l/28Sr6PKTSbke0='; - dP = 'A5Ycj3YKor1RVMeq/XciWzus0BOa57WUjqMxH8zYb7lcda+nZyhLmy3lWVcvFdjQRMfrg6G+X63yzDd8DYR1KUs='; - dQ = 'AiGX4GZ0IZaqvAP6L+605wsVy3h9YXrNMbt1x7wjStcG98SNIYLR8P+cIo3PQZZ7bAum0sCtEQobhXgx7CReLLE='; - qInv = 'BAHEwMU9RdvbXp2W0P7PQnXfCXS8Sgc2tKdMMmkFPvtoas4kBuIsngWN20rlQGJ64v2wgmHo5+S8vJlNqvowXEU='; - pubkey = decodeBase64PublicKey(modulus, exponent); - privateKey = decodeBase64PrivateKey(modulus, exponent, d, p, q, dP, dQ, qInv); - - examples = [{ - title: 'RSAES-OAEP Encryption Example 6.1', - message: 'QEbKi6ozR8on9J4NgfnMHXG+m6UX1A==', - seed: '3Q9s/kFeiOWkaaUfu6bf1ArbQ4TdD2z+QV6I5aRppR8=', - encrypted: 'C3d3hdR81ybq+Wuf6QUfy2KHVuQjrsvVH2HuE2LbJT2o2ZPdrDHIoGphdGj+GWNTrcV/d8iPLJlZ0CR3O2e2b7wLUVPMorv1HidYA8B8eJxkg5FIsPuK836LchnGqQlE7ObiWOjSuIw4lZ/ULCfOYejelr6PJXSxWgQUlV78sbvP' - }, { - title: 'RSAES-OAEP Encryption Example 6.2', - message: 'XMcsYCMd8Ds9QPm1eTG8MRCflyUn8osZ50gMcojLPJKyJRIhTkvmyRR5Ldq99X+qiqc=', - seed: 'jRS9lGoTURSPXK4u2aDGU+hevYWNFL2UahNRFI9cri4=', - encrypted: 'DXAHBh/uWFjxl/kIwrzm0MXeHNH5MSmoPc0mjn00UcCUFmOwTQipPmLmephH+rNOOfCQVvwP5wysU3/w2hjmk/rl6Jb4qNc+KqDiij7fKSKhPGTvY3aiXZ2LflnJ3yv4LdT9KvvWsZrHEWfsEG+fQZW4c1OMEpOMC4N44nc88yRm' - }, { - title: 'RSAES-OAEP Encryption Example 6.3', - message: 'sg5lEwMJL0vMtDBwwPhtIwSTYu2WZC/FYywn20pS49gx8qsGiyOxSYecAC9r8/7ul1kRElYs', - seed: 'bAdbxFUg8WXAv16kxd8ZG8nvDkRsB1vEVSDxZcC/XqQ=', - encrypted: 'AMe1ZPYbk4lABLKDLhwJMM4AfK46Jyilp/vQ9M921AamJzanoNGdlj6ZEFkbIO68hc/Wp4Qr43iWtjcasgpLw2NS0vroRi91VI5k9BZgXtgNG7Z9FBOtPjM61Um2PWSFpAyfaZS7zoJlfRKciEa+XUKa4VGly4fYSXXAbUJV2YHc' - }, { - title: 'RSAES-OAEP Encryption Example 6.4', - message: 'aE4wOMXAQfc=', - seed: 'O7w71mN9/hKEaQECm/WwwHEDQ5w7vDvWY33+EoRpAQI=', - encrypted: 'AJS/vpVJKJuLwnnzENVQChT5MCBa0mLxw/a9nt+6Zj4FL8nucIl7scjXSOkwBDPcyCWr7gqdtjjZ9z6RCQv0HfjmVKI2M6AxI2MYuzwftIQldbhCRqo8AlyK3XKjfcK+Rzvii53W8Xw4Obbsv9OCLnCrrbK8aO3XKgrHPmDthH7x' - }, { - title: 'RSAES-OAEP Encryption Example 6.5', - message: 'MkiMsmLQQdbk3TX5h788ppbbHwasKaRGkw==', - seed: 'tGtBiT6L7zJvZ1k4OoMHHa5/yry0a0GJPovvMm9nWTg=', - encrypted: 'CmNUKnNQco5hWHxCISdwN5M7LbL7YJ0u7bfH82LulE32VdATd3vcJmRiFtcczNNudMlHVhl6/ZsDVY1zymLrK2kLIYWeG9Iag3rQ5xhjLAdpMYBBuwjrJ8Oqc4+2qH57bBveynuE5xRpd9p+CkkiRP7x7g4B/iAwrmFxPtrxV/q/' - }, { - title: 'RSAES-OAEP Encryption Example 6.6', - message: 'ULoUvoRicgJ5wwa6', - seed: 'CiQDMSpB49UvBg+8E6Z95c92CacKJAMxKkHj1S8GD7w=', - encrypted: 'DpQAu4uQ4zbkpP/f698+a5f3MhAXCi3QTcP7vXmQVlkH0CFlCnDESNG36Jk2ybe3VmzE2deBHBKI9a5cHUzM9Lsa/AoxnbD5qd2fJt9k19dSRtDWZUR/Bn/AdVHwstzsX/vRLe6qOk9Kf01OZcvKrmlWh2IBLs8/6sEJhBWXNAKj' - }]; - checkOAEPEncryptExamples(pubkey, privateKey, 'sha256', examples); - - // Example 7: A 1030-bit RSA Key Pair - // Components of the RSA Key Pair - modulus = 'MRF58Lz8m508oxXQDvMNe906LPrpkRv+3LlIs6R4LQcytqtEqkvwN0GmRNwBvsPmmwGgM+Z12KzXxJJcaxrsMRkFHf2Jdi0hXUVHX/y1n5CBSGI/NxdxVvauht16fF9D3B4fkIJUBYooSl8GwAIXk6h/GsX+/33K7mnF5Ro3ieNz'; - exponent = 'AQAB'; - d = 'Bwz8/y/rgnbidDLEXf7kj0m3kX1lMOHwyjRg8y4CdhdEh8VuIqRdJQDXd1SVIZ19Flqc872Swyr5qY2NycwpaACtyUoKVPtA80KRv4TujqErbxCTWcbTVCpQ+cdn9c//BaaBwuZW+3fKqttL6UaNirzU35j1jobSBT+hNJ90jiGx'; - p = 'B0kmLBEc1HDsJWbms3MvwJMpRpqhkHHTucAZBlFMbx0muqFL6rCXHIt+YRpPeQCdb+p3aSjKJShbDeNkPRo/jHE='; - q = 'BrweUOlsAr9jbp7qi4mbvr92Ud533UdMPpvCO62BgrYZBMfZffvr+x4AEIh4tuZ+QVOR1nlCwrK/m0Q1+IsMsCM='; - dP = 'A7x+p/CqsUOrxs6LlxGGNqMBcuTP4CyPoN2jt7qvkPgJKYKYVSX0iL38tL1ybiJjmsZKMJKrf/y/HVM0z6ULW/E='; - dQ = 'AmKmqinCo8Z9xTRsBjga/Zh6o8yTz7/s9U/dn514fX9ZpSPTmJedoTei9jgf6UgB98lNohUY3DTLQIcMRpeZStk='; - qInv = 'ZJ1MF7buFyHnctA4mlWcPTzflVDUV8RrA3t0ZBsdUhZq+KITyDliBs37pEIvGNb2Hby10hTJcb9IKuuXanNwwg=='; - pubkey = decodeBase64PublicKey(modulus, exponent); - privateKey = decodeBase64PrivateKey(modulus, exponent, d, p, q, dP, dQ, qInv); - - examples = [{ - title: 'RSAES-OAEP Encryption Example 7.1', - message: 'R6rpCQ==', - seed: 'Q90JoH/0ysccqkYy7l4cHa7kzY9D3Qmgf/TKxxyqRjI=', - encrypted: 'CdXefX8LEW8SqnT1ly7/dvScQdke1rrSIBF4NcFO/G+jg0u7yjsqLLfTa8voI44Ue3W6lVuj5SkVYaP9i7VPmCWA4nFfeleuy23gbHylm4gokcCmzcAm2RLfPQYPnxIb3hoQ2C3wXo/aWoLIMFPYzI19g5uY90XMEchAci3FVC/a' - }, { - title: 'RSAES-OAEP Encryption Example 7.2', - message: 'HZsuIiPZvBO/ufFiznNdtIunxo9oIqChp7auFlg05w==', - seed: 'Opw87HuE+b063svGc+yZ1UsivJs6nDzse4T5vTrey8Y=', - encrypted: 'DDar5/aikhAVropPgT3SVzSMRtdS9sEmVBEqg9my/3na0Okz51EcAy436TOZVsM0exezvKYsVbDQhtOM0Mn9r6oyBsqzUR4lx6Gt2rYDYC4X1aMsJSVcQs9pDqeAWfIAmDIIQH/3IN2uJ6u4Xl2+gFCpp8RP0F//Rj2llnEsnRsl' - }, { - title: 'RSAES-OAEP Encryption Example 7.3', - message: '2Xb8', - seed: 'dqdeW2FXpVbPiIS7LkXCk91UXPV2p15bYVelVs+IhLs=', - encrypted: 'GpTkYrRFNyD9Jw1Pc1TSPSfc9Yb8k4Fw1l4kCwqPodlAboKMJe+yuXoGgVeB7Jb7JTQklGpQc1keZUzUUVZO0Q4qYUelFFe5lWM2uhq21VCbvcchrMTP6Wjts05hVgJHklLKF5cOtBGpQC0FlkwCYoXUAk//wejNycM/ZXw+ozkB' - }, { - title: 'RSAES-OAEP Encryption Example 7.4', - message: '1HOGI98iOqQ4Q9+EZ1NMQdAT4MgDxiTiY2ZrI5veQKXymuuN5549qmHdA3D0m9SwE4NLmCEq72scXuNzs8s=', - seed: 'eGYxSmrW8rJQo1lB2yj1hktYWFl4ZjFKatbyslCjWUE=', - encrypted: 'G5GJEPP4ifUCg+3OHEq41DFvaucXwgdSGyuDX6/yQ1+e30d0OIjIFv4JTUXv6Oi8/uADg+EN5Ug+lEyf0RNSS4wfKgRfAaXK6x1U8dh48g/bED27ZCZ+MjhAkUcjMO0h4m3nNfLxAju7nxO2cJzNI9n1TBCMngJBco0zzhOvMZaN' - }, { - title: 'RSAES-OAEP Encryption Example 7.5', - message: 'u0cjHKXqHTrUbJk0XZqKYQ==', - seed: 'shZu1HLVjbEMqyxrAAzM8Qp9xQmyFm7UctWNsQyrLGs=', - encrypted: 'HebBc/6i18c2FbG7ibWuxyQgtiN1uhtxyNsXw1Kuz8zo7RkBkt5JZEwucKyXFSwI6drZlK6QaqCRZwPQsdc2wnZlQzbkilVf1TiACqzDdpKX5i+SbCTUsOyGETV3vtxFe7/SatEKseFSLEWkIfZxAFcisIs5hWmLJdqfWQeYuMrK' - }, { - title: 'RSAES-OAEP Encryption Example 7.6', - message: 'IYSCcJXTXD+G9gDo5ZdUATKW', - seed: 'Umc73iyhZsKqRhMawdyAjWfX07FSZzveLKFmwqpGExo=', - encrypted: 'DX+W3vsdnJfe63BVUFYgCAG1VmTqG/DbQ4nZgWTUGHhuijUshLtz07dHar21GJ9Ory8QQPX67PgKGnBMp0fJBnqKO3boMOEcc52HEnQxOWIW2h2rgmDtnaYtvK85pddXzhbuXkXg4DDnoMy+4XzgbLfArK12deGB0wruBbQyv3Ar' - }]; - checkOAEPEncryptExamples(pubkey, privateKey, 'sha256', examples); - - // Example 8: A 1031-bit RSA Key Pair - // Components of the RSA Key Pair - modulus = 'W98OMNMh3aUUf4gkCPppGVSA34+A0/bov1gYUE82QnypsfVUC5xlqPaXTPhEeiRNkoAgG7Sfy75jeNGUTNIn4jD5bj0Q+Bnc7ydsZKALKktnAefQHeX6veOx6aDfgvRjE1nNImaWR/uxcXJGE07XtJfP/73EK1nHOpbtkBZiEt/3'; - exponent = 'AQAB'; - d = 'D30enlqqJf0T5KBmOuFE4NFfXNGLzbCd8sx+ZOPF6RWtYmRTBBYdCYxxW7eri9AdB+rz/tfH7QivKopi70SrFrMg4Ur3Kkj5av4mKgrkz2XmNekQeQzU7lzqdopLJjn35vZ3s/C7a+MrdXR9iQkDbwJk9Y1AHNuhMXFhV6dez2Mx'; - p = 'CgLvhEjZ+ti70NAEyMKql1HvlyHBsNAyNqVLDflHy67VolXuno4g1JHqFyP+CUcEqXYuiK/RbrtZlEEsqWbcT58='; - q = 'CS02Ln7ToL/Z6f0ObAMBtt8pFZz1DMg7mwz01u6nGmHgArRuCuny3mLSW110UtSYuByaxvxYWT1MP7T11y37sKk='; - dP = 'B8cUEK8QOWLbNnQE43roULqk6cKd2SFFgVKUpnx9HG3tJjqgMKm2M65QMD4UA10a8BQSPrpoeCAwjY68hbaVfX0='; - dQ = 'rix1OAwCwBatBYkbMwHeiB8orhFxGCtrLIO+p8UV7KnKKYx7HKtYF6WXBo/IUGDeTaigFjeKrkPH+We8w3kEuQ=='; - qInv = 'BZjRBZ462k9jIHUsCdgF/30fGuDQF67u6c76DX3X/3deRLV4Mi9kBdYhHaGVGWZqqH/cTNjIj2tuPWfpYdy7o9A='; - pubkey = decodeBase64PublicKey(modulus, exponent); - privateKey = decodeBase64PrivateKey(modulus, exponent, d, p, q, dP, dQ, qInv); - - examples = [{ - title: 'RSAES-OAEP Encryption Example 8.1', - message: 'BQt1Xl5ogPe56daSp0w3quRJsxv+pt7/g3R6iX9sLIJbsa2/hQo8lplLXeWzPLx9SheROnln', - seed: 'dwb/yh7PsevuKlXlxuJM0nl6QSV3Bv/KHs+x6+4qVeU=', - encrypted: 'DZZvGJ61GU6OOkaPl2t8iLNAB1VwLjl3RKd/tcu19Vz9j68fjCFBQvASq9FK6Sul/N6sXIVsi4ypx/1m77bErYJqiGwkE8sQz/g4ViwQmeCvpfbCoq00B5LxklezvhnM5OeSxFtO/8AtYimLrJ3sUmDYk7xkDI20/Lb8/pyOFsjH' - }, { - title: 'RSAES-OAEP Encryption Example 8.2', - message: 'TraNzZPKmxnfERvUNgj1VwJv5KodXPrCJ6PrWrlUjBigbd7SP4GCWYay/NcRCezvfv+Ihz8HXCqgxGn2nJK8', - seed: 'o3F9oUO03P+8dCZlqPqVBYVUg0OjcX2hQ7Tc/7x0JmU=', - encrypted: 'DwsnkHG2jNLgSU4LEvbkOuSaQ9+br9t3dwen8KDGmLkKVJgWGu+TNxyyo2gsBCw7S4eqEFrl49ENEhMehdjrHCBLrEBrhbHxgncKrwIXmcjX1DOCrQXEfbT4keig8TaXkasow5qby9Ded6MWcLu1dZnXPfiuiXaOYajMGJ1D3/y7' - }, { - title: 'RSAES-OAEP Encryption Example 8.3', - message: 'hgSsVjKMGrWtkXhh', - seed: '7gYgkHPMoCa7Jk5Rhb+MaLdzn4buBiCQc8ygJrsmTlE=', - encrypted: 'PAKF3K/lSKcZKWQDr56LmmVqSltcaKEfS7G6+rwG239qszt8eKG6fMYJsP4h7ZfXyV1zuIZXTVhXgiRQbA9os0AhkWiMJJouhsAn60R20BOLQOtQxlXxVOvUMPGuG5EP2O+nTI0VCXky5kHNJdfJolSW+pJLVdSu4mX9Ooga1CSx' - }, { - title: 'RSAES-OAEP Encryption Example 8.4', - message: '/dpfv27DYanZpKxoryFqBob0OLHg5cNrlV904QfznA3dzA==', - seed: 'mQrVc9xIqXMjW22CVDYY8ulVEF2ZCtVz3EipcyNbbYI=', - encrypted: 'LcCLDDj2S5ZOKwpvobOk6rfBWMBbxs3eWR+Edk3lKaoEAFFD5sQv0AaIs3r7yI8sOir9HvS6GKf+jc9t31zIDCIJc3sKVyrNZfEeUFSvihjbPZDo6IaZ8Jau8woE2p1z7n9rG+cbMwKuILRPSEN4hE0QSA/qz0wcye6bjb6NbK20' - }, { - title: 'RSAES-OAEP Encryption Example 8.5', - message: 'Sl9JFL7iXePGk0HeBw==', - seed: '7MY7KPB1byL1Ksjm7BJRpuwwRxjsxjso8HVvIvUqyOY=', - encrypted: 'U+PBTMw6peNHnFQ3pwix/KvVeWu1nSKQGcr9QPpYNgHhuFZK6ARR7XhKxFtDoUMP+iVTXprcow4lr1Uaw4PnEx+cPe0Khl15R8GLiuh5Vm9p3lTPW1u58iP2Oa81pQZTB5AuFiD0fnFZsl+BYfjDVah3cMIu83KOBRPOdLY0j8iq' - }, { - title: 'RSAES-OAEP Encryption Example 8.6', - message: 'jgfWb3uICnJWOrzT81CSvDNAn7f4jyRyvg==', - seed: 'OSXHGzYtQKCm3kIUVXm6Hn3UWfw5JccbNi1AoKbeQhQ=', - encrypted: 'WK9hbyje7E0PLeXtWaJxqD4cFkdL5x4vawlKJSOO1OKyZ6uaY8vMYBhBO47xRIqtab5Ul5UGCwdvwPR69PpARsiiSfJHVavkihXixHGgZViGTMU/7J7ftSiNT9hAwrj4JL4f1+8RhTp6WKRzsXAEKpvLK0TrzQL3ioF3QtTsiu/a' - }]; - checkOAEPEncryptExamples(pubkey, privateKey, 'sha256', examples); - - // Example 9: A 1536-bit RSA Key Pair - // Components of the RSA Key Pair - modulus = 'zyzUHjTKOnKOpcuK/2TDbSe971Nk4zb9aNMSPFoZaowocBPoU9UVbVjRUZVFIPtPbXsXq7aBd2WQnFdhGWWdkCsZBu2KKxDBVcJNEkUo2rnurjeb6sZuSkEXhty4/QBi68Aw3hIZoEwqjBt90xMeTWtsruLjGl7UGsFQmy7x7iqxg2S+VoypQcJezIT/nWQ7XsGqrhAqINc/R5t4D9bakQdSEtnqwDoGdNiZ66LkMfTES2Fba6IjK9SzO67XPWJd'; - exponent = 'AQAB'; - d = 'GYwUHiNxWpK8z2oRmlvBE4lGjSgR9UjXJ+F7SrDrmG1vIR77U7cffMvqh+5px17mFQCMUzLetSvzkKvfv+N9cgU2gVmyY4wd4ybiHSIlHw+1hIs78VAF0qdDMPCv6RbuYszBNE0dg6cJ5gZ2JzhA9/N3QkpeCk2nXwGzH/doGc+cv90hUkPDkXwD7zgZkxLlZ7O/eu06tFfzce+KFCP0W2jG4oLsERu6KDO5h/1p+tg7wbjGE8Xh6hbBHtEl6n7B'; - p = '/I1sBL7E65qBksp5AMvlNuLotRnezzOyRZeYxpCd9PF2230jGQ/HK4hlpxiviV8bzZFFKYAnQjtgXnCkfPWDkKjD6I/IxI6LMuPaIQ374+iB6lZ0tqNIwh6T+eVepl79'; - q = '0gDUXniKrOpgakAdBGD4fdXBAn4S3BoNdYbok52c94m0D1GsBEKWHefSHMIeBcgxVcHyqpGTOHz9+VbLSNFTuicEBvm7ulN9SYfZ4vmULXoUy//+p0/s3ako0j4ln17h'; - dP = '2xaAL3mi8NRfNY1p/TPkS4H66ChiLpOlQlPpl9AbB0N1naDoErSqTmyL6rIyjVQxlVpBimf/JqjFyAel2jVOBe8xzIz3WPRjcylQsD4mVyb7lOOdalcqJiRKsI23V1Kt'; - dQ = 'oKMXz+ffFCP4em3uhFH04rSmflSX8ptPHk6DC5+t2UARZwJvVZblo5yXgX4PXxbifhnsmQLgHX6m+5qjx2Cv7h44G2neasnAdYWgatnEugC/dcitL6iYpHnoCuKU/tKh'; - qInv = 'CyHzNcNTNC60TDqiREV4DC1lW5QBdMrjjHyKTmSTwLqf0wN0gmewg7mnpsth5C2zYrjJiW23Bk4CrVrmFYfaFbRknJBZSQn+s328tlS+tyaOyAHlqLSqORG+vYhULwW+'; - pubkey = decodeBase64PublicKey(modulus, exponent); - privateKey = decodeBase64PrivateKey(modulus, exponent, d, p, q, dP, dQ, qInv); - - examples = [{ - title: 'RSAES-OAEP Encryption Example 9.1', - message: '9zX9VbqSWSw7Urj5xPaaqhy++P6IrdCVWVQSRn+c9OwLiWxZ7aFiEOdUnIq7EM28IaEuyba1uP0vEDmetg==', - seed: 'jsll8TSj7Jkx6SocoNyBadXqcFyOyWXxNKPsmTHpKhw=', - encrypted: 'kuBqApUSIPP0yfNvL0I57K2hReD8CcPhiYZFlPPmdM0cVFQHvdPMjQ2GcEekoBMk2+JR2H3IY6QF0JcANECuoepAuEvks/XolStfJNyUVUO3vLbWGlA1JOOSPiWElIdM0hmLN5In0DizqQit7R0mzH3Y1vUGPBhzOnNgNVQgrWVvqJugjG1SPY7LaZxIjhnz3O/8EkCpxLWcyWkFLX+ujnxIKxAqjmvEztiwLLlcWbJKILOy7KE1lctyh58wYP6e' - }, { - title: 'RSAES-OAEP Encryption Example 9.2', - message: 'gbkGYFAVpjqr5C3fEeGXiRL1QEx0dLJtzj7Ugr+WHsyBi/QgxUZZ', - seed: '7LG4sl+lDNqwjlYEKGf0r1gm0WzssbiyX6UM2rCOVgQ=', - encrypted: 'iNEGT/cssEWuXX1C+SWyMK1hhUjRdNz9l8FeCBhftw8I5JUY1EDXPi2hUpESGxbJOjbyricua+QVvfP/UeoPfOxCcpRSoA3DlviB0ExCJTpCb2NSv9qXtw6Z7qEqk2YyQD7mAsGb2/Y3ug3KkKrF68MAxsWFV3tmL2NV2h+yfW6qz1dVAbAIUZeRuLIbaLdY9F7O4yPC68zkaX9NcTg0tOtnAJth9fMAOFX8sVbvKBgeOuVHV1A8HcAbmqkLMIyp' - }, { - title: 'RSAES-OAEP Encryption Example 9.3', - message: '/TJkKd+biQ4JtUsYuPNPHiQ=', - seed: '6JuwMsbOYiy9tTvJRmAU6nf3d8Dom7Ayxs5iLL21O8k=', - encrypted: 'JiwfWprF58xVjVRR9B9r0mhomwU5IzkxXCZDgYJwYUcacmrz+KRLKMmtCMN7DLA2lOsfK+72mU+RLmhwfAAhBYmLGR8dLLstazb5xzU9wIM9u3jAl5iyyMLSo6wk/3SH0f7vC2bnFtMkhoHsd3VSTpzl5Q+SqX/4Q1JAMGWMMiHdyjCH+WaXNdTrboPEnPVtTcBGthkkYu8r/G0IkBR6OMPCZFgl/J4uiRTGCRbZx7UC02g6+qNMQY+ksygV6R8w' - }, { - title: 'RSAES-OAEP Encryption Example 9.4', - message: '8UWbXwyS8BoPcjouVmJITY+MCiD8KdrWrNQ7tfPv/fThtj4H/f5mKNDXTKGb8taeSgq/htKTklp5Z3L4CI4=', - seed: 'YG87mcC5zNdx6qKeoOTIhPMYnMxgbzuZwLnM13Hqop4=', - encrypted: 'YXo+2y1QMWzjHkLtCW6DjdJ6fS5qdm+VHALYLFhG/dI1GmOwGOiOrFqesc5KPtWE73N5nJ680e6iYQYdFIsny6a4VH9mq/2Lr6qasMgM27znPzK8l6uQ1pTcDu1fJ4gCJABshzVEXzeTWx6OyKZsOFL8eXiNCwQpyfP9eH0tRjc+F75H3dnzX6AEVff4t0yKjDqp7aRMxFZGidcMJ6KetiNXUg1dhs/lHzItdQ7oMSUAgMnHYAvJDGqy5L4F8XXM' - }, { - title: 'RSAES-OAEP Encryption Example 9.5', - message: 'U+boxynW+cMZ3TF+dLDbjkzMol88gwV0bhN6xjpj7zc557WVq7lujVXlT3vUGrQzN4/7kR0=', - seed: '/LxCFALp7KvGCCr6QLpfJlIshA78vEIUAunsq8YIKvo=', - encrypted: 'fwY+yhF2kyhotPKPlHEXcTOqVRG8Kg9bDJE/cSPUOoyVoiV0j57o9xpEYtZBuM5RanPUsTDcYNvorKqP5mbN81JV3SmEkIRTL7JoHGpJAMDHFjXBfpAwgUCPhfJ2+CUCIyOoPZqlt4w+K9l+WeFZYDatr0HC1NO+stbvWq358HRdX27TexTocG5OEB4l9gqhnUYD2JHNlGidsm0vzFQJoIMaH26x9Kgosg6tZQ0t3jdoeLbTCSxOMM9dDQjjK447' - }, { - title: 'RSAES-OAEP Encryption Example 9.6', - message: 'trKOohmNDBAIvGQ=', - seed: 'I6reDh4Iu5uaeNIwKlL5whsuG6Ijqt4OHgi7m5p40jA=', - encrypted: 'PISd/61VECapJ7gfG4J2OroSl69kvIZD2uuqmiro3E4pmXfpdOW/q+1WCr574Pjsj/xrIUdgmNMAl8QjciO/nArYi0IFco1tCRLNZqMDGjzZifHIcDNCsvnKg/VRmkPrjXbndebLqMtw7taeVztYq1HKVAoGsdIvLkuhmsK0Iaesp+/8xka40c9hWwcXHsG+I7pevwFarxQQbuUjXSkZ2ObWgzgGSiGCw9QNUGpO0usATLSd0AFkeE+IM/KAwJCy' - }]; - checkOAEPEncryptExamples(pubkey, privateKey, 'sha256', examples); - - // Example 10: A 2048-bit RSA Key Pair - // Components of the RSA Key Pair - modulus = 'rkXtVgHOxrjMBfgDk1xnTdvg11xMCf15UfxrDK7DE6jfOZcMUYv/ul7Wjz8NfyKkAp1BPxrgfk6+nkF3ziPn9UBLVp5O4b3PPB+wPvETgC1PhV65tRNLWnyAha3K5vovoUF+w3Y74XGwxit2Dt4jwSrZK5gIhMZB9aj6wmva1KAzgaIv4bdUiFCUyCUG1AGaU1ooav6ycbubpZLeGNz2AMKu6uVuAvfPefwUzzvcfNhP67v5UMqQMEsiGaeqBjrvosPBmA5WDNZK/neVhbYQdle5V4V+/eYBCYirfeQX/IjY84TE5ucsP5Q+DDHAxKXMNvh52KOsnX1Zhg6q2muDuw=='; - exponent = 'AQAB'; - d = 'BWsEIW/l81SsdyUKS2sMhSWoXFmwvYDFZFCiLV9DjllqMzqodeKR3UP0jLiLnV/A1Jn5/NHDl/mvwHDNnjmMjRnmHbfHQQprJnXfv100W4BNIBrdUC1c4t/LCRzpmXu+vlcwbzg+TViBA/A29+hdGTTRUqMj5KjbRR1vSlsbDxAswVDgL+7iuI3qStTBusyyTYQHLRTh0kpncfdAjuMFZPuG1Dk6NLzwt4hQHRkzA/E6IoSwAfD2Ser3kyjUrFxDCrRBSSCpRg7Rt7xA7GU+h20Jq8UJrkW1JRkBFqDCYQGEgphQnBw786SD5ydAVOFelwdQNumJ9gkygHtSV3UeeQ=='; - p = '7PWuzR5VFf/6y9daKBbG6/SQGM37RjjhhdZqc5a2+AkPgBjH/ZXMNLhX3BfwzGUWuxNGq01YLK2te0EDNSOHtwM40IQEfJ2VObZJYgSz3W6kQkmSB77AH5ZCh/9jNsOYRlgzaEb1bkaGGIHBAjPSF2vxWl6W3ceAvIaKp30852k='; - q = 'vEbEZPxqxMp4Ow6wijyEG3cvfpsvKLq9WIroheGgxh5IWKD7JawpmZDzW+hRZMJZuhF1zdcZJwcTUYSZK2wpt0bdDSyr4UKDX30UjMFhUktKCZRtSLgoRz8c52tstohsNFwD4F9B1RtcOpCj8kBzx9dKT+JdnPIcdZYPP8OGMYM='; - dP = 'xzVkVx0A+xXQij3plXpQkV1xJulELaz0K8guhi5Wc/9qAI7U0uN0YX34nxehYLQ7f9qctra3QhhgmBX31FyiY8FZqjLSctEn+vS8jKLXc3jorrGbCtfaPLPeCucxSYD2K21LCoddHfA8G645zNgz72zX4tlSi/CE0flp55Tp9sE='; - dQ = 'Jlizf235wQML4dtoEX+p2H456itpO35tOi9wlHQT7sYULhj7jfy2rFRdfIagrUj4RXFw8O+ya8SBJsU+/R0WkgGY3CoRB9woLbaoDNMGI2C6P6E/cOQxL/GmzWuPxM2cXD2xfG1qVyEvc64p9hkye61ZsVOFhYW6Tii2CmKkXkk='; - qInv = 'bzhSazklCFU07z5BWoNu3ouGFYosfL/sywvYNDBP7Gg7qNT0ecQz1DQW5jJpYjzqEAd22Fr/QB0//2EO5lQRzjsTY9Y6lwnu3kJkfOpWFJPVRXCoecGGgs2XcQuWIF7DERfXO182Ij+t1ui6kN18DuYdROFjJR4gx/ZuswURfLg='; - pubkey = decodeBase64PublicKey(modulus, exponent); - privateKey = decodeBase64PrivateKey(modulus, exponent, d, p, q, dP, dQ, qInv); - - examples = [{ - title: 'RSAES-OAEP Encryption Example 10.1', - message: 'i7pr+CpsD4bV8XVul5VocLCJU7BrTrIFvBaU7g==', - seed: 'R+GrcRn+5WyV7l6q2G9A0KpjvTNH4atxGf7lbJXuXqo=', - encrypted: 'iXCnHvFRO1zd7U4HnjDMCLRvnKZj6OVRMZv8VZCAyxdA1T4AUORzxWzAtAAA541iVjEs1n5MIrDkymBDk3cM1oha9XCGsXeazZpW2z2+4aeaM3mv/oz3QYfEGiet415sHNnikAQ9ZmYg2uzBNUOS90h0qRAWFdUV5Tyxo1HZ0slg37Ikvyu2d6tgWRAAjgiAGK7IzlU4muAfQ4GiLpvElfm+0vch7lhlrk7t5TErhEF7RWQe16lVBva7azIxlGyyrqOhYrmQ+6JQpmPnsmEKYpSxTUP2tLzoSH5e+Y0CSaD7ZB20PWILB+7PKRueJ23hlMYmnAgQBePWSUdsljXAgA==' - }, { - title: 'RSAES-OAEP Encryption Example 10.2', - message: '5q0YHwU7WKkE8kV1EDc+Vw==', - seed: 'bRf1tMH/rDUdGVv3sJ0J8JpAec9tF/W0wf+sNR0ZW/c=', - encrypted: 'I3uBbIiYuvEYFA5OtRycm8zxMuuEoZMNRsPspeKZIGhcnQkqH8XEM8iJMeL6ZKA0hJm3jj4z1Xz7ra3tqMyTiw3vGKocjsYdXchK+ar3Atj/jXkdJLeIiqfTBA+orCKoPbrBXLllt4dqkhc3lbq0Z5lTBeh6caklDnmJGIMnxkiG3vON/uVpIR6LMBg+IudMCMOv2f++RpBhhrI8iJOsPbnebdMIrxviVaVxT22GUNehadT8WrHI/qKv+p1rCpD3AAyXAhJy7KKp1l+nPCy1IY1prey+YgBxCAnlHuHv2V7q1FZTRXMJe3iKubLeiX6SfAKU1sivpoqk5ntMSMgAfw==' - }, { - title: 'RSAES-OAEP Encryption Example 10.3', - message: 'UQos9g6Gb6I0BVPJTqOfvCVjEeg+lEVLQSQ=', - seed: 'OFOHUU3szHx0DdjN+druSaHL/VQ4U4dRTezMfHQN2M0=', - encrypted: 'n3scq/IYyBWbaN4Xd+mKJ0bZQR10yiSYzdjV1D1K3xiH11Tvhbj59PdRQXflSxE1QMhxN0jp9/tsErIlXqSnBH2XsTX6glPwJmdgXj7gZ1Aj+wsl15PctCcZv0I/4imvBBOSEd5TRmag3oU7gmbpKQCSHi6Hp2z5H/xEHekrRZemX7Dwl6A8tzVhCBpPweKNpe34OLMrHcdyb0k/uyabEHtzoZLpiOgHRjqi7SHr2ene9PPOswH7hc87xkiKtiFOpCeCScF6asFeiUTn5sf5tuPHVGqjKskwxcm/ToW3hm7ChnQdYcPRlnHrMeLBJt6o6xdrg6+SvsnNzctLxes0gA==' - }, { - title: 'RSAES-OAEP Encryption Example 10.4', - message: 'vN0ZDaO30wDfmgbiLKrip18QyR/2Z7fBa96LUwZKJkmpQEXJ', - seed: 'XKymoPdkFhqWhPhdkrbg7zfKi2VcrKag92QWGpaE+F0=', - encrypted: 'KWbozLkoxbGfY0Dixr8GE/JD+MDAXIUFzm7K5AYscTvyAh9EDkLfDc/i8Y9Cjz/GXWsrRAlzO9PmLj4rECjbaNdkyzgYUiXSVV0SWmEF62nhZcScf+5QWHgsv6syu2VXdkz9nW4O3LWir2M/HqJ6kmpKVm5o7TqeYZ7GrY25FUnFDM8DpXOZqOImHVAoh8Tim9d2V9lk2D2Av6Tdsa4SIyBDj5VcX3OVoTbqdkKj5It9ANHjXaqGwqEyj7j1cQrRzrbGVbib3qzvoFvGWoo5yzr3D8J8z/UXJ4sBkumcjrphFTDe9qQcJ5FI82ZZsChJssRcZl4ApFosoljixk0WkA==' - }, { - title: 'RSAES-OAEP Encryption Example 10.5', - message: 'p91sfcJLRvndXx6RraTDs9+UfodyMqk=', - seed: 'lbyp44WYlLPdhp+n7NW7xkAb8+SVvKnjhZiUs92Gn6c=', - encrypted: 'D7UPhV1nPwixcgg47HSlk/8yDLEDSXxoyo6H7MMopUTYwCmAjtnpWp4oWGg0sACoUlzKpR3PN21a4xru1txalcOkceylsQI9AIFvLhZyS20HbvQeExT9zQGyJaDhygC/6gPifgELk7x5QUqsd+TL/MQdgBZqbLO0skLOqNG3KrTMmN0oeWgxgjMmWnyBH0qkUpV5SlRN2P3nIHd/DZrkDn/qJG0MpXh6AeNHhvSgv8gyDG2Vzdf04OgvZLJTJaTdqHuXz93t7+PQ+QfKOG0wCEf5gOaYpkFarorv9XPLhzuOauN+Dd2IPzgKH5+wjbTZlZzEn+xRyDXK7s6GL/XOZw==' - }, { - title: 'RSAES-OAEP Encryption Example 10.6', - message: '6vGnOhsMRglTfeac2SKLvPuajKjGw++vBW/kp/RjTtALfDnsaSLXuOosBOus', - seed: 'n0fd9C6X7qhWqb28cU6zrCL26zKfR930LpfuqFapvbw=', - encrypted: 'FO6Mv81w3SW/oVGIgdfAbIOW1eK8/UFdwryWg3ek0URFK09jNQtAaxT+66Yn5EJrTWh8fgRn1spnAOUsY5eq7iGpRsPGE86MLNonOvrBIht4Z+IDum55EgmwCrlfyiGe2fX4Xv1ifCQMSHd3OJTujAosVI3vPJaSsbTW6FqOFkM5m9uPqrdd+yhQ942wN4m4d4TG/YPx5gf62fbCRHOfvA5qSpO0XGQ45u+sWBAtOfzxmaYtf7WRAlu+JvIjTp8I2lAfVEuuW9+TJattx9RXN8jaWOBsceLIOfE6bkgad50UX5PyEtapnJOG1j0bh5PZ//oKtIASarB3PwdWM1EQTQ==' - }]; - checkOAEPEncryptExamples(pubkey, privateKey, 'sha256', examples); - } - - function _bytesToBigInteger(bytes) { - var buffer = UTIL.createBuffer(bytes); - var hex = buffer.toHex(); - return new BigInteger(hex, 16); - } - - function _base64ToBn(s) { - var decoded = UTIL.decode64(s); - return _bytesToBigInteger(decoded); - } - - function checkOAEPEncryptExamples(publicKey, privateKey, md, examples) { - if(md === 'sha1') { - md = MD.sha1.create(); - } else if(md === 'sha256') { - md = MD.sha256.create(); - } - - for(var i = 0; i < examples.length; ++i) { - var ex = examples[i]; - it('should test ' + ex.title, function() { - checkOAEPEncrypt( - publicKey, privateKey, md, ex.message, ex.seed, ex.encrypted); - }); - } - } - - function checkOAEPEncrypt( - publicKey, privateKey, md, message, seed, expected) { - var message = UTIL.decode64(message); - var seed = UTIL.decode64(seed); - var encoded = PKCS1.encode_rsa_oaep( - publicKey, message, {seed: seed, md: md}); - var ciphertext = publicKey.encrypt(encoded, null); - ASSERT.equal(expected, UTIL.encode64(ciphertext)); - - var decrypted = privateKey.decrypt(ciphertext, null); - var decoded = PKCS1.decode_rsa_oaep(privateKey, decrypted, {md: md}); - ASSERT.equal(message, decoded); - - // test with higher-level API, default label, and generating a seed - ciphertext = publicKey.encrypt(message, 'RSA-OAEP', {md: md}); - decoded = privateKey.decrypt(ciphertext, 'RSA-OAEP', {md: md}); - ASSERT.equal(message, decoded); - } - - function decodeBase64PublicKey(modulus, exponent) { - modulus = _base64ToBn(modulus); - exponent = _base64ToBn(exponent); - return PKI.setRsaPublicKey(modulus, exponent); - } - - function decodeBase64PrivateKey(modulus, exponent, d, p, q, dP, dQ, qInv) { - modulus = _base64ToBn(modulus); - exponent = _base64ToBn(exponent); - d = _base64ToBn(d); - p = _base64ToBn(p); - q = _base64ToBn(q); - dP = _base64ToBn(dP); - dQ = _base64ToBn(dQ); - qInv = _base64ToBn(qInv); - return PKI.setRsaPrivateKey(modulus, exponent, d, p, q, dP, dQ, qInv); - } - - function makeKey() { - var modulus, exponent, d, p, q, dP, dQ, qInv, pubkey, privateKey; - - // Example 1: A 1024-bit RSA Key Pair - modulus = 'qLOyhK+OtQs4cDSoYPFGxJGfMYdjzWxVmMiuSBGh4KvEx+CwgtaTpef87Wdc9GaFEncsDLxkp0LGxjD1M8jMcvYq6DPEC/JYQumEu3i9v5fAEH1VvbZi9cTg+rmEXLUUjvc5LdOq/5OuHmtme7PUJHYW1PW6ENTP0ibeiNOfFvs='; - exponent = 'AQAB'; - d = 'UzOc/befyEZqZVxzFqyoXFX9j23YmP2vEZUX709S6P2OJY35P+4YD6DkqylpPNg7FSpVPUrE0YEri5+lrw5/Vf5zBN9BVwkm8zEfFcTWWnMsSDEW7j09LQrzVJrZv3y/t4rYhPhNW+sEck3HNpsx3vN9DPU56c/N095lNynq1dE='; - p = '0yc35yZ//hNBstXA0VCoG1hvsxMr7S+NUmKGSpy58wrzi+RIWY1BOhcu+4AsIazxwRxSDC8mpHHcrSEurHyjnQ=='; - q = 'zIhT0dVNpjD6wAT0cfKBx7iYLYIkpJDtvrM9Pj1cyTxHZXA9HdeRZC8fEWoN2FK+JBmyr3K/6aAw6GCwKItddw=='; - dP = 'DhK/FxjpzvVZm6HDiC/oBGqQh07vzo8szCDk8nQfsKM6OEiuyckwX77L0tdoGZZ9RnGsxkMeQDeWjbN4eOaVwQ=='; - dQ = 'lSl7D5Wi+mfQBwfWCd/U/AXIna/C721upVvsdx6jM3NNklHnkILs2oZu/vE8RZ4aYxOGt+NUyJn18RLKhdcVgw=='; - qInv = 'T0VsUCSTvcDtKrdWo6btTWc1Kml9QhbpMhKxJ6Y9VBHOb6mNXb79cyY+NygUJ0OBgWbtfdY2h90qjKHS9PvY4Q=='; - pubkey = decodeBase64PublicKey(modulus, exponent); - privateKey = decodeBase64PrivateKey(modulus, exponent, d, p, q, dP, dQ, qInv); - - return {publicKey: pubkey, privateKey: privateKey}; - } - }); -} - -// check for AMD -if(typeof define === 'function') { - define([ - 'forge/pki', - 'forge/pkcs1', - 'forge/md', - 'forge/jsbn', - 'forge/util' - ], function(PKI, PKCS1, MD, JSBN, UTIL) { - Tests( - // Global provided by test harness - ASSERT, - PKI(), - PKCS1(), - MD(), - JSBN(), - UTIL() - ); - }); -} else if(typeof module === 'object' && module.exports) { - // assume NodeJS - Tests( - require('assert'), - require('../../js/pki')(), - require('../../js/pkcs1')(), - require('../../js/md')(), - require('../../js/jsbn')(), - require('../../js/util')()); -} - -})(); diff --git a/alarm/node_modules/node-forge/nodejs/test/pkcs12.js b/alarm/node_modules/node-forge/nodejs/test/pkcs12.js deleted file mode 100644 index 70f482c..0000000 --- a/alarm/node_modules/node-forge/nodejs/test/pkcs12.js +++ /dev/null @@ -1,687 +0,0 @@ -(function() { - -function Tests(ASSERT, FORGE) { - var forge = FORGE(); - var PKCS12 = forge.pkcs12; - var ASN1 = forge.asn1; - var PEM = forge.pem; - var PKI = forge.pki; - var UTIL = forge.util; - - var _data; - describe('pkcs12', function() { - it('should create certificate-only p12', function() { - var p12Asn = PKCS12.toPkcs12Asn1(null, _data.certificate, null, { - useMac: false, - generateLocalKeyId: false - }); - var p12Der = ASN1.toDer(p12Asn).getBytes(); - - /* The generated PKCS#12 file lacks a MAC, therefore pass -nomacver to - OpenSSL: openssl pkcs12 -nomacver -nodes -in pkcs12_certonly.p12 */ - ASSERT.equal(p12Der, UTIL.decode64(_data.p12certonly)); - }); - - it('should create key-only p12', function() { - var privateKey = PKI.privateKeyFromPem(_data.privateKey); - var p12Asn = PKCS12.toPkcs12Asn1(privateKey, null, null, { - useMac: false, - generateLocalKeyId: false - }); - var p12Der = ASN1.toDer(p12Asn).getBytes(); - - /* The generated PKCS#12 file lacks a MAC, therefore pass -nomacver to - OpenSSL: openssl pkcs12 -nomacver -nodes -in pkcs12_keyonly.p12 */ - ASSERT.equal(p12Der, UTIL.decode64(_data.p12keyonly)); - }); - - it('should create encrypted-key-only p12', function() { - /* Note we need to mock the PRNG, since the PKCS#12 file uses encryption - which otherwise would differ each time due to the randomized IV. */ - var oldRandomGenerate = forge.random.generate; - forge.random.generate = function(num) { - return UTIL.createBuffer().fillWithByte(0, num).getBytes(); - }; - - var privateKey = PKI.privateKeyFromPem(_data.privateKey); - var p12Asn = PKCS12.toPkcs12Asn1(privateKey, null, 'nopass', { - useMac: false, - generateLocalKeyId: false - }); - var p12Der = ASN1.toDer(p12Asn).getBytes(); - - // restore old random function - forge.random.generate = oldRandomGenerate; - - /* The generated PKCS#12 file lacks a MAC, therefore pass -nomacver to - OpenSSL: openssl pkcs12 -nomacver -in pkcs12_enckeyonly.p12 */ - ASSERT.equal(p12Der, UTIL.decode64(_data.p12enckeyonly)); - }); - - it('should import certificate-only p12', function() { - var p12Der = UTIL.decode64(_data.p12certonly); - var p12Asn1 = ASN1.fromDer(p12Der); - var p12 = PKCS12.pkcs12FromAsn1(p12Asn1); - ASSERT.equal(p12.version, 3); - - // PKCS#12 PFX has exactly one SafeContents; it is not encrypted - ASSERT.equal(p12.safeContents.length, 1); - ASSERT.equal(p12.safeContents[0].encrypted, false); - - // SafeContents has one SafeBag which has one CertBag with the cert - ASSERT.equal(p12.safeContents[0].safeBags.length, 1); - ASSERT.equal(p12.safeContents[0].safeBags[0].type, PKI.oids.certBag); - - // check cert's serial number - ASSERT.equal( - p12.safeContents[0].safeBags[0].cert.serialNumber, - '00d4541c40d835e2f3'); - }); - - it('should import key-only p12', function() { - var p12Der = UTIL.decode64(_data.p12keyonly); - var p12Asn1 = ASN1.fromDer(p12Der); - var p12 = PKCS12.pkcs12FromAsn1(p12Asn1); - ASSERT.equal(p12.version, 3); - - // PKCS#12 PFX has exactly one SafeContents; it is not encrypted - ASSERT.equal(p12.safeContents.length, 1); - ASSERT.equal(p12.safeContents[0].encrypted, false); - - // SafeContents has one SafeBag which has one KeyBag with the key - ASSERT.equal(p12.safeContents[0].safeBags.length, 1); - ASSERT.equal(p12.safeContents[0].safeBags[0].type, PKI.oids.keyBag); - - // compare the key from the PFX by comparing both primes - var expected = PKI.privateKeyFromPem(_data.privateKey); - ASSERT.deepEqual(p12.safeContents[0].safeBags[0].key.p, expected.p); - ASSERT.deepEqual(p12.safeContents[0].safeBags[0].key.q, expected.q); - }); - - it('should import encrypted-key-only p12', function() { - var p12Der = UTIL.decode64(_data.p12enckeyonly); - var p12Asn1 = ASN1.fromDer(p12Der); - var p12 = PKCS12.pkcs12FromAsn1(p12Asn1, 'nopass'); - ASSERT.equal(p12.version, 3); - - // PKCS#12 PFX has exactly one SafeContents; it is *not* encrypted, - // only the key itself is encrypted (shrouded) - ASSERT.equal(p12.safeContents.length, 1); - ASSERT.equal(p12.safeContents[0].encrypted, false); - - // SafeContents has one SafeBag which has one shrouded KeyBag with the key - ASSERT.equal(p12.safeContents[0].safeBags.length, 1); - ASSERT.equal( - p12.safeContents[0].safeBags[0].type, PKI.oids.pkcs8ShroudedKeyBag); - - // compare the key from the PFX by comparing both primes - var expected = PKI.privateKeyFromPem(_data.privateKey); - ASSERT.deepEqual(p12.safeContents[0].safeBags[0].key.p, expected.p); - ASSERT.deepEqual(p12.safeContents[0].safeBags[0].key.q, expected.q); - }); - - it('should import an encrypted-key-only p12', function() { - var p12Der = UTIL.decode64(_data.p12enckeyonly); - var p12Asn1 = ASN1.fromDer(p12Der); - var p12 = PKCS12.pkcs12FromAsn1(p12Asn1, 'nopass'); - ASSERT.equal(p12.version, 3); - - // PKCS#12 PFX has exactly one SafeContents; it is *not* encrypted, - // only the key itself is encrypted (shrouded) - ASSERT.equal(p12.safeContents.length, 1); - ASSERT.equal(p12.safeContents[0].encrypted, false); - - // SafeContents has one SafeBag which has one shrouded KeyBag with the key - ASSERT.equal(p12.safeContents[0].safeBags.length, 1); - ASSERT.equal( - p12.safeContents[0].safeBags[0].type, PKI.oids.pkcs8ShroudedKeyBag); - - // compare the key from the PFX by comparing both primes - var expected = PKI.privateKeyFromPem(_data.privateKey); - ASSERT.deepEqual(p12.safeContents[0].safeBags[0].key.p, expected.p); - ASSERT.deepEqual(p12.safeContents[0].safeBags[0].key.q, expected.q); - }); - - it('should import an encrypted p12 with keys and certificates', function() { - var p12Der = UTIL.decode64(_data.p12encmixed); - var p12Asn1 = ASN1.fromDer(p12Der); - var p12 = PKCS12.pkcs12FromAsn1(p12Asn1, '123456'); - ASSERT.equal(p12.version, 3); - - // PKCS#12 PFX has two SafeContents; first is *not* encrypted but - // contains two shrouded keys, second is encrypted and has six - // certificates - ASSERT.equal(p12.safeContents.length, 2); - - ASSERT.equal(p12.safeContents[0].encrypted, false); - ASSERT.equal(p12.safeContents[0].safeBags.length, 2); - ASSERT.equal(p12.safeContents[0].safeBags[0].type, PKI.oids.pkcs8ShroudedKeyBag); - ASSERT.equal(p12.safeContents[0].safeBags[0].attributes.friendlyName.length, 1); - ASSERT.equal(p12.safeContents[0].safeBags[0].attributes.friendlyName[0], 'encryptionkey'); - ASSERT.equal(p12.safeContents[0].safeBags[0].attributes.localKeyId.length, 1); - ASSERT.equal(p12.safeContents[0].safeBags[0].attributes.localKeyId[0], 'Time 1311855238964'); - - ASSERT.equal(p12.safeContents[0].safeBags[1].type, PKI.oids.pkcs8ShroudedKeyBag); - ASSERT.equal(p12.safeContents[0].safeBags[1].attributes.friendlyName.length, 1); - ASSERT.equal(p12.safeContents[0].safeBags[1].attributes.friendlyName[0], 'signaturekey'); - ASSERT.equal(p12.safeContents[0].safeBags[1].attributes.localKeyId.length, 1); - ASSERT.equal(p12.safeContents[0].safeBags[1].attributes.localKeyId[0], 'Time 1311855238863'); - - ASSERT.equal(p12.safeContents[1].encrypted, true); - ASSERT.equal(p12.safeContents[1].safeBags.length, 6); - - ASSERT.equal(p12.safeContents[1].safeBags[0].type, PKI.oids.certBag); - ASSERT.equal(p12.safeContents[1].safeBags[0].attributes.friendlyName.length, 1); - ASSERT.equal(p12.safeContents[1].safeBags[0].attributes.friendlyName[0], 'CN=1002753325,2.5.4.5=#130b3130303237353333323543'); - ASSERT.equal(p12.safeContents[1].safeBags[0].attributes.localKeyId.length, 1); - ASSERT.equal(p12.safeContents[1].safeBags[0].attributes.localKeyId[0], 'Time 1311855238964'); - - ASSERT.equal(p12.safeContents[1].safeBags[1].type, PKI.oids.certBag); - ASSERT.equal(p12.safeContents[1].safeBags[1].attributes.friendlyName.length, 1); - ASSERT.equal(p12.safeContents[1].safeBags[1].attributes.friendlyName[0], 'CN=ElsterSoftTestCA,OU=CA,O=Elster,C=DE'); - - ASSERT.equal(p12.safeContents[1].safeBags[2].type, PKI.oids.certBag); - ASSERT.equal(p12.safeContents[1].safeBags[2].attributes.friendlyName.length, 1); - ASSERT.equal(p12.safeContents[1].safeBags[2].attributes.friendlyName[0], 'CN=ElsterRootCA,OU=RootCA,O=Elster,C=DE'); - - ASSERT.equal(p12.safeContents[1].safeBags[3].type, PKI.oids.certBag); - ASSERT.equal(p12.safeContents[1].safeBags[3].attributes.friendlyName.length, 1); - ASSERT.equal(p12.safeContents[1].safeBags[3].attributes.friendlyName[0], 'CN=1002753325,2.5.4.5=#130b3130303237353333323541'); - ASSERT.equal(p12.safeContents[1].safeBags[3].attributes.localKeyId.length, 1); - ASSERT.equal(p12.safeContents[1].safeBags[3].attributes.localKeyId[0], 'Time 1311855238863'); - - ASSERT.equal(p12.safeContents[1].safeBags[4].type, PKI.oids.certBag); - ASSERT.equal(p12.safeContents[1].safeBags[4].attributes.friendlyName.length, 1); - ASSERT.equal(p12.safeContents[1].safeBags[4].attributes.friendlyName[0], 'CN=ElsterSoftTestCA,OU=CA,O=Elster,C=DE'); - - ASSERT.equal(p12.safeContents[1].safeBags[5].type, PKI.oids.certBag); - ASSERT.equal(p12.safeContents[1].safeBags[5].attributes.friendlyName.length, 1); - ASSERT.equal(p12.safeContents[1].safeBags[5].attributes.friendlyName[0], 'CN=ElsterRootCA,OU=RootCA,O=Elster,C=DE'); - }); - - it('should get bags by friendly name', function() { - var p12Der = UTIL.decode64(_data.p12encmixed); - var p12Asn1 = ASN1.fromDer(p12Der); - var p12 = PKCS12.pkcs12FromAsn1(p12Asn1, '123456'); - var bags = p12.getBags({friendlyName: 'signaturekey'}); - - ASSERT.equal(bags.friendlyName.length, 1); - ASSERT.equal(bags.friendlyName[0].attributes.friendlyName[0], 'signaturekey'); - }); - - it('should get cert bags by friendly name', function() { - var p12Der = UTIL.decode64(_data.p12encmixed); - var p12Asn1 = ASN1.fromDer(p12Der); - var p12 = PKCS12.pkcs12FromAsn1(p12Asn1, '123456'); - var bags = p12.getBags({ - friendlyName: 'CN=1002753325,2.5.4.5=#130b3130303237353333323543', - bagType: PKI.oids.certBag - }); - - ASSERT.equal(bags.friendlyName.length, 1); - ASSERT.equal(bags.friendlyName[0].attributes.friendlyName[0], 'CN=1002753325,2.5.4.5=#130b3130303237353333323543'); - }); - - it('should get all cert bags', function() { - var p12Der = UTIL.decode64(_data.p12encmixed); - var p12Asn1 = ASN1.fromDer(p12Der); - var p12 = PKCS12.pkcs12FromAsn1(p12Asn1, '123456'); - var bags = p12.getBags({ - bagType: PKI.oids.certBag - }); - - ASSERT.equal(bags[PKI.oids.certBag].length, 6); - for(var i = 0; i < bags[PKI.oids.certBag].length; ++i) { - ASSERT.equal(bags[PKI.oids.certBag][i].type, PKI.oids.certBag); - } - }); - - it('should get bags by local key ID', function() { - var p12Der = UTIL.decode64(_data.p12encmixed); - var p12Asn1 = ASN1.fromDer(p12Der); - var p12 = PKCS12.pkcs12FromAsn1(p12Asn1, '123456'); - var bags = p12.getBags({localKeyId: 'Time 1311855238863'}); - - ASSERT.equal(bags.localKeyId.length, 2); - ASSERT.equal(bags.localKeyId[0].attributes.localKeyId[0], 'Time 1311855238863'); - ASSERT.equal(bags.localKeyId[1].attributes.localKeyId[0], 'Time 1311855238863'); - }); - - it('should get cert bags by local key ID', function() { - var p12Der = UTIL.decode64(_data.p12encmixed); - var p12Asn1 = ASN1.fromDer(p12Der); - var p12 = PKCS12.pkcs12FromAsn1(p12Asn1, '123456'); - var bags = p12.getBags({ - localKeyId: 'Time 1311855238863', - bagType: PKI.oids.certBag - }); - - ASSERT.equal(bags.localKeyId.length, 1); - ASSERT.equal(bags.localKeyId[0].attributes.localKeyId[0], 'Time 1311855238863'); - ASSERT.equal(bags.localKeyId[0].type, PKI.oids.certBag); - }); - - it('should generate a PKCS#12 mac key', function() { - var salt = 'A15D6AA8F8DAFC352F9EE1C192F09966EB85D17B'; - salt = UTIL.createBuffer(UTIL.hexToBytes(salt)); - var expected = '03e46727268575c6ebd6bff828d0d09b0c914201263ca543'; - var key = PKCS12.generateKey('123456', salt, 1, 1024, 24); - ASSERT.equal(key.toHex(), expected); - }); - - it('should load a PKCS#12 with an ECDSA key in a certificate (unsupported key format)', function() { - var p12Der = UTIL.decode64(_data.p12ecdsa); - var p12Asn1 = ASN1.fromDer(p12Der); - var p12 = PKCS12.pkcs12FromAsn1(p12Asn1, '123321'); - var bags = p12.getBags({bagType: PKI.oids.certBag}); - - ASSERT.equal(bags[PKI.oids.certBag].length, 1); - var bag = bags[PKI.oids.certBag][0]; - ASSERT.equal(bag.cert, null); - ASSERT.equal('asn1' in bag, true); - - // convert to ASN.1, then DER, then PEM-encode - var msg = { - type: 'CERTIFICATE', - body: ASN1.toDer(bag.asn1).getBytes() - }; - var pem = PEM.encode(msg); - ASSERT.equal(pem, _data.p12ecdsaCert); - }); - }); - - _data = { - certificate: '-----BEGIN CERTIFICATE-----\r\n' + - 'MIIDtDCCApwCCQDUVBxA2DXi8zANBgkqhkiG9w0BAQUFADCBmzELMAkGA1UEBhMC\r\n' + - 'REUxEjAQBgNVBAgMCUZyYW5jb25pYTEQMA4GA1UEBwwHQW5zYmFjaDEVMBMGA1UE\r\n' + - 'CgwMU3RlZmFuIFNpZWdsMRIwEAYDVQQLDAlHZWllcmxlaW4xFjAUBgNVBAMMDUdl\r\n' + - 'aWVybGVpbiBERVYxIzAhBgkqhkiG9w0BCQEWFHN0ZXNpZUBicm9rZW5waXBlLmRl\r\n' + - 'MB4XDTEyMDMxODIyNTc0M1oXDTEzMDMxODIyNTc0M1owgZsxCzAJBgNVBAYTAkRF\r\n' + - 'MRIwEAYDVQQIDAlGcmFuY29uaWExEDAOBgNVBAcMB0Fuc2JhY2gxFTATBgNVBAoM\r\n' + - 'DFN0ZWZhbiBTaWVnbDESMBAGA1UECwwJR2VpZXJsZWluMRYwFAYDVQQDDA1HZWll\r\n' + - 'cmxlaW4gREVWMSMwIQYJKoZIhvcNAQkBFhRzdGVzaWVAYnJva2VucGlwZS5kZTCC\r\n' + - 'ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMsAbQ4fWevHqP1K1y/ewpMS\r\n' + - '3vYovBto7IsKBq0v3NmC2kPf3NhyaSKfjOOS5uAPONLffLck+iGdOLLFia6OSpM6\r\n' + - '0tyQIV9lHoRh7fOEYORab0Z+aBUZcEGT9yotBOraX1YbKc5f9XO+80eG4XYvb5ua\r\n' + - '1NHrxWqe4w2p3zGJCKO+wHpvGkbKz0nfu36jwWz5aihfHi9hp/xs8mfH86mIKiD7\r\n' + - 'f2X2KeZ1PK9RvppA0X3lLb2VLOqMt+FHWicyZ/wjhQZ4oW55ln2yYJUQ+adlgaYn\r\n' + - 'PrtnsxmbTxM+99oF0F2/HmGrNs8nLZSva1Vy+hmjmWz6/O8ZxhiIj7oBRqYcAocC\r\n' + - 'AwEAATANBgkqhkiG9w0BAQUFAAOCAQEAvfvtu31GFBO5+mFjPAoR4BlzKq/H3EPO\r\n' + - 'qS8cm/TjHgDRALwSnwKYCFs/bXqE4iOTD6otV4TusX3EPbqL2vzZQEcZn6paU/oZ\r\n' + - 'ZVXwQqMqY5tf2teQiNxqxNmSIEPRHOr2QVBVIx2YF4Po89KGUqJ9u/3/10lDqRwp\r\n' + - 'sReijr5UKv5aygEcnwcW8+Ne4rTx934UDsutKG20dr5trZfWQRVS9fS9CFwJehEX\r\n' + - 'HAMUc/0++80NhfQthmWZWlWM1R3dr4TrIPtWdn5z0MtGeDvqBk7HjGrhcVS6kAsy\r\n' + - 'Z9y/lfLPjBuxlQAHztEJCWgI4TW3/RLhgfg2gI1noM2n84Cdmisfkg==\r\n' + - '-----END CERTIFICATE-----\r\n', - privateKey: '-----BEGIN RSA PRIVATE KEY-----\r\n' + - 'MIIEowIBAAKCAQEAywBtDh9Z68eo/UrXL97CkxLe9ii8G2jsiwoGrS/c2YLaQ9/c\r\n' + - '2HJpIp+M45Lm4A840t98tyT6IZ04ssWJro5KkzrS3JAhX2UehGHt84Rg5FpvRn5o\r\n' + - 'FRlwQZP3Ki0E6tpfVhspzl/1c77zR4bhdi9vm5rU0evFap7jDanfMYkIo77Aem8a\r\n' + - 'RsrPSd+7fqPBbPlqKF8eL2Gn/GzyZ8fzqYgqIPt/ZfYp5nU8r1G+mkDRfeUtvZUs\r\n' + - '6oy34UdaJzJn/COFBnihbnmWfbJglRD5p2WBpic+u2ezGZtPEz732gXQXb8eYas2\r\n' + - 'zyctlK9rVXL6GaOZbPr87xnGGIiPugFGphwChwIDAQABAoIBAAjMA+3QvfzRsikH\r\n' + - 'zTtt09C7yJ2yNjSZ32ZHEPMAV/m1CfBXCyL2EkhF0b0q6IZdIoFA3g6xs4UxYvuc\r\n' + - 'Q9Mkp2ap7elQ9aFEqIXkGIOtAOXkZV4QrEH90DeHSfax7LygqfD5TF59Gg3iAHjh\r\n' + - 'B3Qvqg58LyzJosx0BjLZYaqr3Yv67GkqyflpF/roPGdClHpahAi5PBkHiNhNTAUU\r\n' + - 'LJRGvMegXGZkUKgGMAiGCk0N96OZwrinMKO6YKGdtgwVWC2wbJY0trElaiwXozSt\r\n' + - 'NmP6KTQp94C7rcVO6v1lZiOfhBe5Kc8QHUU+GYydgdjqm6Rdow/yLHOALAVtXSeb\r\n' + - 'U+tPfcECgYEA6Qi+qF+gtPincEDBxRtoKwAlRkALt8kly8bYiGcUmd116k/5bmPw\r\n' + - 'd0tBUOQbqRa1obYC88goOVzp9LInAcBSSrexhVaPAF4nrkwYXMOq+76MiH17WUfQ\r\n' + - 'MgVM2IB48PBjNk1s3Crj6j1cxxkctqmCnVaI9HlU2PPZ3xjaklfv/NsCgYEA3wH8\r\n' + - 'mehUhiAp7vuhd+hfomFw74cqgHC9v0saiYGckpMafh9MJGc4U5GrN1kYeb/CFkSx\r\n' + - '1hOytD3YBKoaKKoYagaMQcjxf6HnEF0f/5OiQkUQpWmgC9lNnE4XTWjnwqaTS5L9\r\n' + - 'D+H50SiI3VjHymGXTRJeKpAIwV74AxxrnVofqsUCgYAwmL1B2adm9g/c7fQ6yatg\r\n' + - 'hEhBrSuEaTMzmsUfNPfr2m4zrffjWH4WMqBtYRSPn4fDMHTPJ+eThtfXSqutxtCi\r\n' + - 'ekpP9ywdNIVr6LyP49Ita6Bc+mYVyU8Wj1pmL+yIumjGM0FHbL5Y4/EMKCV/xjvR\r\n' + - '2fD3orHaCIhf6QvzxtjqTwKBgFm6UemXKlMhI94tTsWRMNGEBU3LA9XUBvSuAkpr\r\n' + - 'ZRUwrQssCpXnFinBxbMqXQe3mR8emrM5D8En1P/jdU0BS3t1kP9zG4AwI2lZHuPV\r\n' + - 'ggbKBS2Y9zVtRKXsYcHawM13+nIA/WNjmAGJHrB45UJPy/HNvye+9lbfoEiYKdCR\r\n' + - 'D4bFAoGBAIm9jcZkIwLa9kLAWH995YYYSGRY4KC29XZr2io2mog+BAjhFt1sqebt\r\n' + - 'R8sRHNiIP2mcUECMOcaS+tcayi+8KTHWxIEed9qDmFu6XBbePfe/L6yxPSagcixH\r\n' + - 'BK0KuK/fgTPvZCmIs8hUIC+AxhXKnqn4fIWoO54xLsALc0gEjs2d\r\n' + - '-----END RSA PRIVATE KEY-----\r\n', - p12certonly: - 'MIIEHgIBAzCCBBcGCSqGSIb3DQEHAaCCBAgEggQEMIIEADCCA/wGCSqGSIb3DQEH\r\n' + - 'AaCCA+0EggPpMIID5TCCA+EGCyqGSIb3DQEMCgEDoIID0DCCA8wGCiqGSIb3DQEJ\r\n' + - 'FgGgggO8BIIDuDCCA7QwggKcAgkA1FQcQNg14vMwDQYJKoZIhvcNAQEFBQAwgZsx\r\n' + - 'CzAJBgNVBAYTAkRFMRIwEAYDVQQIDAlGcmFuY29uaWExEDAOBgNVBAcMB0Fuc2Jh\r\n' + - 'Y2gxFTATBgNVBAoMDFN0ZWZhbiBTaWVnbDESMBAGA1UECwwJR2VpZXJsZWluMRYw\r\n' + - 'FAYDVQQDDA1HZWllcmxlaW4gREVWMSMwIQYJKoZIhvcNAQkBFhRzdGVzaWVAYnJv\r\n' + - 'a2VucGlwZS5kZTAeFw0xMjAzMTgyMjU3NDNaFw0xMzAzMTgyMjU3NDNaMIGbMQsw\r\n' + - 'CQYDVQQGEwJERTESMBAGA1UECAwJRnJhbmNvbmlhMRAwDgYDVQQHDAdBbnNiYWNo\r\n' + - 'MRUwEwYDVQQKDAxTdGVmYW4gU2llZ2wxEjAQBgNVBAsMCUdlaWVybGVpbjEWMBQG\r\n' + - 'A1UEAwwNR2VpZXJsZWluIERFVjEjMCEGCSqGSIb3DQEJARYUc3Rlc2llQGJyb2tl\r\n' + - 'bnBpcGUuZGUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDLAG0OH1nr\r\n' + - 'x6j9Stcv3sKTEt72KLwbaOyLCgatL9zZgtpD39zYcmkin4zjkubgDzjS33y3JPoh\r\n' + - 'nTiyxYmujkqTOtLckCFfZR6EYe3zhGDkWm9GfmgVGXBBk/cqLQTq2l9WGynOX/Vz\r\n' + - 'vvNHhuF2L2+bmtTR68VqnuMNqd8xiQijvsB6bxpGys9J37t+o8Fs+WooXx4vYaf8\r\n' + - 'bPJnx/OpiCog+39l9inmdTyvUb6aQNF95S29lSzqjLfhR1onMmf8I4UGeKFueZZ9\r\n' + - 'smCVEPmnZYGmJz67Z7MZm08TPvfaBdBdvx5hqzbPJy2Ur2tVcvoZo5ls+vzvGcYY\r\n' + - 'iI+6AUamHAKHAgMBAAEwDQYJKoZIhvcNAQEFBQADggEBAL377bt9RhQTufphYzwK\r\n' + - 'EeAZcyqvx9xDzqkvHJv04x4A0QC8Ep8CmAhbP216hOIjkw+qLVeE7rF9xD26i9r8\r\n' + - '2UBHGZ+qWlP6GWVV8EKjKmObX9rXkIjcasTZkiBD0Rzq9kFQVSMdmBeD6PPShlKi\r\n' + - 'fbv9/9dJQ6kcKbEXoo6+VCr+WsoBHJ8HFvPjXuK08fd+FA7LrShttHa+ba2X1kEV\r\n' + - 'UvX0vQhcCXoRFxwDFHP9PvvNDYX0LYZlmVpVjNUd3a+E6yD7VnZ+c9DLRng76gZO\r\n' + - 'x4xq4XFUupALMmfcv5Xyz4wbsZUAB87RCQloCOE1t/0S4YH4NoCNZ6DNp/OAnZor\r\n' + - 'H5I=', - p12enckeyonly: - 'MIIFcQIBAzCCBWoGCSqGSIb3DQEHAaCCBVsEggVXMIIFUzCCBU8GCSqGSIb3DQEH\r\n' + - 'AaCCBUAEggU8MIIFODCCBTQGCyqGSIb3DQEMCgECoIIFIzCCBR8wSQYJKoZIhvcN\r\n' + - 'AQUNMDwwGwYJKoZIhvcNAQUMMA4ECAAAAAAAAAAAAgIIADAdBglghkgBZQMEAQIE\r\n' + - 'EAAAAAAAAAAAAAAAAAAAAAAEggTQQHIbPs0naCmJGgmtvFNmUlv9sHkm2A/vWHjY\r\n' + - 'B8UavyYUz3IMtDCWZBoWHWp/izLDroCSxkabxyzqlSbYdGug1QY9y9RP6TjP6uaw\r\n' + - 'SFurDe7beTRB3d8Oe2AMEmUQtaPE/zQI52aWse8RNh5P1I1wQEzVvk8/hf2eLdLQ\r\n' + - 'cxUb0flz65Nkr4tVPsAmXfbepiyPm+lISi7syNfO6d7424CsGYXD3VCtDxbS5r0m\r\n' + - 'L7OIkMfr7JhkvlrcdgrBY5r8/67MtfaJrMe0FR90UJd6ST++2FyhbilSz2BI6Twu\r\n' + - 'wNICvkbThwY/LLxOCPKm4AgEj/81pYy6z2eWG59pD8fju4IOJUt3AGoPZoCQrbmD\r\n' + - 'MDahpYgey6bo8ti9H08HhvP9keOgI2HUCQoObL0c2GF+fv6m/EJ59hpH9qeryfT4\r\n' + - 'HAzSfd4h0YszF32a23+dGEgXAA492m00lZ/uM5nTF0RIQsqj5BJSxEEBpYequF4A\r\n' + - 'MNCsjKl90HPSIndNSUfgN0us8FtmrzBNbmIATFE9juKHWag3p751ertsGv6e/Ofm\r\n' + - 'xAhgF21j8ZhwXKjsVY4uYVFYLWkCLSD4gF8/ijWg873XZKzjPuy8w3SAAcya8vaQ\r\n' + - 'buzzk5zgN0g5T+JxCAdP50FH68rVG2dhfY1BDFe8xY6mxSfs/wUj5EVD9jdqlYpu\r\n' + - '/o3IFtdksSra8eOwO2F/kw69x11wZaYpZaRzbIM2x1pDARkAtnbdvdSEXMOT7htA\r\n' + - 'OYAJiZuhW0czOgumGGhIO8TBxwMh3/WjkUdlJ1JNhl6M+JHlmIKerCuP6kCLJsAp\r\n' + - '+RyRRp6pKa4t09G5rjAjCUiPqkCKRSf40ijhn+lLhj8ZHKLDyw4FCMo6NvQvFsDp\r\n' + - 'dbCbbHzWGZXEspT56jGbuju1DQCiy+uVKYhigU1PvRXrxpCHKcv65iqnwPRgGE6X\r\n' + - 'dPSGfjsLDbATvSrVv1DvJNTH9wyCSQt/eqBXFWkQeFEqKXij0atkdHL6GXRo57PX\r\n' + - 'KZgeul2Xxd2J5SYNCUJf8IL4UOfHRMB4GaGGt9LTpPq2bI9fju1vVE4BjL1gSYIi\r\n' + - 'cvynjH7mpzVwq+Cxj4uCo8aZQKWB0BI7c4cDaFmKPIFD47QFZUNgYCv9WfNljOe/\r\n' + - '+CqRbxNFUsXCR4hEoYmdn0EEI2b1F6Hkz/dDrLH33My4Gp14N8MVkASWtecxvbfa\r\n' + - 'xkj5SiC5NZQ2TZtt3DX508BPFSqJRjb83I7qhNjWxqFUxS1ma9PF/AQzUgNLw+Gz\r\n' + - 't5fpB3hD+33fWE8y4RbiUsBU+O56qaN9luOZLa/eVwo+I9F1LgXsS29iv6LvHO5m\r\n' + - '+IfzHM+FROS1XhzM+t8rxTK7VmBHqmPrKcjtnYXZh0eA9YIhTEeRdlEO8q4dsKFv\r\n' + - 'sbQZ3+65DW6pbDbe/3CGqf43w5vbTvhsRSYqC9ojKjnUtoJ8gY+b7GPNUVsgxQCh\r\n' + - 'jfqqZoVmhBihTO5hgeHJf+ilCbw5cPCEXobAxMfdPaasBV5xDBcvDDl7Sv16feYk\r\n' + - 'OZJ6bm9wRkqbQUsWYMgYLCfs/FDe1kfkSeS8JYlmFIkHZL6K3LqkULnqPfQdnlMp\r\n' + - '1PYGlPTdp+6XcqNBVORyXkOXF7PyrOw7vRefEuGcBvZ4TT0jmHE3KxKEvJwbVsne\r\n' + - 'H4/s3xo=', - p12keyonly: - 'MIIFEAIBAzCCBQkGCSqGSIb3DQEHAaCCBPoEggT2MIIE8jCCBO4GCSqGSIb3DQEH\r\n' + - 'AaCCBN8EggTbMIIE1zCCBNMGCyqGSIb3DQEMCgEBoIIEwjCCBL4CAQAwDQYJKoZI\r\n' + - 'hvcNAQEBBQAEggSoMIIEpAIBAAKCAQEAywBtDh9Z68eo/UrXL97CkxLe9ii8G2js\r\n' + - 'iwoGrS/c2YLaQ9/c2HJpIp+M45Lm4A840t98tyT6IZ04ssWJro5KkzrS3JAhX2Ue\r\n' + - 'hGHt84Rg5FpvRn5oFRlwQZP3Ki0E6tpfVhspzl/1c77zR4bhdi9vm5rU0evFap7j\r\n' + - 'DanfMYkIo77Aem8aRsrPSd+7fqPBbPlqKF8eL2Gn/GzyZ8fzqYgqIPt/ZfYp5nU8\r\n' + - 'r1G+mkDRfeUtvZUs6oy34UdaJzJn/COFBnihbnmWfbJglRD5p2WBpic+u2ezGZtP\r\n' + - 'Ez732gXQXb8eYas2zyctlK9rVXL6GaOZbPr87xnGGIiPugFGphwChwIDAQABAoIB\r\n' + - 'AQAIzAPt0L380bIpB807bdPQu8idsjY0md9mRxDzAFf5tQnwVwsi9hJIRdG9KuiG\r\n' + - 'XSKBQN4OsbOFMWL7nEPTJKdmqe3pUPWhRKiF5BiDrQDl5GVeEKxB/dA3h0n2sey8\r\n' + - 'oKnw+UxefRoN4gB44Qd0L6oOfC8syaLMdAYy2WGqq92L+uxpKsn5aRf66DxnQpR6\r\n' + - 'WoQIuTwZB4jYTUwFFCyURrzHoFxmZFCoBjAIhgpNDfejmcK4pzCjumChnbYMFVgt\r\n' + - 'sGyWNLaxJWosF6M0rTZj+ik0KfeAu63FTur9ZWYjn4QXuSnPEB1FPhmMnYHY6puk\r\n' + - 'XaMP8ixzgCwFbV0nm1PrT33BAoGBAOkIvqhfoLT4p3BAwcUbaCsAJUZAC7fJJcvG\r\n' + - '2IhnFJnddepP+W5j8HdLQVDkG6kWtaG2AvPIKDlc6fSyJwHAUkq3sYVWjwBeJ65M\r\n' + - 'GFzDqvu+jIh9e1lH0DIFTNiAePDwYzZNbNwq4+o9XMcZHLapgp1WiPR5VNjz2d8Y\r\n' + - '2pJX7/zbAoGBAN8B/JnoVIYgKe77oXfoX6JhcO+HKoBwvb9LGomBnJKTGn4fTCRn\r\n' + - 'OFORqzdZGHm/whZEsdYTsrQ92ASqGiiqGGoGjEHI8X+h5xBdH/+TokJFEKVpoAvZ\r\n' + - 'TZxOF01o58Kmk0uS/Q/h+dEoiN1Yx8phl00SXiqQCMFe+AMca51aH6rFAoGAMJi9\r\n' + - 'QdmnZvYP3O30OsmrYIRIQa0rhGkzM5rFHzT369puM63341h+FjKgbWEUj5+HwzB0\r\n' + - 'zyfnk4bX10qrrcbQonpKT/csHTSFa+i8j+PSLWugXPpmFclPFo9aZi/siLpoxjNB\r\n' + - 'R2y+WOPxDCglf8Y70dnw96Kx2giIX+kL88bY6k8CgYBZulHplypTISPeLU7FkTDR\r\n' + - 'hAVNywPV1Ab0rgJKa2UVMK0LLAqV5xYpwcWzKl0Ht5kfHpqzOQ/BJ9T/43VNAUt7\r\n' + - 'dZD/cxuAMCNpWR7j1YIGygUtmPc1bUSl7GHB2sDNd/pyAP1jY5gBiR6weOVCT8vx\r\n' + - 'zb8nvvZW36BImCnQkQ+GxQKBgQCJvY3GZCMC2vZCwFh/feWGGEhkWOCgtvV2a9oq\r\n' + - 'NpqIPgQI4RbdbKnm7UfLERzYiD9pnFBAjDnGkvrXGsovvCkx1sSBHnfag5hbulwW\r\n' + - '3j33vy+ssT0moHIsRwStCriv34Ez72QpiLPIVCAvgMYVyp6p+HyFqDueMS7AC3NI\r\n' + - 'BI7NnQ==', - p12encmixed: - 'MIIpiwIBAzCCKUUGCSqGSIb3DQEHAaCCKTYEgikyMIIpLjCCCtMGCSqGSIb3DQEH\r\n' + - 'AaCCCsQEggrAMIIKvDCCBVsGCyqGSIb3DQEMCgECoIIE+jCCBPYwKAYKKoZIhvcN\r\n' + - 'AQwBAzAaBBShXWqo+Nr8NS+e4cGS8Jlm64XRewICBAAEggTIMtqzJpmSCGAYKTj8\r\n' + - '1t3U0mGNAErZt0UA2EP9dcGvyG+0W+PMorwwduveGz5ymdqh+8mdbGOTTGKqLVmB\r\n' + - '9vR2826foDSgjB+x+fSX9UtSvf9xwF0J6VGPt64RP4J3c+5ntd/gleJCpeBW/div\r\n' + - 'ieeSRAJ0JX/JthDvO1VyzBOb8w5lakK/mCvLpcbUMIMnF6M/TT1rreqtl8GSx9+n\r\n' + - '+ne4tBWCUYAZfYHuKd2tCpT+lpP8pmZ7BYEvgyWPmYkNTkbPMAct1nJcN3L89Rt0\r\n' + - 'Yw2fg58pvzY0WlHK3H5rB4J7835jTnZLAYz2sjnlDXndwXtiH9AU3X3KQpSDHrkd\r\n' + - 'ypBQfPHVwB7f+UiKYx5KYNjT1ph2y4DoBV6e4tnQs4KjixtKnom/9ipqOwjP2o6+\r\n' + - '4rkZf3I+g8ZrTQygbmQBCfdduNwnhImf7XJezK2RoW9/b9WoSPGSuzsVmt7h+hYs\r\n' + - 'hGGx5mdk+iJTmst5MrdNx4byKLW+ThrFJ+eqUwm/d+ODQolu+gckOTyaUvNfjYy7\r\n' + - 'JYi7wnzKAiOyNHwoP+Efpwb+eDffDyg0u/SuEc3qulWr61hfvjihK7w9Vo21kW3r\r\n' + - 'a6vSL6mS9XBJjvJFdf5sEMiNTUxR7Zw4AsKUysgyiXRFM2hkxuwImFozyK+Er4OJ\r\n' + - 'ydi3NpzcAL2+a8JzB35QztRxnypn/v/bWIyt89fW1mrstkCwvNRBaYnI4AGDN0C7\r\n' + - 'jw5aYbOcdg3PbV69+5i4RCRkN2GU6LTovSaBvfBWxrJHav8pfinLhduOckwrWckx\r\n' + - 'O38vc0fSuTUQaXgL8fXofX6L0139l9fN2MfndI8+39JOlzXNCsldpX+Nt2PI2Awm\r\n' + - 'AgKEpLA3jbjazqvOmZUBxh0RVozzVu+JTbGWvkalEcmyncCuKSFZkMlP3SNrn4PS\r\n' + - 'tpHlohTPBPHpxgJce0O6ylxgUZkUsSDatE0joWW/YJ+us0bqeGej5OLvmI9/L9iH\r\n' + - '2jCFIN79WVG06GsNuiKON12KPL4J/B4rv9bguQHdcPGJcVXtKv1Uzscpy1uQcqZc\r\n' + - 'qVzl+Om4fbb0mg+vRXi9FQu//U35yK95NjF6KyniVF0riZWA6bb8dO4YdO4q9IYZ\r\n' + - 'OFeoLQ/Zl4Zg58ytsUsqoFW6yK7itGUAV1y4BPME4pqkQAI5EVgaFnng9Gdcq9hN\r\n' + - '3VHHJLUiCjMLCmWrzt5dTgNCLrvF60bDnM5w9VAkR1xvNzYL/ui0j5A5fbpFc7jz\r\n' + - '1JcwFilP9qD94MPBOoPRNJNRxDl1bigdBtR50VTo7tNt48sSZHdVWPGMaqjDndRg\r\n' + - 'ur3EJeQVMUvVf/5L9hDaZdqxJ9x6Va+5f4a4Or3ttOCb1qCawqutx6IcOc26EAVy\r\n' + - 'nQ47UXQ2j/AjDoG+T8u34+TQsiVyC5X96TezAfPk5Vp8KUBjhBy15Z0YlnxXw4Up\r\n' + - 'KzFPMfWOLTiElbJGaLtD7MXrXMQcdK9S2d/MR01zM8QuLwDH4OJfSJ53mlgsFmRG\r\n' + - 'x7L+nZS7961GpoGHIZRRWvi7yejNpzxBUN7rIERgUqVQeh3lLDeDz8XKT83Hzd5R\r\n' + - '4AufZHsVg4K1xHxczD1NVoc2O/GM40vyPiK2ms1mQPiTckyF1jrsfKYDwbkzE3yi\r\n' + - 'tJXp7Wlc5IHVQqULMU4wKQYJKoZIhvcNAQkUMRweGgBlAG4AYwByAHkAcAB0AGkA\r\n' + - 'bwBuAGsAZQB5MCEGCSqGSIb3DQEJFTEUBBJUaW1lIDEzMTE4NTUyMzg5NjQwggVZ\r\n' + - 'BgsqhkiG9w0BDAoBAqCCBPowggT2MCgGCiqGSIb3DQEMAQMwGgQUVHez67zL2YSj\r\n' + - 'TqMZjS54S+FO+3wCAgQABIIEyDFgx9KJvdvBoednovcwUJeTWhvvMl6owrJ2FhVY\r\n' + - 'FjahfYv7vLAKUeQiqnepRcATUzSHJgDDKlnW+0UDSGUqUoabbJhAqtHqrHFevGS2\r\n' + - 'YpPNCfi7C2XTm4+F1MNmlmZhsM8gIY+2lmVpjRm+DvymKBzRuEw81xcF+RFDdOTX\r\n' + - '/ka6l5leRoFWTbfTnpIxA5QBVvEH52UkDw3hcrmVIct0v60IseiOqiL/4IpbpjmF\r\n' + - '3/rQdinE2sckujcEJD8edu1zbZzZ7KIbklWpPvcMRqCQSgrTuW1/lBuyVH3cvoFp\r\n' + - 'FtaAw60f6X1ezKmiwA0nYIwahGVmyG4iektxO76zzBPkhL5HPD8BuJX+TRE9hYrZ\r\n' + - 'tk161/hKFznWpPEC5ferEEEQi0vB2In1uz7L9LkpmC/to1k8MI1A/0yhY5xXUh4H\r\n' + - 'hmp50OEsBnaXjDqPgtZeukqObjKbOSS4zL1WZ5vohJWQdF+C04d93MZoieUSz0yr\r\n' + - '1vSQ/JIr51NRKdffCgoZSFayv5vzFyTu9FKlUBgGEUMEzBdZ200v5ho7fHXWp1gW\r\n' + - 'TyZK1pdVAC6tnKIgfSdkG7txHUDru120G7AdFXoFeRo7zalxGiGx5RIn3b/qfmyO\r\n' + - 'MxcJX9wpFck9IcnN8L/S7hbxt9yAINshOyEM0rUXz0fjVZfcckKLso87YXCGJ7+X\r\n' + - '6HYe8bs7/uID7Yz7svD1iwnBlEPQInENZBEPuj6dtMYhMXXMHrY5nwNkXBGQioET\r\n' + - 'O6xLjigPX7AUSuCCIRuoHGfo54HxV5uCon2/ibDuhTr46FrTKxQl2xv3M6VoWF/+\r\n' + - '0vLiCGKDa/aT5dZhdZ9OqC56mr6dFf8fSntMBBBxtUmcLVySa33G5UCInSrnTgu0\r\n' + - 'fY8XGgud/V++xs5lr6jxFQjTdc0ec4muRBOflAvxGq/KKmhbO6h2sa9Ldmr9EABY\r\n' + - 'jRaMz63WvObklE1m1IajjiceVXNLwJCwf37J7HKp1836WiWl/psIRSpsV0gdeb7y\r\n' + - 'kEx54sEkbwtu8TNga6PbWUzwVEamFSGkAIxAnCCBj7W0okoLw+z1+FAby2lnMSSP\r\n' + - 'F9g6aEEACt0h7fgOb6AEi9NCqfrpiZADwW1E0FRYOf8sIy/z6NPQGft3aIlUG9DA\r\n' + - 'EZAm5IdZ0umQLMqeG30ZkC88W+ERhdIpVpwuHevdRyDwwN6SZ2+AZd5it1EOCLrC\r\n' + - '8CSWXyCNaSkPyoPzE0CpeayyhxYkQNg2KiLEOsOOOmSFpQx+R4QQjJL+chuX8T/D\r\n' + - 'rxrgUgnPWPTDRI5iTexcCBlPdMbeyxfpwIWU0ZZsQxK1eBdizIzw/2JTSyHYVZuq\r\n' + - 'nhznMaQHH0oA2PGqZw0y7Vu9iRzGU3RrEBBdGnZIwdz9agBc6BxqtLQ5tLKNLCBS\r\n' + - 'BZjrCbWe9yBarQOFOpVPiczt/oJju/d5jC9Sj1QDppjLTiajZlcoY+mHGqcbzoe4\r\n' + - 'wVN9+ZetkrGk4zDc8MPYMbHIxLR58P3noVZ6s84h1rhA8lKCg9vvG0jffcuveIRu\r\n' + - 'AosyBT0v0qVRUWMIXJKpJSivKPykbQm6J+bAoK8+l3yCJ0AWpDcw5Wo5XqV/t4px\r\n' + - 'xr95ikcr1+ANBRxa/TAl4oYuoqhlkx7Q8i/XCSudpXrswWcfR5ipc0tBzDFMMCcG\r\n' + - 'CSqGSIb3DQEJFDEaHhgAcwBpAGcAbgBhAHQAdQByAGUAawBlAHkwIQYJKoZIhvcN\r\n' + - 'AQkVMRQEElRpbWUgMTMxMTg1NTIzODg2MzCCHlMGCSqGSIb3DQEHBqCCHkQwgh5A\r\n' + - 'AgEAMIIeOQYJKoZIhvcNAQcBMCgGCiqGSIb3DQEMAQYwGgQUQmWgPDEzodyfX1/t\r\n' + - '0lON23fzMeUCAgQAgIIeAAxfoaegDbtpKNtbR/bKgGGecS1491HJMR22X5mHI5EV\r\n' + - 'UxPyuyM2bHky/U1eGix06P0ExQMV5kh/Eb+6vRLn+l0pTci53Ps2ITKFXvmqZ5Zx\r\n' + - 'yjFtU3LCzN/qh5rFsLpPLdFn4oNrBveXWNPJrIj3Sf93To2GkLFQQ2aINNHe76k3\r\n' + - 'O4jp6Kz4DKFrnyrY/fDDhHuGnkvHXBXPO+413PIV4Jgmv1zULkB94WpcJ35gsBGV\r\n' + - '3Njt7F0X10ZE3VN/tXlEPjaSv5k4zpG5Pe18Q4LnrPSN+XLfFLRnnYJiDlQkvO91\r\n' + - 'AOxqlAkUq4jAGbTBUeSt+8P5HaliAPDJA43/tEWrb7fX68VpIblm4Y38AIoZOL8u\r\n' + - 'uafg3WctcD9cy2rP6e0kblkcG4DLrwp/EezeXDxbOsdViiLU5SL1/RhO/0cqB2zw\r\n' + - '2scYLc6nJkxzC3iyzhukyn4834SAj+reJMzyiy9VviGQlDz4HFC+P9kYKOqbdW9N\r\n' + - 'YYLYluHWjnNzE1enaYSPNPuR1U9UhSN/wKVwmdXsLRK0+ee7xpryxpTeUNAwacGR\r\n' + - 'R7uWiXVBj+xQ2AG5qmW4fe1wxrZIL5bD1Z98ss3YLyUESUIv3K6MxkXZdp+gXv97\r\n' + - 'jN6j2r536fGpA6jWehjsjk03tL5Zjv4i0PZLUFj16T1uXMzmaKplVd1HYY6bhBl6\r\n' + - '7lJerTtrGnPpybAeVn5KFsct0HchWIOkAeqOy3tIqi3R1msIrtR5FviFCgFYS5sV\r\n' + - 'ly+T+rNdjQM4FrRk6y/IcCqoQTE6By8cYafRH58X07ix1+k5IFlrTbPrA8w1qQ6T\r\n' + - 'wI5ww0hf4aE3W7brXMlmLYBfwfkTWLH/yDQsXBLsma0y1G7Ixn0BLuo6FBm3ayC2\r\n' + - 'LEkN+iB+zEeC54oHE450Bhv1TOS80PrLzDW7wL789adWKXHgMmug9sT67gBbaFeU\r\n' + - 'u3Z8VTISGxmbrEJQAMEoLuQiujHSfpPb5zK02+A363r+bLt1VbIs5jrYMvaB7qrk\r\n' + - '7nVJbVYlPscGwUQUEq4YbCjlg77rhY6d61LIcguG5snF2JTnR74Gu72JpqkrrtA9\r\n' + - 'QHQ/njBnmIenXkqCzwcjyqiKUmPXazC/un7Hl3ZUp7BbbvfCJ1VNqtQJTdyS6kZ0\r\n' + - 'ZIURy6R4uenoOw9BJfTzLEi+on3af1XXavb8apGlTVCxs8hL4F2IR1A3bkB8fMHv\r\n' + - '5oie2te80GKp+B+r0VrEdOLy6BkLgEfuwrpcsIjz+6z83UhfMhgKAcXYJVUC/mmf\r\n' + - 'xO4hZ3AHKLCgVql8D4NoYPanQYEKx2sEoTDsCzsoh+E6OYhe4CiSBYwB4s5fKX1w\r\n' + - '5LVz7crf8Pg+WfffeP8Y/tDOiShz4luB7YVzw+sAy9Xil5+KmPO11yeDwIe3bdvu\r\n' + - 'SeTAgzZ4lx7aZUpQ2cGaswo5Ix3Q7z2WkooYxCi4+XVw+BhRO0pVuyQB04v5rr1W\r\n' + - 'EFlDAsC+RVcUw8gyM+tSxm5vqP7H6oEJT00tBYNAX/9ztDpoX4i2276s+6Iszz8B\r\n' + - 'kqqTfasb41xzUdFf1PpSzqVGKDi4lAftfedn4JFuQHhcI4MhtxwwecKUL3uHXWiW\r\n' + - '3o++dAjO7ybfBm3j0WIKGVwxfON5KnVetSOofc3ZahSklUqEuyaQ/X93FT4amYMJ\r\n' + - 'U7NwbLmrCuYe19/+0lt0ySSSBPNNJcV8r+/P0m4gR7athre9aSn/gU2rRrpYfXUS\r\n' + - 'SIskLLPn26naLqLW5eEqF9KBg77pGXoXA4guavjUtxEeDCL0ncqAPlhNlRc7NTw5\r\n' + - 'MGy65ozntamlGrAWK96fMesmF81ZFHyBH4XImDkIvEr62hmJUJuTh3lBhIGAmqwo\r\n' + - 'jcYdAkibrZh3RmhYNzuSAPoBOd959fOwb9SVltDea49XAopKTodL6FPX4UQbCuES\r\n' + - 'oml4ZBvRs+ykU+q1to+0QdoY8x0vzkEL1cOOEcbAQebK3kw3GmNZSi6+dzh+gC3C\r\n' + - 'xrt53S6VrPlO5kpvlMjUjd5LDTIa05Kz+pIXVXUJSY5zNEWtQ54ne3TIHoqpT8oB\r\n' + - '8aQ+AnUKznf3Q5S3hQSA0P/zeIcbLwUvDGwk5GI+X38vNm6zbg+fhLwKi0E87fGE\r\n' + - '4ZM1w+D5Cfzl6AOP8QTnM9Az/g7z+nlslfh1uS4O87WNnETXyFqOKuMK5MsAYBmg\r\n' + - 'mctsteL7lHbOcmATAX0MjGfewqvh3uVm18xg3S8RHbsQ42IC6NGDS7YfYI/ePrGu\r\n' + - 'hdaTeUJuQVm8vSseL5vTeINLbWG7znV4avDgFDx6V+lL77relJ6dQQkRoCf/SNc4\r\n' + - 'r3v2I1Dd7I77+AT/uBZ3laKsqQcUhcjhEb2iLzjWpZNnO54VhqILwVD8AU8QMQpu\r\n' + - 'bjMxDXNKY9nhDWZtCoSEcbmvReo5dYXLCAjUokd2utwT8xTj+D7MADWKLTIfUO4H\r\n' + - '/OKq26mKCZq/6xgoLzXpiQeDxBfojJA4HWvZTmPlqH2VzIihKNFgP3QD1TH/nPCp\r\n' + - 'LP0SULTuszYNMTbOOmPj8sYK57dVJUJc2/TiUr1rbxSEEnBL/y4BBUmWxESzNJuO\r\n' + - 'ohJcR8rnyeklB5tnB5KzYuJqb5Do8PX7h7sGKZWOX0JAQkyq6QNSpJPR3PQ4tTSo\r\n' + - 'vt2pn/+3Uj+9uEvMpYroJEaOMKW3kGL+PUxLg5xMmOWR86jGqHmfY/zx/sx0eiYL\r\n' + - 'xXlD7KzaNuBLKGnTv/7fK7OzNc9bmS+pIeru8jtPIm6i6u+mQ/byIehjIPYxR1m/\r\n' + - 'WBu7LJv4LALDHUh93Fnr92sdWkiV9yU5m5dMIgWzcT2Qis148p+y+w1teqJEnYsN\r\n' + - '7Ea1cRRbG/HXB4EmOuwI9oDU5so4gYqQKwv0YvL1P93AzxN0v5iA8g9JIcWD8jun\r\n' + - 'CeyV90HiPa/shqk/xMbwQTypfFK0kGSPPeCJNBeAmLlM4RoTdGHY7pSoYyuRaRZj\r\n' + - 'TgBfHT4WxQA5Wttp/rLlbJbyt0vabH15gyjE0WpYOItPh11ONchShJXh5/6zEyDS\r\n' + - 'Nyn6TjFLmoDqHRSIxNraYQd2q7e11v9CJX0eoqljjst0LAWPFZ7X4m+kSQtoTdzt\r\n' + - 'tuiPqkBY8wFokG/Mo0mDKwfTT1ZYSdygJZr8ZrNF+hXmBJN9mm4/0S+hN4Vtx/wm\r\n' + - 'KKWeUOysbqOl3r0EHhh0Mugo2ApTABBDwzoLy7UDXfmJT8T7M0hh+ZT1Pja+G1YL\r\n' + - '/HrGHx8eAQQj0c4hyqePC86jgSh3iIkaBJFgEpytfJAnRZ/qr50YK5G7J6R2EjrL\r\n' + - '8IGcABSimIidvn0gQ0fBB//LR3con+KjugsA8cTC/cTwfSoyWr9K9FhjpmQ0rxUZ\r\n' + - 'uE12auhTB2dNdCoOwai97jREVngGaL5GTqUqowNeUUXbedhQI5sRKphrRoinYjJ1\r\n' + - 'uPuJDLVEsur2pkenLZLZn4l0Srgq1KAOBuZzqqDT6adxfQn3eKN6H0XHja9HMYU5\r\n' + - 'eXNDEZyT+W6Xg4HcHtiH751LF62SR74GR1HiU3B1XXryXpxyBMGbzdypIDRR6PZb\r\n' + - '4o6na3Kx8nyYztI6KZ1Y4PukFqsYuCjFqjJDf9KtFM9eJyedSlsYGd2XDVMUpIlC\r\n' + - 'NQ9VbRk+hDoH+J74upvX3cbASGkjmuu6sIKdt+quV2vdbyCKukayeWBXVP8bCW4Z\r\n' + - 'ft0UIf8QIPmkP6GQ3F2qn/SjJI7WhrdGh04tpC0QuMdRLzJnd+R/tjA/QisCWxAW\r\n' + - '3WETPDphJMTqKHAUx/86VDSGV013uCrOkTXvuGJLOTl3mdbEj2+0+DLOE2APBsJc\r\n' + - 'O0Lt5P0Oouigbj+wSVz20Fg7QhXO8Wep7S0krHAXJv3FdV0Cdn6MXaxeCBOfY4Rf\r\n' + - 'MDUmN/xaiMk2mz7dfDRhg8OADNacg60RylM9jEQ1UclXNlzEBUseY7x3R7qqyeXz\r\n' + - '8zDQeCXj+PHFBm48fEvKhP5sqHNNZsB5cy53y6nVwM2Nb9XBOmVajX2kUSgQE3GQ\r\n' + - 'HdCZE45Gx9FNP+tG6fYRnOx33ABnJdYwcN4s7xNwBXlTFp2t4CLWPDjwXUSBPudh\r\n' + - '2Hy/IzXic86kMmpl09WvPY89eFQ9o1laR4y7M5vnx+GMpCGkxmYZBbOZIGESVoy0\r\n' + - '70R7mkVJDFpPQg8FONTNzJki4ggZ2osWBy9fHbE1DvM+MqZe+4zpikjeMwoqmsK4\r\n' + - 'flvcaautoiwLChpiG0/tjMw13JLPMW3ZMwQDfZXYta2ngT35X2iKcgZTykNSeVJe\r\n' + - 'bB+ABC1Q9+R9/xlmlrBIUzzZHjNWr2FqDfDvbIIhURYmOqojtncOCttvEg2BUKSU\r\n' + - 'DdHwTay9R34YmeM6GjzjAcJWY5PJUy+kYnD5Drkp0CNL3LSxoCuQEMqudFz/fMU/\r\n' + - 'C3PogT6Ncnkr1FVu4uvs3ujG2ufu2YaGrLcYw2/N1yOZJWnnz07goD94VtyojMNc\r\n' + - 'WTmKni3mHDobNYwHWiRW+g1vxptOH+u5efUlDuz9nnn6cOnqR73Xuht3wDOpyn/N\r\n' + - 'VfvhZLRa3xeTTVHFqQFU+oqPjTV9H6y58zWpGhu8HOvsBcMmU/FQS6mfK7ebPGGi\r\n' + - 'jboKbwLpHYFewi01tYgfqwn6hMMrzYPjJY1tsYJ8NIAsmRHkG70t70PVeTQ8cJoC\r\n' + - 'Fm2IFDsZV/iTDdrBqvRcyBo0XmONAQQKr7rk/90eM4fd8nxGm/cAp/67NotSWQHa\r\n' + - 'ZFdxhOPSBr6VBiS8SAfF1rIra8funxtQ5Yk04FPjsVotkm2nkMt4gntoM2b3w23Q\r\n' + - 'GBaNcyPikhkQ8UC80Fbz6UzyLBKbZqCDI/GSa1A4BSvp0vy1pndHzrynyytF4t80\r\n' + - 'r3I7e0M0SEHWYJFGmQ9szh3cXePvk0p5KJIu1BzPH6AoIK0dNRXQXAINnsxmpkeJ\r\n' + - '7pAkz0rIVxZ4SyH4TrZcXxnVJ0Gte9kd/95XSEZDyvT9Arhs/0jHzotxaua6wpK3\r\n' + - 'JFF4BEmRPE7U3PsPJQN1fm6mqOdmaCE0UrnLhaMf8uMzYOoXVV8A5eRIDtgJ3X8V\r\n' + - 'k6UkNbDt8mVlctLdkNM9tKkClaF4JnvyYYX16HS5sAJiZnM8vW46nh4KsYIVRqAf\r\n' + - 'DaAeJzxRTSInaW52tuDqrBPVnl5XiAKbrved1fOUSSorI+SptHzaHcIH20h2DuSJ\r\n' + - 'ryQnLseZ+F3sb7wdAUtQb6eMNvu7L3s1vBxKqKKlwAVuZEqQI/GT/5WAB34iul3U\r\n' + - 'hAZZX0xKfweRp27xLRyUiqGFAsOaoDIwRiDhVKJZVCwIa3dSKCW8jvmC+EaeSyKG\r\n' + - 'Wx7gGnJm9XovdI1hi/zHM60ABejiMnDeAACcvsCJqKXE/9YDFQF+yW30OSZ2AOUL\r\n' + - 'UWnyD493R347W2oPzV1HbYLd//2gIQFFeMDv0AWfJGv4K0JkZ/pGpaPAoee6Pd1C\r\n' + - 'OjcxbWhvbEwXDtVRFztCjgNd/rp4t+YQ9QbMczK3HplpMyYjIs0WdTU3gNWqmTEf\r\n' + - 'guOokh7tqlOHQso0gg3ax65vc2k9V2yLJz2CDkVkATKpJOjV4sNWGPnB4129xact\r\n' + - 'p9JfGDAWniAE4cYW/etNTXhNWJTzkSlb5Ad5JPPQ4p/lB97Xr/Krwjp1o3h2JTgC\r\n' + - 'IBfqb9g7WQ/B8EL0AwnoHxPDTdXAHOCiUr0y1M1w36thr56AVR97/R02k2XI3dxv\r\n' + - 'oS/bCgNtFFSao2O7uANqtU/SMHMl0BrR8dk+4924Wu0m06iNDZB8NU0jU5bqxcW6\r\n' + - 'wzf/rjqwIndehfpH7MkeCk6rM0JiVku/EKoCfg9DOAA2rLIiyWO2+mm5UWiT60a0\r\n' + - 'kmGwwrAxduugMnfVdb5fI8F+IyXYCH8Iwi6qpFvSLm4F/++0WP6pD1Xov6cRu9Eq\r\n' + - 'nQ4FcCFQJ62ymKlZ0+qZ1ywftKTRwNNlPfZezkqJm17sDI02AUAjGotxrSdDfca5\r\n' + - 'ViRxq+HJiQGVCUo4fEl4iMzSWaBLeQr9nSijB76dyq1e89NMXS0L3Uo6B7gbKm2i\r\n' + - 'AjRTUEN2LIGM7TiRC4kZRRMrgVcBBDAtuyY/sMDZ6bUageLXlAPSGZ+VY/a+usok\r\n' + - 'pxP+U88X7mkxuvvPIG7yKaxymdB993pRaVvLuPVcZRDmXIFrTSP5wxejRQpIvwNR\r\n' + - 'UeYwGQs1gAuM3l6N7trX99j6WBzZr09YRVPgehh5N3s/omrEMDMcExlmAdVOYNij\r\n' + - 'UN5NOZgPZrHTev4BtZa53FKttvGT9Ly9iLtle218tQyJRK7UQ/APZJzidpcy3p/x\r\n' + - 'U9AgXG9+horGLG4/HAmpZh4VH+8wXpiUxsC2rXLb0cAoFg03gStLvqXU93UU6KSn\r\n' + - 'xC0FYZZAqeFDdKbk4IMirklafEu+j45I+57RiCr7mpOyDI4o5FItWMzSxFo06ciw\r\n' + - 'aUT4eQf+pUFrBz0yUvgJArh3+VZdRhd8vycuxrYgfp9q4H1n2hOEOi/eeQCuJH36\r\n' + - 'RnAkToyRYwCepD3di2tf5FL2cW2DPMj69o7dIUHEn76SKVtgwmv5Q86rBWTecAn1\r\n' + - 'qkUXMst6qxyZCqHMsrQ0Bf7lcB9nSTvPXHzbJjLg0QRYi4qZzU46Vmo5bLw0l8R/\r\n' + - '66Wyv+OIastQdCB6S1JtRnE2zvR7nRA/TgfmbJBklgEUY9KeyRzh1Vkp7aykuMXV\r\n' + - '9bsND+1swzKgqTGxCyMMqIP6OQsr9AVlO4MsR8XCTOY4F/dTaCRHWXC/uvtuar/y\r\n' + - '8vFQeaUPSR10+XGxYb7tnaaBqdVy9MMuwz7Y3jYgvbfxku6aXJMyWFBRqCRskOZa\r\n' + - 'GQOMmb0j9QH/bl6goHBfCJjSSU+vkVytQf7ZtWyD+k4+R3X+nQEex0Eb+2nfzh3i\r\n' + - 'ZHSO7cqRz12/B8CmQ75L8suRcRrqINMdAZfmARp5s0UtmHYKbOcrxd4l625rUwTJ\r\n' + - 't0vih8+BK6k1F6oT1kCR6ZyfIHhh8dn22SYJAQFW3+WZsaPjLgkh0ihcyfhLfKMC\r\n' + - 'K3YvF/dt9rQDorwNwp5+xiuGUrwk7SLbc7wmNCFiD5nER3AhUSuGzQLfZzjeqYgK\r\n' + - 'Wge2QCPwtwzaHNp51c5QMvKqQfsg12P81qs3Jl/j+xKpzLh2vLYlnq8OuFd3lR6x\r\n' + - 'q0Rya6j4o+AqW/v1CJBRhS0qXTW/bHvPm8uU16Uw9W4AGPnISbLQh5sfOKkKgNN/\r\n' + - 'jTogehgId2rZ1VfhW7n9xvPkk2NEt+YmXHn7EuPri6GXPIDhaLWLaSpa8PYW+jxx\r\n' + - 'T0CDjYQkT/Q/TfuX3yzGHXKhMInKxjqihd1RQ2OIBLBF8/1UFNLM82XntXt2TJXK\r\n' + - 'kUQYAIJxH23h9ZBH2K3T2gNjOqLmiqE0C4QEW8xNO75TWiYm8j+sX2LmdYmXZP8C\r\n' + - 'iMlyE2shMVriN3t457D8S5a1aEvATDFxM4YL5k5OsZ6HrQ6PrnzZfrWXh5OxoxAU\r\n' + - '+FCXxpRi6lwY3yNi3kUteexRLZGrEz2FRPemDLsevShRqnsy/0OA/05TA6JxLVpd\r\n' + - 'Dd7ZWUBcIJZ7lQKMzfCAdWR20J7ngEuiUksQDo5h9/727aO/fbVh+aLVYY1EF+0p\r\n' + - '8gbM3/hyoGd8pujWqU1U7jLQACAp5zsy7xvnbiXYl42SaF1PFUP5aZrAPBcj0Fru\r\n' + - 't8SnPjys2JE172lCkQQOBglanklkpRiBDWYxG8josUyASo7EzddOneLNoMNl8+ZO\r\n' + - 'ZZYN6BRIioChYDsrrPZiootTU5DYC8a0/AcDsV6PQ48SlInCKtuAOi8nHJDVUzBI\r\n' + - 'QkDd13kAeIFEMOJUV17xh7eLpbe10bv1B8zUiMbvBTzWPXZHEbuNlWiGy960J4t3\r\n' + - 'x6NGEAfIjYg9+aMCf7uiEWd48s+nrKWymn7Ewg7llyMfK2Vsa9PVMilopGx42y51\r\n' + - 'HMIzSV4TjOxSAJmXFZs55w57Rqjx3+LP9P7Ilpde4Lh35hD6yX5hZW+gnQs+B/j8\r\n' + - 'DkBDeIYtMSz4tHqiK6rBUD/KnNUYYmOOGUi/bPyS4TH0ycbSFp1xx+rS/86Uh8YK\r\n' + - 'wSOVkKvL2VhGE5G0RSSvYLUkEPcjA8K+EaHf8aCWpnGmpr3rT7F00JFhmH/kDXcU\r\n' + - 'rtatu8Lniqm0sIV84nVEqHF9Vgz1D2d2/VYfLWlMDM5Mb8IWVUi8fjNFQf32bTCZ\r\n' + - 'ZYTNUSushCwwpo2R8akkURsev+zstIzw73MGldj2AJ6y/0h51Z4dpQuJbwsKIw4g\r\n' + - '5MH42cM4PwiQ7hpqDeGLoyfeAMRFnme/HZCsgBCv247KXdpuYolORXBwjiqhlXYl\r\n' + - '6W5aUXp7H+Idz+ahq+nEdsGR57lX1dCC731i8x7/0fl7LEAPGCgr3A0UqTesBKqV\r\n' + - '5iq03xmxLhXEyv5QJVPCmG2067Wuoi9hMbXWb/IuX6TV2GACuZ54x9ftWtrPtZ7J\r\n' + - 'bJEst/IK1SvODlNpk3Z8jcx8YFS7RzjrI3CuVrn45HXF5yHlzwiyBnaFiuBXaDFk\r\n' + - 'kFGnTIxDrDfBsxCN7v3snuf+eW41SaXv8BHAvi4A+cv5vpSduEGY+aZWdgLDsnxw\r\n' + - '+zU5GUhNuT28YKEYzyTnMTdo/QL1KZkFqRDqANeRK3V24OaxHt6sbxYuRLGphytc\r\n' + - 'uUnB6ICpHgwASejiJY/hWhm5PLI3jxdXAa7XOg7asESz1yo7FrJIwW7UlnNBOneA\r\n' + - 'yuYFdB0usNx+E63hsw+TJ9Sg0+t+mG2+Fr1hE2qEahF2BrrB9LW0xuTXmAeW2qHp\r\n' + - 'cOVLJigo9QsEy3Y/sPuDJC0z9MnsKefglpSZyGBxkpKtVN7ePHl/hmMBRD6W1aZ0\r\n' + - '8bdl0Ljj6SoT9DB8qqyUX3Km/5xSWguvp2hMa1s/J+dJAzOOGx9P94QOgggrImOR\r\n' + - 'yhMa/3i5qA9QPzT0ivMtQwS5HaGL6Hjv6jkmK1FzfCoOE8d6+9AuhvvbfZs3c0Wf\r\n' + - '31F5e09s6fPqXTk3Dw6TsiED+NjtTTywPEaNgjldpPjZPBpAl6pNx/i9KghBmaCG\r\n' + - 'LDsvFJ/BqZf1qYFKE47Ozf8jQ4b+ZgU37awZAKERnoEvPdJ3gv5H+pyjbYbacLG4\r\n' + - '2jF/pRzhiF0eRBuqY/5DrgMe1dkI9TNvBFzsX4YFOxZWca/kc26JhCajuH8MaTyW\r\n' + - 'LzOeIg6QKane6HBBxRvoOBMIa40oBhffbOi5FKukKUFS3xlPL3EwdS/aZK61vCR2\r\n' + - 'NPS7Y/d2vk80aNVRZAm2FBcmBWF6q7A825S7HqwM1izmlmqC6yWYXGofP8PuYfww\r\n' + - 'eWW5rm+3URjcRM54K5Ob7rfKu3q7zUwUAB6R7YM9pgeDbaARyE7mB0MmpB+3UqO8\r\n' + - 'F5heKtELqIskZGAiCKxGPKERoHPItKTV77ZCZ+ql0FjlJSrXVZ1P/9i/BiwdYmij\r\n' + - 'vhjCEtDcHWPXXIra6Hf5hTIUJ7conZ9ldGhHliV6Rso7ST1FGIsqrgYDyt1/+Vo4\r\n' + - 'hNBaUhWOHh65EKRblCW04v71KyaL8ms7Pevgcz4NZFtUwv3v2qI+OqdWBFFbc9Lr\r\n' + - 'cfiyt5XbZeUD4GiI5/wDVk0b07ev7xyoedeB7GvXgmb13D1vCtHYubeDyI+V7zlM\r\n' + - 'GXPvCkIPhj34fK6vhtHJIfHL3+8vf6emd7h4Ziakod9G0HYJTKbugpCmi6ejW8G9\r\n' + - 'X5Kzrn9c8HD7bNCUtwNFV0unoZUN3ReVAOLNn2N0LUfHBrlq/XwseHovUbzSomYT\r\n' + - 'Xtr/w+tiLSMSRLsJzAu0LJHgNtYPsPIavpim0OLTPg7JBmnzWoyEFCXcLvjNry6c\r\n' + - 'yCgA4RgfmBcJzXS1Uyf/TUM9IFoeTbGo9dIziygUdWXxrUzx2Uyak53xZXEX82cB\r\n' + - 'kC/v1+VCq668xgthc9pEEHIsqxKuRCUXj53xYThI5gSJke3XYrCdk3R8rh8FdkkQ\r\n' + - 'E/4WFpZ8kqraFXSYlfYvGHYd31cbJoSxjTIISd5US85KaOH2n3HN0d017xfwaSqS\r\n' + - 'I1l1iutPvcc+wxydp7On+uQAP4GiV1uPmuN0s0lu81j7ye9nS+fjxlXiukHQu1mF\r\n' + - 'c5IdEASgborfk+mrVpl/hpeLJH4LZIGPaZgr3KDBZPDMgqDCXBphL+GjJYPXyW7I\r\n' + - 't3QRCKMTNHCO7E3e7eet7k2ADSjrN1eZuzo7FxCU6cv+oCQUWPzaRYWb6gzr2QV4\r\n' + - 'snvwM2sGc0Mkg1QnJAzT6zrtfVZ2uh2VwkN93u8KxwiiCRn53rHn46uW1djNHmIe\r\n' + - '4E2vS4IWoCmy59lGxV6UEfsjEGxC+pDv33xX69aDf8vN6VON8B4ooHwdg+GMe2Us\r\n' + - 'N7sQkhf1ykdR0tmJnG8yr0DfGfxbcJArEv8wcZh89M0oOY7iKx/hq4n4DSVHLmDg\r\n' + - 'obV4S2+c5aRrVFWQiw+/OjA9MCEwCQYFKw4DAhoFAAQUXolDwewLkmOH6dGcPdhJ\r\n' + - 'JeUrAz0EFHRZbCAQ2bUo5B8DAFM8VJLi/+A2AgIEAA==', - p12ecdsa: 'MIIEwQIBAzCCBIcGCSqGSIb3DQEHAaCCBHgEggR0MIIEcDCCAy8GCSqGSIb3DQEHBqCCAyAwggMcAgEAMIIDFQYJKoZIhvcNAQcBMBwGCiqGSIb3DQEMAQYwDgQIxn3OksiScggCAggAgIIC6OB2GSW2p7zaoD4FS5+8kVRF8yTPFpNfV49YCQk49DzPEJoa2tKUE8dMh48jKEh3NRm4kemaN+CKZczTPB5xk21P/+PtLWzfFYFS8/wt/UJ+5NEbRHlVkI2GDj4HYwP+7E0ad0qi54UsuyxIeph7046Jag3keqfoKYinAoiEe3mvbWlICKTWj0PpuDQ2gxb7axwOnqsGfNC3J4HivnbcDPNL+/JReC5SgK/xEQpyBc4Fz49YA9qIGC6gQxNiIC9mQvq7M8hKDumYgkFWH25HXWzj6/pBT+4C8kQxkuLi+KWh9KWj8UXc2YaeqMR6MeJUJ7YMNELVGxU+a3ZY8NFkJf4jLAPy76u4JMEbX6meHtfmOAzqaGG6pnfuqZUWRHrTxYGWIWuTkSFfqCsB08McB6HYqEYm7juHqO7lqnIvRwh++TV7F/DJupOcS8sm4Q0+pI/Ug9lex27d/TVfFL2ICRfCVOvOtv65K+6fqNkPDrctQVl/kqS8tkWZoH+yfS/qDzICk9/fnAnO7bl4yiFGYp6ISbjAnki2NnRVdyGPQIO4B51VqqMeVzN3689ppJQZCajgw7afyq1rDt1dCqiD0OdnKXkARZEp2UeIqmMCMhVPRCeY1N+Z8yF8yWUv77SkGlwtMtyvhGYlrM3Wq/rweW6P20DfeSoLu9pU/ZxXe0X9a4ko/lXjKp/+ksJRZJcxWcRDxFRLtrHIWqrzIEdWilN/ld59HP6JU2+fhBkg+waWXd+lxEmIaVw6YY7WVmQT4riC17GGKjzyrNKQp0q4BDRZKJiJm1LSDBkGYUhWTkiHaZnihuwkidnXGaM6RshPu8c7nA29EoyoZjs4Vtj9dxQzwu6RvA+UvO3v+PMxxa0O/UKjU1XPLdhaxnc5KIUQGechjsgCooHQFOQ8hxEZPUQaBnebTRjq0W7Q+DhKv1EyGFWWRNG2cJRx1EDUO+A02nBvLck5DKOdIcJlsKiHWB0/ntCRqtQ7XzCCATkGCSqGSIb3DQEHAaCCASoEggEmMIIBIjCCAR4GCyqGSIb3DQEMCgECoIG0MIGxMBwGCiqGSIb3DQEMAQMwDgQI3Q+0WbOjf/0CAggABIGQhW8EaZfJhr+MTd4xjkUcubSPjzspoLeLtGLxmKxTBnbwBrKJBJ3bzXvU7we7qvvJGhWQfsRSHXEE841WS8I14veJJLWBJfN5V0AYz2aYkoApDQ61/o7mvgaAIn5rQQh20jp0EFXZM1TRqAT17pjBcBTaZ/s0wpUi2dbYqzhIgEYsQFQfHbW576eht5NlND3tMVgwIwYJKoZIhvcNAQkVMRYEFJ6dpRl6qwj5OZg36y8v5EVowEENMDEGCSqGSIb3DQEJFDEkHiIARQBDAEQAUwBBACAAYwBlAHIAdABpAGYAaQBjAGEAdABlMDEwITAJBgUrDgMCGgUABBSMcup2jX5JqMU5lqH8d/A0/kOu+wQI5FJlbGEnxF4CAggA', - p12ecdsaCert: '-----BEGIN CERTIFICATE-----\r\n' + - 'MIICVzCCAf6gAwIBAgIJAO8k1Go1w/58MAkGByqGSM49BAEwgYgxCzAJBgNVBAYT\r\n' + - 'AkZSMQ4wDAYDVQQIDAVwYXJpczEMMAoGA1UEBwwDSWxlMQ0wCwYDVQQKDARlcmRm\r\n' + - 'MSIwIAYDVQQDDBluaXphci5hYmRlbm5lYmlAZ21haWwuY29tMSgwJgYJKoZIhvcN\r\n' + - 'AQkBFhluaXphci5hYmRlbm5lYmlAZ21haWwuY29tMB4XDTE0MDczMDE2MTYyMloX\r\n' + - 'DTE1MDczMDE2MTYyMlowgYgxCzAJBgNVBAYTAkZSMQ4wDAYDVQQIDAVwYXJpczEM\r\n' + - 'MAoGA1UEBwwDSWxlMQ0wCwYDVQQKDARlcmRmMSIwIAYDVQQDDBluaXphci5hYmRl\r\n' + - 'bm5lYmlAZ21haWwuY29tMSgwJgYJKoZIhvcNAQkBFhluaXphci5hYmRlbm5lYmlA\r\n' + - 'Z21haWwuY29tMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAELqy3xekJMWlXzq5g\r\n' + - '5ao7Z8PH3iL0I2Tj28SGrDIdZ07f5x/rAbwjbcfp2YsJecEJOoaE3/jgbI8/mc1p\r\n' + - 'wWJtm6NQME4wHQYDVR0OBBYEFINzYXPWdpiaoDaLBiObKSezqjYSMB8GA1UdIwQY\r\n' + - 'MBaAFINzYXPWdpiaoDaLBiObKSezqjYSMAwGA1UdEwQFMAMBAf8wCQYHKoZIzj0E\r\n' + - 'AQNIADBFAiEA9Q+TJyUHEn7lhjEkF1OUb0hEwejAWny+mvqQ0XNHup4CIAeOLjEs\r\n' + - 'mthwYiI/c1op4Y+H0xLUp2v8iLWHIDqAZA89\r\n' + - '-----END CERTIFICATE-----\r\n' - }; -} - -// check for AMD -if(typeof define === 'function') { - define([ - 'forge/forge' - ], function(FORGE) { - Tests( - // Global provided by test harness - ASSERT, - FORGE - ); - }); -} else if(typeof module === 'object' && module.exports) { - // assume NodeJS - Tests( - require('assert'), - require('../../js/forge')); -} - -})(); diff --git a/alarm/node_modules/node-forge/nodejs/test/pkcs7.js b/alarm/node_modules/node-forge/nodejs/test/pkcs7.js deleted file mode 100644 index 2c4e793..0000000 --- a/alarm/node_modules/node-forge/nodejs/test/pkcs7.js +++ /dev/null @@ -1,350 +0,0 @@ -(function() { - -function Tests(ASSERT, PKCS7, PKI, AES, DES, UTIL) { - var _pem = { - p7: '-----BEGIN PKCS7-----\r\n' + - 'MIICTgYJKoZIhvcNAQcDoIICPzCCAjsCAQAxggHGMIIBwgIBADCBqTCBmzELMAkG\r\n' + - 'A1UEBhMCREUxEjAQBgNVBAgMCUZyYW5jb25pYTEQMA4GA1UEBwwHQW5zYmFjaDEV\r\n' + - 'MBMGA1UECgwMU3RlZmFuIFNpZWdsMRIwEAYDVQQLDAlHZWllcmxlaW4xFjAUBgNV\r\n' + - 'BAMMDUdlaWVybGVpbiBERVYxIzAhBgkqhkiG9w0BCQEWFHN0ZXNpZUBicm9rZW5w\r\n' + - 'aXBlLmRlAgkA1FQcQNg14vMwDQYJKoZIhvcNAQEBBQAEggEAJhWQz5SniCd1w3A8\r\n' + - 'uKVZEfc8Tp21I7FMfFqou+UOVsZCq7kcEa9uv2DIj3o7zD8wbLK1fuyFi4SJxTwx\r\n' + - 'kR0a6V4bbonIpXPPJ1f615dc4LydAi2tv5w14LJ1Js5XCgGVnkAmQHDaW3EHXB7X\r\n' + - 'T4w9PR3+tcS/5YAnWaM6Es38zCKHd7TnHpuakplIkwSK9rBFAyA1g/IyTPI+ktrE\r\n' + - 'EHcVuJcz/7eTlF6wJEa2HL8F1TVWuL0p/0GsJP/8y0MYGdCdtr+TIVo//3YGhoBl\r\n' + - 'N4tnheFT/jRAzfCZtflDdgAukW24CekrJ1sG2M42p5cKQ5rGFQtzNy/n8EjtUutO\r\n' + - 'HD5YITBsBgkqhkiG9w0BBwEwHQYJYIZIAWUDBAEqBBBmlpfy3WrYj3uWW7+xNEiH\r\n' + - 'gEAm2mfSF5xFPLEqqFkvKTM4w8PfhnF0ehmfQNApvoWQRQanNWLCT+Q9GHx6DCFj\r\n' + - 'TUHl+53x88BrCl1E7FhYPs92\r\n' + - '-----END PKCS7-----\r\n', - certificate: '-----BEGIN CERTIFICATE-----\r\n' + - 'MIIDtDCCApwCCQDUVBxA2DXi8zANBgkqhkiG9w0BAQUFADCBmzELMAkGA1UEBhMC\r\n' + - 'REUxEjAQBgNVBAgMCUZyYW5jb25pYTEQMA4GA1UEBwwHQW5zYmFjaDEVMBMGA1UE\r\n' + - 'CgwMU3RlZmFuIFNpZWdsMRIwEAYDVQQLDAlHZWllcmxlaW4xFjAUBgNVBAMMDUdl\r\n' + - 'aWVybGVpbiBERVYxIzAhBgkqhkiG9w0BCQEWFHN0ZXNpZUBicm9rZW5waXBlLmRl\r\n' + - 'MB4XDTEyMDMxODIyNTc0M1oXDTEzMDMxODIyNTc0M1owgZsxCzAJBgNVBAYTAkRF\r\n' + - 'MRIwEAYDVQQIDAlGcmFuY29uaWExEDAOBgNVBAcMB0Fuc2JhY2gxFTATBgNVBAoM\r\n' + - 'DFN0ZWZhbiBTaWVnbDESMBAGA1UECwwJR2VpZXJsZWluMRYwFAYDVQQDDA1HZWll\r\n' + - 'cmxlaW4gREVWMSMwIQYJKoZIhvcNAQkBFhRzdGVzaWVAYnJva2VucGlwZS5kZTCC\r\n' + - 'ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMsAbQ4fWevHqP1K1y/ewpMS\r\n' + - '3vYovBto7IsKBq0v3NmC2kPf3NhyaSKfjOOS5uAPONLffLck+iGdOLLFia6OSpM6\r\n' + - '0tyQIV9lHoRh7fOEYORab0Z+aBUZcEGT9yotBOraX1YbKc5f9XO+80eG4XYvb5ua\r\n' + - '1NHrxWqe4w2p3zGJCKO+wHpvGkbKz0nfu36jwWz5aihfHi9hp/xs8mfH86mIKiD7\r\n' + - 'f2X2KeZ1PK9RvppA0X3lLb2VLOqMt+FHWicyZ/wjhQZ4oW55ln2yYJUQ+adlgaYn\r\n' + - 'PrtnsxmbTxM+99oF0F2/HmGrNs8nLZSva1Vy+hmjmWz6/O8ZxhiIj7oBRqYcAocC\r\n' + - 'AwEAATANBgkqhkiG9w0BAQUFAAOCAQEAvfvtu31GFBO5+mFjPAoR4BlzKq/H3EPO\r\n' + - 'qS8cm/TjHgDRALwSnwKYCFs/bXqE4iOTD6otV4TusX3EPbqL2vzZQEcZn6paU/oZ\r\n' + - 'ZVXwQqMqY5tf2teQiNxqxNmSIEPRHOr2QVBVIx2YF4Po89KGUqJ9u/3/10lDqRwp\r\n' + - 'sReijr5UKv5aygEcnwcW8+Ne4rTx934UDsutKG20dr5trZfWQRVS9fS9CFwJehEX\r\n' + - 'HAMUc/0++80NhfQthmWZWlWM1R3dr4TrIPtWdn5z0MtGeDvqBk7HjGrhcVS6kAsy\r\n' + - 'Z9y/lfLPjBuxlQAHztEJCWgI4TW3/RLhgfg2gI1noM2n84Cdmisfkg==\r\n' + - '-----END CERTIFICATE-----\r\n', - privateKey: '-----BEGIN RSA PRIVATE KEY-----\r\n' + - 'MIIEowIBAAKCAQEAywBtDh9Z68eo/UrXL97CkxLe9ii8G2jsiwoGrS/c2YLaQ9/c\r\n' + - '2HJpIp+M45Lm4A840t98tyT6IZ04ssWJro5KkzrS3JAhX2UehGHt84Rg5FpvRn5o\r\n' + - 'FRlwQZP3Ki0E6tpfVhspzl/1c77zR4bhdi9vm5rU0evFap7jDanfMYkIo77Aem8a\r\n' + - 'RsrPSd+7fqPBbPlqKF8eL2Gn/GzyZ8fzqYgqIPt/ZfYp5nU8r1G+mkDRfeUtvZUs\r\n' + - '6oy34UdaJzJn/COFBnihbnmWfbJglRD5p2WBpic+u2ezGZtPEz732gXQXb8eYas2\r\n' + - 'zyctlK9rVXL6GaOZbPr87xnGGIiPugFGphwChwIDAQABAoIBAAjMA+3QvfzRsikH\r\n' + - 'zTtt09C7yJ2yNjSZ32ZHEPMAV/m1CfBXCyL2EkhF0b0q6IZdIoFA3g6xs4UxYvuc\r\n' + - 'Q9Mkp2ap7elQ9aFEqIXkGIOtAOXkZV4QrEH90DeHSfax7LygqfD5TF59Gg3iAHjh\r\n' + - 'B3Qvqg58LyzJosx0BjLZYaqr3Yv67GkqyflpF/roPGdClHpahAi5PBkHiNhNTAUU\r\n' + - 'LJRGvMegXGZkUKgGMAiGCk0N96OZwrinMKO6YKGdtgwVWC2wbJY0trElaiwXozSt\r\n' + - 'NmP6KTQp94C7rcVO6v1lZiOfhBe5Kc8QHUU+GYydgdjqm6Rdow/yLHOALAVtXSeb\r\n' + - 'U+tPfcECgYEA6Qi+qF+gtPincEDBxRtoKwAlRkALt8kly8bYiGcUmd116k/5bmPw\r\n' + - 'd0tBUOQbqRa1obYC88goOVzp9LInAcBSSrexhVaPAF4nrkwYXMOq+76MiH17WUfQ\r\n' + - 'MgVM2IB48PBjNk1s3Crj6j1cxxkctqmCnVaI9HlU2PPZ3xjaklfv/NsCgYEA3wH8\r\n' + - 'mehUhiAp7vuhd+hfomFw74cqgHC9v0saiYGckpMafh9MJGc4U5GrN1kYeb/CFkSx\r\n' + - '1hOytD3YBKoaKKoYagaMQcjxf6HnEF0f/5OiQkUQpWmgC9lNnE4XTWjnwqaTS5L9\r\n' + - 'D+H50SiI3VjHymGXTRJeKpAIwV74AxxrnVofqsUCgYAwmL1B2adm9g/c7fQ6yatg\r\n' + - 'hEhBrSuEaTMzmsUfNPfr2m4zrffjWH4WMqBtYRSPn4fDMHTPJ+eThtfXSqutxtCi\r\n' + - 'ekpP9ywdNIVr6LyP49Ita6Bc+mYVyU8Wj1pmL+yIumjGM0FHbL5Y4/EMKCV/xjvR\r\n' + - '2fD3orHaCIhf6QvzxtjqTwKBgFm6UemXKlMhI94tTsWRMNGEBU3LA9XUBvSuAkpr\r\n' + - 'ZRUwrQssCpXnFinBxbMqXQe3mR8emrM5D8En1P/jdU0BS3t1kP9zG4AwI2lZHuPV\r\n' + - 'ggbKBS2Y9zVtRKXsYcHawM13+nIA/WNjmAGJHrB45UJPy/HNvye+9lbfoEiYKdCR\r\n' + - 'D4bFAoGBAIm9jcZkIwLa9kLAWH995YYYSGRY4KC29XZr2io2mog+BAjhFt1sqebt\r\n' + - 'R8sRHNiIP2mcUECMOcaS+tcayi+8KTHWxIEed9qDmFu6XBbePfe/L6yxPSagcixH\r\n' + - 'BK0KuK/fgTPvZCmIs8hUIC+AxhXKnqn4fIWoO54xLsALc0gEjs2d\r\n' + - '-----END RSA PRIVATE KEY-----\r\n', - encryptedData: '-----BEGIN PKCS7-----\r\n' + - 'MIGHBgkqhkiG9w0BBwagejB4AgEAMHMGCSqGSIb3DQEHATAUBggqhkiG9w0DBwQI\r\n' + - 'upMFou5X3DWAUAqObuHSlewM0ZtHzWk9MAmtYb7MSb//OBMKVfLCdbmrS5BpKm9J\r\n' + - 'gzwiDR5Od7xgfkqasLS2lOdKAvJ5jZjjTpAyrjBKpShqK9gtXDuO0zH+\r\n' + - '-----END PKCS7-----\r\n', - p7IndefiniteLength: '-----BEGIN PKCS7-----\r\n' + - 'MIAGCSqGSIb3DQEHA6CAMIACAQAxggHGMIIBwgIBADCBqTCBmzELMAkGA1UEBhMC\r\n' + - 'REUxEjAQBgNVBAgMCUZyYW5jb25pYTEQMA4GA1UEBwwHQW5zYmFjaDEVMBMGA1UE\r\n' + - 'CgwMU3RlZmFuIFNpZWdsMRIwEAYDVQQLDAlHZWllcmxlaW4xFjAUBgNVBAMMDUdl\r\n' + - 'aWVybGVpbiBERVYxIzAhBgkqhkiG9w0BCQEWFHN0ZXNpZUBicm9rZW5waXBlLmRl\r\n' + - 'AgkA1FQcQNg14vMwDQYJKoZIhvcNAQEBBQAEggEAlWCH+E25c4jfff+m0eAxxMmE\r\n' + - 'WWaftdsk4ZpAVAr7HsvxJ35bj1mhwTh7rBTg929JBKt6ZaQ4I800jCNxD2O40V6z\r\n' + - 'lB7JNRqzgBwfeuU2nV6FB7v1984NBi1jQx6EfxOcusE6RL/63HqJdFbmq3Tl55gF\r\n' + - 'dm3JdjmHbCXqwPhuwOXU4yhkpV1RJcrYhPLe3OrLAH7ZfoE0nPJPOX9HPTZ6ReES\r\n' + - 'NToS7I9D9k7rCa8fAP7pgjO96GJGBtCHG1VXB9NX4w+xRDbgVPOeHXqqxwZhqpW2\r\n' + - 'usBU4+B+MnFLjquOPoySXFfdJFwTP61TPClUdyIne5FFP6EYf98mdtnkjxHo1TCA\r\n' + - 'BgkqhkiG9w0BBwEwFAYIKoZIhvcNAwcECFNtpqBmU3M9oIAESM+yyQLkreETS0Kc\r\n' + - 'o01yl6dqqNBczH5FNTK88ypz38/jzjo47+DURlvGzjHJibiDsCz9KyiVmgbRrtvH\r\n' + - '08rfnMbrU+grCkkx9wQI1GnLrYhr87oAAAAAAAAAAAAA\r\n' + - '-----END PKCS7-----\r\n', - p73des: '-----BEGIN PKCS7-----\r\n' + - 'MIICTQYJKoZIhvcNAQcDoIICPjCCAjoCAQAxggHGMIIBwgIBADCBqTCBmzELMAkG\r\n' + - 'A1UEBhMCREUxEjAQBgNVBAgMCUZyYW5jb25pYTEQMA4GA1UEBwwHQW5zYmFjaDEV\r\n' + - 'MBMGA1UECgwMU3RlZmFuIFNpZWdsMRIwEAYDVQQLDAlHZWllcmxlaW4xFjAUBgNV\r\n' + - 'BAMMDUdlaWVybGVpbiBERVYxIzAhBgkqhkiG9w0BCQEWFHN0ZXNpZUBicm9rZW5w\r\n' + - 'aXBlLmRlAgkA1FQcQNg14vMwDQYJKoZIhvcNAQEBBQAEggEAS6K+sQvdKcK6YafJ\r\n' + - 'maDPjBzyjf5jtBgVrFgBXTCRIp/Z2zAXa70skfxhbwTgmilYTacA7jPGRrnLmvBc\r\n' + - 'BjhyCKM3dRUyYgh1K1ka0w1prvLmRk6Onf5df1ZQn3AJMIujJZcCOhbV1ByLInve\r\n' + - 'xn02KNHstGmdHM/JGyPCp+iYGprhUozVSpNCKS+R33EbsT0sAxamfqdAblT9+5Qj\r\n' + - '4CABvW11a1clPV7STwBbAKbZaLs8mDeoWP0yHvBtJ7qzZdSgJJA2oU7SDv4icwEe\r\n' + - 'Ahccbe2HWkLRw8G5YG9XcWx5PnQQhhnXMxkLoSMIYxItyL/cRORbpDohd+otAo66\r\n' + - 'WLH1ODBrBgkqhkiG9w0BBwEwFAYIKoZIhvcNAwcECD5EWJMv1fd7gEj1w3WM1KsM\r\n' + - 'L8GDk9JoqA8t9v3oXCT0nAMXoNpHZMnv+0UHHVljlSXBTQxwUP5VMY/ddquJ5O3N\r\n' + - 'rDEqqJuHB+KPIsW1kxrdplU=\r\n' + - '-----END PKCS7-----\r\n' - }; - - describe('pkcs7', function() { - it('should import message from PEM', function() { - var p7 = PKCS7.messageFromPem(_pem.p7); - - ASSERT.equal(p7.type, PKI.oids.envelopedData); - ASSERT.equal(p7.version, 0); - - ASSERT.equal(p7.recipients.length, 1); - ASSERT.equal(p7.recipients[0].version, 0); - ASSERT.equal(p7.recipients[0].serialNumber, '00d4541c40d835e2f3'); - - // Test converted RDN, which is constructed of seven parts. - ASSERT.equal(p7.recipients[0].issuer.length, 7); - ASSERT.equal(p7.recipients[0].issuer[0].type, '2.5.4.6'); - ASSERT.equal(p7.recipients[0].issuer[0].value, 'DE'); - ASSERT.equal(p7.recipients[0].issuer[1].type, '2.5.4.8'); - ASSERT.equal(p7.recipients[0].issuer[1].value, 'Franconia'); - ASSERT.equal(p7.recipients[0].issuer[2].type, '2.5.4.7'); - ASSERT.equal(p7.recipients[0].issuer[2].value, 'Ansbach'); - ASSERT.equal(p7.recipients[0].issuer[3].type, '2.5.4.10'); - ASSERT.equal(p7.recipients[0].issuer[3].value, 'Stefan Siegl'); - ASSERT.equal(p7.recipients[0].issuer[4].type, '2.5.4.11'); - ASSERT.equal(p7.recipients[0].issuer[4].value, 'Geierlein'); - ASSERT.equal(p7.recipients[0].issuer[5].type, '2.5.4.3'); - ASSERT.equal(p7.recipients[0].issuer[5].value, 'Geierlein DEV'); - ASSERT.equal(p7.recipients[0].issuer[6].type, '1.2.840.113549.1.9.1'); - ASSERT.equal(p7.recipients[0].issuer[6].value, 'stesie@brokenpipe.de'); - - ASSERT.equal(p7.recipients[0].encryptedContent.algorithm, PKI.oids.rsaEncryption); - ASSERT.equal(p7.recipients[0].encryptedContent.content.length, 256); - - ASSERT.equal(p7.encryptedContent.algorithm, PKI.oids['aes256-CBC']); - ASSERT.equal(p7.encryptedContent.parameter.data.length, 16); // IV - }); - - it('should import indefinite length message from PEM', function() { - ASSERT.doesNotThrow(function() { - var p7 = PKCS7.messageFromPem(_pem.p7IndefiniteLength); - ASSERT.equal(p7.type, PKI.oids.envelopedData); - ASSERT.equal(p7.encryptedContent.parameter.toHex(), '536da6a06653733d'); - ASSERT.equal(p7.encryptedContent.content.length(), 80); - }); - }); - - it('should find recipient by serial number', function() { - var p7 = PKCS7.messageFromPem(_pem.p7); - var cert = PKI.certificateFromPem(_pem.certificate); - - var ri = p7.findRecipient(cert); - ASSERT.equal(ri.serialNumber, '00d4541c40d835e2f3'); - - // modify certificate so it doesn't match recipient any more - cert.serialNumber = '1234567890abcdef42'; - ri = p7.findRecipient(cert); - ASSERT.equal(ri, null); - }); - - it('should aes-decrypt message', function() { - var p7 = PKCS7.messageFromPem(_pem.p7); - var privateKey = PKI.privateKeyFromPem(_pem.privateKey); - p7.decrypt(p7.recipients[0], privateKey); - - // symmetric key must be 32 bytes long (AES 256 key) - ASSERT.equal(p7.encryptedContent.key.data.length, 32); - ASSERT.equal( - p7.content, - 'Today is Boomtime, the 9th day of Discord in the YOLD 3178\r\n'); - }); - - it('should 3des-decrypt message', function() { - var p7 = PKCS7.messageFromPem(_pem.p73des); - var privateKey = PKI.privateKeyFromPem(_pem.privateKey); - p7.decrypt(p7.recipients[0], privateKey); - - // symmetric key must be 24 bytes long (DES3 key) - ASSERT.equal(p7.encryptedContent.key.data.length, 24); - ASSERT.equal( - p7.content, - 'Today is Prickle-Prickle, ' + - 'the 16th day of Discord in the YOLD 3178\r\n'); - }); - - it('should add a recipient', function() { - var p7 = PKCS7.createEnvelopedData(); - - // initially there should be no recipients - ASSERT.equal(p7.recipients.length, 0); - - var cert = PKI.certificateFromPem(_pem.certificate); - p7.addRecipient(cert); - - ASSERT.equal(p7.recipients.length, 1); - ASSERT.deepEqual(p7.recipients[0].serialNumber, cert.serialNumber); - ASSERT.deepEqual(p7.recipients[0].issuer, cert.subject.attributes); - ASSERT.deepEqual(p7.recipients[0].encryptedContent.key, cert.publicKey); - }); - - it('should aes-encrypt a message', function() { - var p7 = PKCS7.createEnvelopedData(); - var cert = PKI.certificateFromPem(_pem.certificate); - var privateKey = PKI.privateKeyFromPem(_pem.privateKey); - - p7.addRecipient(cert); - p7.content = UTIL.createBuffer('Just a little test'); - - // pre-condition, PKCS#7 module should default to AES-256-CBC - ASSERT.equal(p7.encryptedContent.algorithm, PKI.oids['aes256-CBC']); - p7.encrypt(); - - // since we did not provide a key, a random key should have been created - // automatically, AES256 requires 32 bytes of key material - ASSERT.equal(p7.encryptedContent.key.data.length, 32); - - // furthermore an IV must be generated, AES256 has 16 byte IV - ASSERT.equal(p7.encryptedContent.parameter.data.length, 16); - - // content is 18 bytes long, AES has 16 byte blocksize, - // with padding that makes 32 bytes - ASSERT.equal(p7.encryptedContent.content.data.length, 32); - - // RSA encryption should yield 256 bytes - ASSERT.equal(p7.recipients[0].encryptedContent.content.length, 256); - - // rewind Key & IV - p7.encryptedContent.key.read = 0; - p7.encryptedContent.parameter.read = 0; - - // decryption of the asym. encrypted data should reveal the symmetric key - var decryptedKey = privateKey.decrypt( - p7.recipients[0].encryptedContent.content); - ASSERT.equal(decryptedKey, p7.encryptedContent.key.data); - - // decryption of sym. encrypted data should reveal the content - var ciph = AES.createDecryptionCipher(decryptedKey); - ciph.start(p7.encryptedContent.parameter); - ciph.update(p7.encryptedContent.content); - ciph.finish(); - ASSERT.equal(ciph.output, 'Just a little test'); - }); - - it('should 3des-ede-encrypt a message', function() { - var p7 = PKCS7.createEnvelopedData(); - var cert = PKI.certificateFromPem(_pem.certificate); - var privateKey = PKI.privateKeyFromPem(_pem.privateKey); - - p7.addRecipient(cert); - p7.content = UTIL.createBuffer('Just a little test'); - p7.encryptedContent.algorithm = PKI.oids['des-EDE3-CBC']; - p7.encrypt(); - - // since we did not provide a key, a random key should have been created - // automatically, 3DES-EDE requires 24 bytes of key material - ASSERT.equal(p7.encryptedContent.key.data.length, 24); - - // furthermore an IV must be generated, DES3 has 8 byte IV - ASSERT.equal(p7.encryptedContent.parameter.data.length, 8); - - // content is 18 bytes long, DES has 8 byte blocksize, - // with padding that makes 24 bytes - ASSERT.equal(p7.encryptedContent.content.data.length, 24); - - // RSA encryption should yield 256 bytes - ASSERT.equal(p7.recipients[0].encryptedContent.content.length, 256); - - // rewind Key & IV - p7.encryptedContent.key.read = 0; - p7.encryptedContent.parameter.read = 0; - - // decryption of the asym. encrypted data should reveal the symmetric key - var decryptedKey = privateKey.decrypt( - p7.recipients[0].encryptedContent.content); - ASSERT.equal(decryptedKey, p7.encryptedContent.key.data); - - // decryption of sym. encrypted data should reveal the content - var ciph = DES.createDecryptionCipher(decryptedKey); - ciph.start(p7.encryptedContent.parameter); - ciph.update(p7.encryptedContent.content); - ciph.finish(); - ASSERT.equal(ciph.output, 'Just a little test'); - }); - - it('should export message to PEM', function() { - var p7 = PKCS7.createEnvelopedData(); - p7.addRecipient(PKI.certificateFromPem(_pem.certificate)); - p7.content = UTIL.createBuffer('Just a little test'); - p7.encrypt(); - - var pem = PKCS7.messageToPem(p7); - - // convert back from PEM to new PKCS#7 object, decrypt, and test - p7 = PKCS7.messageFromPem(pem); - p7.decrypt(p7.recipients[0], PKI.privateKeyFromPem(_pem.privateKey)); - ASSERT.equal(p7.content, 'Just a little test'); - }); - - it('should decrypt encrypted data from PEM', function() { - var result = '1f8b08000000000000000b2e494d4bcc5308ce4c4dcfd15130b0b430d4b7343732b03437d05170cc2b4e4a4cced051b034343532d25170492d2d294ecec849cc4b0100bf52f02437000000'; - var key = 'b96e4a4c0a3555d31e1b295647cc5cfe74081918cb7f797b'; - key = UTIL.createBuffer(UTIL.hexToBytes(key)); - - ASSERT.doesNotThrow(function() { - var p7 = PKCS7.messageFromPem(_pem.encryptedData); - ASSERT.equal(p7.type, PKI.oids.encryptedData); - ASSERT.equal(p7.encryptedContent.algorithm, PKI.oids['des-EDE3-CBC']); - ASSERT.equal(p7.encryptedContent.parameter.toHex(), 'ba9305a2ee57dc35'); - ASSERT.equal(p7.encryptedContent.content.length(), 80); - - p7.decrypt(key); - ASSERT.equal(p7.content.toHex(), result); - }); - }); - }); -} - -// check for AMD -if(typeof define === 'function') { - define([ - 'forge/pkcs7', - 'forge/pki', - 'forge/aes', - 'forge/des', - 'forge/util' - ], function(PKCS7, PKI, AES, DES, UTIL) { - Tests( - // Global provided by test harness - ASSERT, - PKCS7(), - PKI(), - AES(), - DES(), - UTIL() - ); - }); -} else if(typeof module === 'object' && module.exports) { - // assume NodeJS - Tests( - require('assert'), - require('../../js/pkcs7')(), - require('../../js/pki')(), - require('../../js/aes')(), - require('../../js/des')(), - require('../../js/util')()); -} - -})(); diff --git a/alarm/node_modules/node-forge/nodejs/test/random.js b/alarm/node_modules/node-forge/nodejs/test/random.js deleted file mode 100644 index efeec2b..0000000 --- a/alarm/node_modules/node-forge/nodejs/test/random.js +++ /dev/null @@ -1,70 +0,0 @@ -(function() { - -function Tests(ASSERT, RANDOM, UTIL) { - var random = RANDOM(); - - describe('random', function() { - it('should generate 10 random bytes', function() { - random.getBytes(16); - random.getBytes(24); - random.getBytes(32); - - var b = random.getBytes(10); - ASSERT.equal(b.length, 10); - }); - - it('should use a synchronous seed file', function() { - var rand = RANDOM(); - rand.seedFileSync = function(needed) { - return UTIL.fillString('a', needed); - }; - var b = rand.getBytes(10); - ASSERT.equal(UTIL.bytesToHex(b), '80a7901a239c3e606319'); - }); - - it('should use an asynchronous seed file', function(done) { - var rand = RANDOM(); - rand.seedFile = function(needed, callback) { - callback(null, UTIL.fillString('a', needed)); - }; - rand.getBytes(10, function(err, b) { - ASSERT.equal(err, null); - ASSERT.equal(UTIL.bytesToHex(b), '80a7901a239c3e606319'); - done(); - }); - }); - - it('should collect some random bytes', function() { - var rand = RANDOM(); - rand.seedFileSync = function(needed) { - return UTIL.fillString('a', needed); - }; - rand.collect('bbb'); - var b = rand.getBytes(10); - ASSERT.equal(UTIL.bytesToHex(b), 'ff8d213516047c94ca46'); - }); - }); -} - -// check for AMD -if(typeof define === 'function') { - define([ - 'forge/random', - 'forge/util' - ], function(RANDOM, UTIL) { - Tests( - // Global provided by test harness - ASSERT, - RANDOM, - UTIL() - ); - }); -} else if(typeof module === 'object' && module.exports) { - // assume NodeJS - Tests( - require('assert'), - require('../../js/random'), - require('../../js/util')()); -} - -})(); diff --git a/alarm/node_modules/node-forge/nodejs/test/rc2.js b/alarm/node_modules/node-forge/nodejs/test/rc2.js deleted file mode 100644 index 2acbe7b..0000000 --- a/alarm/node_modules/node-forge/nodejs/test/rc2.js +++ /dev/null @@ -1,109 +0,0 @@ -(function() { - -function Tests(ASSERT, RC2, UTIL) { - describe('rc2', function() { - it('should expand a 128-bit key', function() { - var key = UTIL.hexToBytes('88bca90e90875a7f0f79c384627bafb2'); - var expect = '71ab26462f0b9333609d4476e48ab72438c2194b70a47085d84b6af1dc72119023b94fe80aee2b6b45f27f923d9be1570da3ce8b16ad7f78db166ffbc28a836a4392cf0b748085dae4b69bdc2a4679cdfc09d84317016987e0c5b765c91dc612b1f44d7921b3e2c46447508bd2ac02e119e0f42a89c719675da320cf3e8958cd'; - ASSERT.equal(RC2.expandKey(key).toHex(), expect); - }); - - it('should expand a 40-bit key', function() { - var key = UTIL.hexToBytes('88bca90e90'); - var expect = 'af136d2243b94a0878d7a604f8d6d9fd64a698fd6ebc613e641f0d1612055ef6cb55966db8f32bfd9246dae99880be8a91433adf54ea546d9daad62db7a55f6c7790aa87ba67de0e9ea9128dfc7ccdddd7c47c33d2bb7f823729977f083b5dc1f5bb09000b98e12cdaaf22f80dcc88c37d2c2fd80402f8a30a9e41d356669471'; - ASSERT.equal(RC2.expandKey(key, 40).toHex(), expect); - }); - - it('should rc2-ecb encrypt zeros', function() { - var key = UTIL.hexToBytes('88bca90e90875a7f0f79c384627bafb2'); - var input = new UTIL.createBuffer().fillWithByte(0, 8); - var cipher = RC2.startEncrypting(key, null, null); - cipher.update(input); - cipher.finish(); - ASSERT.equal(cipher.output.toHex(), '2269552ab0f85ca6e35b3b2ce4e02191'); - }); - - it('should rc2-ecb encrypt: vegan', function() { - var key = UTIL.hexToBytes('88bca90e90875a7f0f79c384627bafb2'); - var input = new UTIL.createBuffer('vegan'); - var cipher = RC2.startEncrypting(key, null, null); - cipher.update(input); - cipher.finish(); - ASSERT.equal(cipher.output.toHex(), '2194adaf4d517e3a'); - }); - - it('should rc2-ecb decrypt: 2194adaf4d517e3a', function() { - var key = UTIL.hexToBytes('88bca90e90875a7f0f79c384627bafb2'); - var input = new UTIL.createBuffer(UTIL.hexToBytes('2194adaf4d517e3a')); - var cipher = RC2.startDecrypting(key, null, null); - cipher.update(input); - cipher.finish(); - ASSERT.equal(cipher.output.getBytes(), 'vegan'); - }); - - it('should rc2-cbc encrypt: revolution', function() { - var key = UTIL.hexToBytes('88bca90e90875a7f0f79c384627bafb2'); - var iv = new UTIL.createBuffer(UTIL.hexToBytes('0123456789abcdef')); - var input = new UTIL.createBuffer('revolution'); - var cipher = RC2.startEncrypting(key, iv, null); - cipher.update(input); - cipher.finish(); - ASSERT.equal(cipher.output.toHex(), '50cfd16e0fd7f20b17a622eb2a469b7e'); - }); - - it('should rc2-cbc decrypt: 50cfd16e0fd7f20b17a622eb2a469b7e', function() { - var key = UTIL.hexToBytes('88bca90e90875a7f0f79c384627bafb2'); - var iv = new UTIL.createBuffer(UTIL.hexToBytes('0123456789abcdef')); - var input = new UTIL.createBuffer( - UTIL.hexToBytes('50cfd16e0fd7f20b17a622eb2a469b7e')); - var cipher = RC2.startDecrypting(key, iv, null); - cipher.update(input); - cipher.finish(); - ASSERT.equal(cipher.output, 'revolution'); - }); - - it('should rc2-cbc encrypt w/binary string iv: revolution', function() { - var key = UTIL.hexToBytes('88bca90e90875a7f0f79c384627bafb2'); - var iv = UTIL.hexToBytes('0123456789abcdef'); - var input = new UTIL.createBuffer('revolution'); - var cipher = RC2.startEncrypting(key, iv, null); - cipher.update(input); - cipher.finish(); - ASSERT.equal(cipher.output.toHex(), '50cfd16e0fd7f20b17a622eb2a469b7e'); - }); - - it('should rc2-cbc decrypt w/binary string iv: 50cfd16e0fd7f20b17a622eb2a469b7e', function() { - var key = UTIL.hexToBytes('88bca90e90875a7f0f79c384627bafb2'); - var iv = UTIL.hexToBytes('0123456789abcdef'); - var input = new UTIL.createBuffer( - UTIL.hexToBytes('50cfd16e0fd7f20b17a622eb2a469b7e')); - var cipher = RC2.startDecrypting(key, iv, null); - cipher.update(input); - cipher.finish(); - ASSERT.equal(cipher.output, 'revolution'); - }); - }); -} - -// check for AMD -if(typeof define === 'function') { - define([ - 'forge/rc2', - 'forge/util' - ], function(RC2, UTIL) { - Tests( - // Global provided by test harness - ASSERT, - RC2(), - UTIL() - ); - }); -} else if(typeof module === 'object' && module.exports) { - // assume NodeJS - Tests( - require('assert'), - require('../../js/rc2')(), - require('../../js/util')()); -} - -})(); diff --git a/alarm/node_modules/node-forge/nodejs/test/rsa.js b/alarm/node_modules/node-forge/nodejs/test/rsa.js deleted file mode 100644 index 434d7a3..0000000 --- a/alarm/node_modules/node-forge/nodejs/test/rsa.js +++ /dev/null @@ -1,602 +0,0 @@ -(function() { - -function Tests(ASSERT, PKI, RSA, MD, MGF, PSS, RANDOM, UTIL) { - var _pem = { - privateKey: '-----BEGIN RSA PRIVATE KEY-----\r\n' + - 'MIICXQIBAAKBgQDL0EugUiNGMWscLAVM0VoMdhDZEJOqdsUMpx9U0YZI7szokJqQ\r\n' + - 'NIwokiQ6EonNnWSMlIvy46AhnlRYn+ezeTeU7eMGTkP3VF29vXBo+dLq5e+8VyAy\r\n' + - 'Q3FzM1wI4ts4hRACF8w6mqygXQ7i/SDu8/rXqRGtvnM+z0MYDdKo80efzwIDAQAB\r\n' + - 'AoGAIzkGONi5G+JifmXlLJdplom486p3upf4Ce2/7mqfaG9MnkyPSairKD/JXvfh\r\n' + - 'NNWkkN8DKKDKBcVVElPgORYT0qwrWc7ueLBMUCbRXb1ZyfEulimG0R3kjUh7NYau\r\n' + - 'DaIkVgfykXGSQMZx8FoaT6L080zd+0emKDDYRrb+/kgJNJECQQDoUZoiC2K/DWNY\r\n' + - 'h3/ppZ0ane2y4SBmJUHJVMPQ2CEgxsrJTxet668ckNCKaOP/3VFPoWC41f17DvKq\r\n' + - 'noYINNntAkEA4JbZBZBVUrQFhHlrpXT4jzqtO2RlKZzEq8qmFZfEErxOT1WMyyCi\r\n' + - 'lAQ5gUKardo1Kf0omC8Xq/uO9ZYdED55KwJBALs6cJ65UFaq4oLJiQPzLd7yokuE\r\n' + - 'dcj8g71PLBTW6jPxIiMFNA89nz3FU9wIVp+xbMNhSoMMKqIPVPC+m0Rn260CQQDA\r\n' + - 'I83fWK/mZWUjBM33a68KumRiH238v8XyQxj7+C8i6D8G2GXvkigFAehAkb7LZZd+\r\n' + - 'KLuGFyPlWv3fVWHf99KpAkBQFKk3MRMl6IGJZUEFQe4l5whm8LkGU4acSqv9B3xt\r\n' + - 'qROkCrsFrMPqjuuzEmyHoQZ64r2PLJg7FOuyhBnQUOt4\r\n' + - '-----END RSA PRIVATE KEY-----\r\n', - privateKeyInfo: '-----BEGIN PRIVATE KEY-----\r\n' + - 'MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAMvQS6BSI0Yxaxws\r\n' + - 'BUzRWgx2ENkQk6p2xQynH1TRhkjuzOiQmpA0jCiSJDoSic2dZIyUi/LjoCGeVFif\r\n' + - '57N5N5Tt4wZOQ/dUXb29cGj50url77xXIDJDcXMzXAji2ziFEAIXzDqarKBdDuL9\r\n' + - 'IO7z+tepEa2+cz7PQxgN0qjzR5/PAgMBAAECgYAjOQY42Lkb4mJ+ZeUsl2mWibjz\r\n' + - 'qne6l/gJ7b/uap9ob0yeTI9JqKsoP8le9+E01aSQ3wMooMoFxVUSU+A5FhPSrCtZ\r\n' + - 'zu54sExQJtFdvVnJ8S6WKYbRHeSNSHs1hq4NoiRWB/KRcZJAxnHwWhpPovTzTN37\r\n' + - 'R6YoMNhGtv7+SAk0kQJBAOhRmiILYr8NY1iHf+mlnRqd7bLhIGYlQclUw9DYISDG\r\n' + - 'yslPF63rrxyQ0Ipo4//dUU+hYLjV/XsO8qqehgg02e0CQQDgltkFkFVStAWEeWul\r\n' + - 'dPiPOq07ZGUpnMSryqYVl8QSvE5PVYzLIKKUBDmBQpqt2jUp/SiYLxer+471lh0Q\r\n' + - 'PnkrAkEAuzpwnrlQVqrigsmJA/Mt3vKiS4R1yPyDvU8sFNbqM/EiIwU0Dz2fPcVT\r\n' + - '3AhWn7Fsw2FKgwwqog9U8L6bRGfbrQJBAMAjzd9Yr+ZlZSMEzfdrrwq6ZGIfbfy/\r\n' + - 'xfJDGPv4LyLoPwbYZe+SKAUB6ECRvstll34ou4YXI+Va/d9VYd/30qkCQFAUqTcx\r\n' + - 'EyXogYllQQVB7iXnCGbwuQZThpxKq/0HfG2pE6QKuwWsw+qO67MSbIehBnrivY8s\r\n' + - 'mDsU67KEGdBQ63g=\r\n' + - '-----END PRIVATE KEY-----\r\n', - publicKey: '-----BEGIN PUBLIC KEY-----\r\n' + - 'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDL0EugUiNGMWscLAVM0VoMdhDZ\r\n' + - 'EJOqdsUMpx9U0YZI7szokJqQNIwokiQ6EonNnWSMlIvy46AhnlRYn+ezeTeU7eMG\r\n' + - 'TkP3VF29vXBo+dLq5e+8VyAyQ3FzM1wI4ts4hRACF8w6mqygXQ7i/SDu8/rXqRGt\r\n' + - 'vnM+z0MYDdKo80efzwIDAQAB\r\n' + - '-----END PUBLIC KEY-----\r\n' - }; - var _signature = - '9200ece65cdaed36bcc20b94c65af852e4f88f0b4fe5b249d54665f815992ac4' + - '3a1399e65d938c6a7f16dd39d971a53ca66523209dbbfbcb67afa579dbb0c220' + - '672813d9e6f4818f29b9becbb29da2032c5e422da97e0c39bfb7a2e7d568615a' + - '5073af0337ff215a8e1b2332d668691f4fb731440055420c24ac451dd3c913f4'; - - describe('rsa', function() { - it('should generate 512 bit key pair', function() { - var pair = RSA.generateKeyPair(512); - ASSERT.equal(PKI.privateKeyToPem(pair.privateKey).indexOf('-----BEGIN RSA PRIVATE KEY-----'), 0); - ASSERT.equal(PKI.publicKeyToPem(pair.publicKey).indexOf('-----BEGIN PUBLIC KEY-----'), 0); - - // sign and verify - var md = MD.sha1.create(); - md.update('0123456789abcdef'); - var signature = pair.privateKey.sign(md); - ASSERT.ok(pair.publicKey.verify(md.digest().getBytes(), signature)); - }); - - it('should generate the same 512 bit key pair', function() { - var prng = RANDOM.createInstance(); - prng.seedFileSync = function(needed) { - return UTIL.fillString('a', needed); - }; - var pair = RSA.generateKeyPair(512, {prng: prng}); - var pem = { - privateKey: PKI.privateKeyToPem(pair.privateKey), - publicKey: PKI.publicKeyToPem(pair.publicKey) - }; - ASSERT.equal(pem.privateKey.indexOf('-----BEGIN RSA PRIVATE KEY-----'), 0); - ASSERT.equal(pem.publicKey.indexOf('-----BEGIN PUBLIC KEY-----'), 0); - - // sign and verify - var md = MD.sha1.create(); - md.update('0123456789abcdef'); - var signature = pair.privateKey.sign(md); - ASSERT.ok(pair.publicKey.verify(md.digest().getBytes(), signature)); - - // create same key pair by using same PRNG - prng = RANDOM.createInstance(); - prng.seedFileSync = function(needed) { - return UTIL.fillString('a', needed); - }; - var pair2 = RSA.generateKeyPair(512, {prng: prng}); - var pem2 = { - privateKey: PKI.privateKeyToPem(pair2.privateKey), - publicKey: PKI.publicKeyToPem(pair2.publicKey) - }; - ASSERT.equal(pem.privateKey, pem2.privateKey); - ASSERT.equal(pem.publicKey, pem2.publicKey); - }); - - it('should convert private key to/from PEM', function() { - var privateKey = PKI.privateKeyFromPem(_pem.privateKey); - ASSERT.equal(PKI.privateKeyToPem(privateKey), _pem.privateKey); - }); - - it('should convert public key to/from PEM', function() { - var publicKey = PKI.publicKeyFromPem(_pem.publicKey); - ASSERT.equal(PKI.publicKeyToPem(publicKey), _pem.publicKey); - }); - - it('should convert a PKCS#8 PrivateKeyInfo to/from PEM', function() { - var privateKey = PKI.privateKeyFromPem(_pem.privateKeyInfo); - var rsaPrivateKey = PKI.privateKeyToAsn1(privateKey); - var pki = PKI.wrapRsaPrivateKey(rsaPrivateKey); - ASSERT.equal(PKI.privateKeyInfoToPem(pki), _pem.privateKeyInfo); - }); - - (function() { - var algorithms = ['aes128', 'aes192', 'aes256', '3des', 'des']; - for(var i = 0; i < algorithms.length; ++i) { - var algorithm = algorithms[i]; - it('should PKCS#8 encrypt and decrypt private key with ' + algorithm, function() { - var privateKey = PKI.privateKeyFromPem(_pem.privateKey); - var encryptedPem = PKI.encryptRsaPrivateKey( - privateKey, 'password', {algorithm: algorithm}); - privateKey = PKI.decryptRsaPrivateKey(encryptedPem, 'password'); - ASSERT.equal(PKI.privateKeyToPem(privateKey), _pem.privateKey); - }); - } - })(); - - (function() { - var algorithms = ['aes128', 'aes192', 'aes256', '3des', 'des']; - for(var i = 0; i < algorithms.length; ++i) { - var algorithm = algorithms[i]; - it('should legacy (OpenSSL style) encrypt and decrypt private key with ' + algorithm, function() { - var privateKey = PKI.privateKeyFromPem(_pem.privateKey); - var encryptedPem = PKI.encryptRsaPrivateKey( - privateKey, 'password', {algorithm: algorithm, legacy: true}); - privateKey = PKI.decryptRsaPrivateKey(encryptedPem, 'password'); - ASSERT.equal(PKI.privateKeyToPem(privateKey), _pem.privateKey); - }); - } - })(); - - it('should verify signature', function() { - var publicKey = PKI.publicKeyFromPem(_pem.publicKey); - var md = MD.sha1.create(); - md.update('0123456789abcdef'); - var signature = UTIL.hexToBytes(_signature); - ASSERT.ok(publicKey.verify(md.digest().getBytes(), signature)); - }); - - it('should sign and verify', function() { - var privateKey = PKI.privateKeyFromPem(_pem.privateKey); - var publicKey = PKI.publicKeyFromPem(_pem.publicKey); - var md = MD.sha1.create(); - md.update('0123456789abcdef'); - var signature = privateKey.sign(md); - ASSERT.ok(publicKey.verify(md.digest().getBytes(), signature)); - }); - - it('should generate missing CRT parameters, sign, and verify', function() { - var privateKey = PKI.privateKeyFromPem(_pem.privateKey); - - // remove dQ, dP, and qInv - privateKey = RSA.setPrivateKey( - privateKey.n, privateKey.e, privateKey.d, - privateKey.p, privateKey.q); - - var publicKey = PKI.publicKeyFromPem(_pem.publicKey); - var md = MD.sha1.create(); - md.update('0123456789abcdef'); - var signature = privateKey.sign(md); - ASSERT.ok(publicKey.verify(md.digest().getBytes(), signature)); - }); - - it('should sign and verify with a private key containing only e, n, and d parameters', function() { - var privateKey = PKI.privateKeyFromPem(_pem.privateKey); - - // remove all CRT parameters from private key, so that it consists - // only of e, n and d (which make a perfectly valid private key, but its - // operations are slower) - privateKey = RSA.setPrivateKey( - privateKey.n, privateKey.e, privateKey.d); - - var publicKey = PKI.publicKeyFromPem(_pem.publicKey); - var md = MD.sha1.create(); - md.update('0123456789abcdef'); - var signature = privateKey.sign(md); - ASSERT.ok(publicKey.verify(md.digest().getBytes(), signature)); - }); - - (function() { - var tests = [{ - keySize: 1024, - privateKeyPem: '-----BEGIN RSA PRIVATE KEY-----\r\n' + - 'MIICWwIBAAKBgQDCjvkkLWNTeYXqEsqGiVCW/pDt3/qAodNMHcU9gOU2rxeWwiRu\r\n' + - 'OhhLqmMxXHLi0oP5Xmg0m7zdOiLMEyzzyRzdp21aqp3k5qtuSDkZcf1prsp1jpYm\r\n' + - '6z9EGpaSHb64BCuUsQGmUPKutd5RERKHGZXtiRuvvIyue7ETq6VjXrOUHQIDAQAB\r\n' + - 'AoGAOKeBjTNaVRhyEnNeXkbmHNIMSfiK7aIx8VxJ71r1ZDMgX1oxWZe5M29uaxVM\r\n' + - 'rxg2Lgt7tLYVDSa8s0hyMptBuBdy3TJUWruDx85uwCrWnMerCt/iKVBS22fv5vm0\r\n' + - 'LEq/4gjgIVTZwgqbVxGsBlKcY2VzxAfYqYzU8EOZBeNhZdECQQDy+PJAPcUN2xOs\r\n' + - '6qy66S91x6y3vMjs900OeX4+bgT4VSVKmLpqRTPizzcL07tT4+Y+pAAOX6VstZvZ\r\n' + - '6iFDL5rPAkEAzP1+gaRczboKoJWKJt0uEMUmztcY9NXJFDmjVLqzKwKjcAoGgIal\r\n' + - 'h+uBFT9VJ16QajC7KxTRLlarzmMvspItUwJAeUMNhEpPwm6ID1DADDi82wdgiALM\r\n' + - 'NJfn+UVhYD8Ac//qsKQwxUDseFH6owh1AZVIIBMxg/rwUKUCt2tGVoW3uQJAIt6M\r\n' + - 'Aml/D8+xtxc45NuC1n9y1oRoTl1/Ut1rFyKbD5nnS0upR3uf9LruvjqDtaq0Thvz\r\n' + - '+qQT4RoFJ5pfprSO2QJAdMkfNWRqECfAhZyQuUrapeWU3eQ0wjvktIynCIwiBDd2\r\n' + - 'MfjmVXzBJhMk6dtINt+vBEITVQEOdtyTgDt0y3n2Lw==\r\n' + - '-----END RSA PRIVATE KEY-----\r\n', - publicKeyPem: '-----BEGIN PUBLIC KEY-----\r\n' + - 'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDCjvkkLWNTeYXqEsqGiVCW/pDt\r\n' + - '3/qAodNMHcU9gOU2rxeWwiRuOhhLqmMxXHLi0oP5Xmg0m7zdOiLMEyzzyRzdp21a\r\n' + - 'qp3k5qtuSDkZcf1prsp1jpYm6z9EGpaSHb64BCuUsQGmUPKutd5RERKHGZXtiRuv\r\n' + - 'vIyue7ETq6VjXrOUHQIDAQAB\r\n' + - '-----END PUBLIC KEY-----\r\n', - encrypted: 'jsej3OoacmJ1VjWrlw68F+drnQORAuKAqVu6RMbz1xSXjzA355vctrJZXolRU0mvzuu/6VuNynkKGGyRJ6DHt85CvwTMChw4tOMV4Dy6bgnUt3j+DZA2sWTwFhOlpzvNQMK70QpuqrXtOZmAO59EwoDeJkW/iH6t4YzNOVYo9Jg=', - signature: 'GT0/3EV2zrXxPd1ydijJq3R7lkI4c0GtcprgpG04dSECv/xyXtikuzivxv7XzUdHpu6QiYmM0xE4D4i7LK3Mzy+f7aB4o/dg8XXO3htLiBzVI+ZJCRh06RdYctPtclAWmyZikZ8Etw3NnA/ldKuG4jApbwRb21UFm5gYLrJ4SP4=', - signaturePss: 'F4xffaANDBjhFxeSJx8ANuBbdhaWZjUHRQh4ueYQMPPCaR2mpwdqxE04sbgNgIiZzBuLIAI4HpTMMoDk3Rruhjefx3+9UhzTxgB0hRI+KzRChRs+ToltWWDZdYzt9T8hfTlELeqT4V8HgjDuteO/IAvIVlRIBwMNv53Iebu1FY4=', - signatureWithAbcSalt: 'GYA/Zp8G+jqG2Fu7Um+XP7Cr/yaVdzJN8lyt57Lw6gFflia2CPbOVMLyqLzD7fKoE8UD0Rc6DF8k04xhEu60sudw2nxGHeDvpL4M9du0uYra/WSr9kv7xNjAW62NyNerDngHD2J7O8gQ07TZiTXkrfS724vQab5xZL/+FhvisMY=', - signatureWithCustomPrng: 'LzWcUpUYK+URDp72hJbz1GVEp0rG0LHjd+Pdh2w5rfQFbUThbmXDl3X6DUT5UZr5RjUSHtc2usvH+w49XskyIJJO929sUk9EkMJMK/6QAnYYEp5BA+48pdGNNMZyjIbhyl9Y4lInzFPX8XYMM8o+tdSK+hj+dW5OPdnwWbDtR7U=' - }, { - keySize: 1025, - privateKeyPem: '-----BEGIN RSA PRIVATE KEY-----\r\n' + - 'MIICXgIBAAKBgQGIkej4PDlAigUh5fbbHp1WXuTHhOdQfAke+LoH0TM4uzn0QmgK\r\n' + - 'SJqxzB1COJ5o0DwZw/NR+CNy7NUrly+vmh2YPwsaqN+AsYBF9qsF93oN8/TBtaL/\r\n' + - 'GRoRGpDcCglkj1kZnDaWR79NsG8mC0TrvQCkcCLOP0c2Ux1hRbntOetGXwIDAQAB\r\n' + - 'AoGBAIaJWsoX+ZcAthmT8jHOICXFh6pJBe0zVPzkSPz82Q0MPSRUzcsYbsuYJD7Z\r\n' + - 'oJBTLQW3feANpjhwqe2ydok7y//ONm3Th53Bcu8jLfoatg4KYxNFIwXEO10mPOld\r\n' + - 'VuDIGrBkTABe6q2P5PeUKGCKLT6i/u/2OTXTrQiJbQ0gU8thAkEBjqcFivWMXo34\r\n' + - 'Cb9/EgfWCCtv9edRMexgvcFMysRsbHJHDK9JjRLobZltwtAv3cY7F3a/Cu1afg+g\r\n' + - 'jAzm5E3gowJBAPwYFHTLzaZToxFKNQztWrPsXF6YfqHpPUUIpT4UzL6DhGG0M00U\r\n' + - 'qMyhkYRRqmGOSrSovjg2hjM2643MUUWxUxUCQDPkk/khu5L3YglKzyy2rmrD1MAq\r\n' + - 'y0v3XCR3TBq89Ows+AizrJxbkLvrk/kfBowU6M5GG9o9SWFNgXWZnFittocCQQDT\r\n' + - 'e1P1419DUFi1UX6NuLTlybx3sxBQvf0jY6xUF1jn3ib5XBXJbTJqcIRF78iyjI9J\r\n' + - 'XWIugDc20bTsQOJRSAA9AkEBU8kpueHBaiXTikqqlK9wvc2Lp476hgyKVmVyBGye\r\n' + - '9TLTWkTCzDPtManLy47YtXkXnmyazS+DlKFU61XAGEnZfg==\r\n' + - '-----END RSA PRIVATE KEY-----\r\n', - publicKeyPem: '-----BEGIN PUBLIC KEY-----\r\n' + - 'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQGIkej4PDlAigUh5fbbHp1WXuTH\r\n' + - 'hOdQfAke+LoH0TM4uzn0QmgKSJqxzB1COJ5o0DwZw/NR+CNy7NUrly+vmh2YPwsa\r\n' + - 'qN+AsYBF9qsF93oN8/TBtaL/GRoRGpDcCglkj1kZnDaWR79NsG8mC0TrvQCkcCLO\r\n' + - 'P0c2Ux1hRbntOetGXwIDAQAB\r\n' + - '-----END PUBLIC KEY-----\r\n', - encrypted: 'AOVeCUN8BOVkZvt4mxyNn/yCYE1MZ40A3e/osh6EvCBcJ09hyYbx7bzKSrdkhRnDyW0pGtgP352CollasllQZ9HlfI2Wy9zKM0aYZZn8OHBA+60Tc3xHHDGznLZqggUKuhoNpj+faVZ1uzb285eTpQQa+4mLUue2svJD4ViM8+ng', - signature: 'AFSx0axDYXlF2rO3ofgUhYSI8ZlIWtJUUZ62PhgdBp9O5zFqMX3DXoiov1e7NenSOz1khvTSMctFWzKP3GU3F0yewe+Yd3UAZE0dM8vAxigSSfAchUkBDmp9OFuszUie63zwWwpG+gXtvyfueZs1RniBvW1ZmXJvS+HFgX4ouzwd', - signaturePss: 'AQvBdhAXDpu+7RpcybMgwuTUk6w+qa08Lcq3G1xHY4kC7ZUzauZd/Jn9e0ePKApDqs7eDNAOV+dQkU2wiH/uBg6VGelzb0hFwcpSLyBW92Vw0q3GlzY7myWn8qnNzasrt110zFflWQa1GiuzH/C8f+Z82/MzlWDxloJIYbq2PRC8', - signatureWithAbcSalt: 'AW4bKnG/0TGvAZgqX5Dk+fXpUNgX7INFelE46d3m+spaMTG5XalY0xP1sxWfaE/+Zl3FmZcfTNtfOCo0eNRO1h1+GZZfp32ZQZmZvkdUG+dUQp318LNzgygrVf/5iIX+QKV5/soSDuAHBzS7yDfMgzJfnXNpFE/zPLOgZIoOIuLq', - signatureWithCustomPrng: 'AVxfCyGC/7Y3kz//eYFEuWQijjR7eR05AM36CwDlLsVkDRtXoeVzz2yTFBdP+i+QgQ73C/I3lLtvXTwfleorvIX9YncVBeGDQXssmULxzqsM3izaLfJXCRAGx9ErL1Az10+fAqPZpq954OVSDqrR/61Q7CsMY7CiQO3nfIIaxgVL' - }, { - keySize: 1031, - privateKeyPem: '-----BEGIN RSA PRIVATE KEY-----\r\n' + - 'MIICXwIBAAKBgWyeKqA2oA4klYrKT9hjjutYQksJNN0cxwaQwIm9AYiLxOsYtT/C\r\n' + - 'ovJx5Oy1EvkbYQbfvYsGISUx9bW8yasZkTHR55IbW3+UptvQjTDtdxBQTgQOpsAh\r\n' + - 'BJtZYY3OmyH9Sj3F3oB//oyriNoj0QYyfsvlO8UsMmLzpnf6qfZBDHA/9QIDAQAB\r\n' + - 'AoGBBj/3ne5muUmbnTfU7lOUNrCGaADonMx6G0ObAJHyk6PPOePbEgcmDyNEk+Y7\r\n' + - 'aEAODjIzmttIbvZ39/Qb+o9nDmCSZC9VxiYPP+rjOzPglCDT5ks2Xcjwzd3If6Ya\r\n' + - 'Uw6P31Y760OCYeTb4Ib+8zz5q51CkjkdX5Hq/Yu+lZn0Vx7BAkENo83VfL+bwxTm\r\n' + - 'V7vR6gXqTD5IuuIGHL3uTmMNNURAP6FQDHu//duipys83iMChcOeXtboE16qYrO0\r\n' + - '9KC0cqL4JQJBB/aYo/auVUGZA6f50YBp0b2slGMk9TBQG0iQefuuSyH4kzKnt2e3\r\n' + - 'Q40SBmprcM+DfttWJ11bouec++goXjz+95ECQQyiTWYRxulgKVuyqCYnvpLnTEnR\r\n' + - '0MoYlVTHBriVPkLErYaYCYgse+SNM1+N4p/Thv6KmkUcq/Lmuc5DSRfbl1iBAkEE\r\n' + - '7GKtJQvd7EO1bfpXnARQx+tWhwHHkgpFBBVHReMZ0rQEFhJ5o2c8HZEiZFNvGO2c\r\n' + - '1fErP14zlu2JFZ03vpCI8QJBCQz9HL28VNjafSAF2mon/SNjKablRjoGGKSoSdyA\r\n' + - 'DHDZ/LeRsTp2dg8+bSiG1R+vPqw0f/BT+ux295Sy9ocGEM8=\r\n' + - '-----END RSA PRIVATE KEY-----\r\n', - publicKeyPem: '-----BEGIN PUBLIC KEY-----\r\n' + - 'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgWyeKqA2oA4klYrKT9hjjutYQksJ\r\n' + - 'NN0cxwaQwIm9AYiLxOsYtT/CovJx5Oy1EvkbYQbfvYsGISUx9bW8yasZkTHR55Ib\r\n' + - 'W3+UptvQjTDtdxBQTgQOpsAhBJtZYY3OmyH9Sj3F3oB//oyriNoj0QYyfsvlO8Us\r\n' + - 'MmLzpnf6qfZBDHA/9QIDAQAB\r\n' + - '-----END PUBLIC KEY-----\r\n', - encrypted: 'ShSS4/fEAkuS6XiQakhOpWp82IXaaCaDNtsndU4uokvriqgCGZyqc+IkIk3eVmZ8bn4vVIRR43ydFuvGgsptVjizOdLGZudph3TJ1clcYEMcCXk4z5HaEu0bx5SW9jmzHhE/z+WV8PB48q7y7C2qtmPmfttG2NMsNLBvkiaDopRO', - signature: 'Z3vYgRdezrWmdA3NC1Uz2CcHRTcE+/C2idGZA1FjUGqFztAHQ31k0QW/F5zuJdKvg8LQU45S3KxW+OQpbGPL98QbzJLhml88mFGe6OinLXJbi7UQWrtXwamc2jMdiXwovSLbXaXy6PX2QW089iC8XuAZftVi3T/IKV0458FQQprg', - signaturePss: 'R6QsK6b3QinIPZPamm/dP0Zndqti1TzAkFTRSZJaRSa1u2zuvZC5QHF4flDjEtHosWeDyxrBE7PHGQZ0b1bHv9qgHGsJCMwaQPj3AWj9fjYmx7b86KM2vHr8q/vqDaa9pTvVRSSwvD6fwoZPc9twQEfdjdDBAiy23yLDzk/zZiwM', - signatureWithAbcSalt: 'Ep9qx4/FPNcWTixWhvL2IAyJR69o5I4MIJi3cMAhDmpuTvAaL/ThQwFWkBPPOPT4Jbumnu6ELjPNjo72wa00e5k64qnZgy1pauBPMlXRlKehRc9UJZ6+xot642z8Qs+rt89OgbYTsvlyr8lzXooUHz/lPpfawYCqd7maRMs8YlYM', - signatureWithCustomPrng: 'NHAwyn2MdM5ez/WbDNbu2A2JNS+cRiWk/zBoh0lg3aq/RsBS0nrYr4AGiC5jt6KWVcN4AIVOomYtX2k+MhLoemN2t2rDj/+LXOeU7kgCAz0q0ED2NFQz7919JU+PuYXMy03qTMfl5jbvStdi/00eQHjJKGEH+xAgrDcED2lrhtCu' - }, { - keySize: 1032, - privateKeyPem: '-----BEGIN RSA PRIVATE KEY-----\r\n' + - 'MIICYQIBAAKBggDPhzn5I3GecxWt5DKbP+VhM2AFNSOL0+VbYEOR1hnlZdLbxGK4\r\n' + - 'cPQzMr2qT6dyttJcsgWr3xKobPkz7vsTZzQATSiekm5Js5dGpaj5lrq/x2+WTZvn\r\n' + - '55x9M5Y5dlpusDMKcC3KaIX/axc+MbvPFzo6Eli7JLCWdBg01eKo30knil0CAwEA\r\n' + - 'AQKBggCNl/sjFF7SOD1jbt5kdL0hi7cI9o+xOLs1lEGmAEmc7dNnZN/ibhb/06/6\r\n' + - 'wuxB5aEz47bg5IvLZMbG+1hNjc26D0J6Y3Ltwrg8f4ZMdDrh4v0DZ8hy/HbEpMrJ\r\n' + - 'Td5dk3mtw9FLow10MB5udPLTDKhfDpTcWiObKm2STtFeBk3xeEECQQ6Cx6bZxQJ1\r\n' + - 'zCxflV5Xi8BgAQaUKMqygugte+HpOLflL0j1fuZ0rPosUyDOEFkTzOsPxBYYOU8i\r\n' + - 'Gzan1GvW3WwRAkEOTTRt849wpgC9xx2pF0IrYEVmv5gEMy3IiRfCNgEoBwpTWVf4\r\n' + - 'QFpN3V/9GFz0WQEEYo6OTmkNcC3Of5zbHhu1jQJBBGxXAYQ2KnbP4uLL/DMBdYWO\r\n' + - 'Knw1JvxdLPrYXVejI2MoE7xJj2QXajbirAhEMXL4rtpicj22EmoaE4H7HVgkrJEC\r\n' + - 'QQq2V5w4AGwvW4TLHXNnYX/eB33z6ujScOuxjGNDUlBqHZja5iKkCUAjnl+UnSPF\r\n' + - 'exaOwBrlrpiLOzRer94MylKNAkEBmI58bqfkI5OCGDArAsJ0Ih58V0l1UW35C1SX\r\n' + - '4yDoXSM5A/xQu2BJbXO4jPe3PnDvCVCEyKpbCK6bWbe26Y7zuw==\r\n' + - '-----END RSA PRIVATE KEY-----\r\n', - publicKeyPem: '-----BEGIN PUBLIC KEY-----\r\n' + - 'MIGgMA0GCSqGSIb3DQEBAQUAA4GOADCBigKBggDPhzn5I3GecxWt5DKbP+VhM2AF\r\n' + - 'NSOL0+VbYEOR1hnlZdLbxGK4cPQzMr2qT6dyttJcsgWr3xKobPkz7vsTZzQATSie\r\n' + - 'km5Js5dGpaj5lrq/x2+WTZvn55x9M5Y5dlpusDMKcC3KaIX/axc+MbvPFzo6Eli7\r\n' + - 'JLCWdBg01eKo30knil0CAwEAAQ==\r\n' + - '-----END PUBLIC KEY-----\r\n', - encrypted: 'pKTbv+xgXPDc+wbjsANFu1/WTcmy4aZFKXKnxddHbU5S0Dpdj2OqCACiBwu1oENPMgPAJ27XRbFtKG+eS8tX47mKP2Fo0Bi+BPFtzuQ1bj3zUzTwzjemT+PU+a4Tho/eKjPhm6xrwGAoQH2VEDEpvcYf+SRmGFJpJ/zPUrSxgffj', - signature: 'R9WBFprCfcIC4zY9SmBpEM0E+cr5j4gMn3Ido5mktoR9VBoJqC6eR6lubIPvZZUz9e4yUSYX0squ56Q9Y0yZFQjTHgsrlmhB2YW8kpv4h8P32Oz2TLcMJK9R2tIh9vvyxwBkd/Ml1qG60GnOFUFzxUad9VIlzaF1PFR6EfnkgBUW', - signaturePss: 'v9UBd4XzBxSRz8yhWKjUkFpBX4Fr2G+ImjqbePL4sAZvYw1tWL+aUQpzG8eOyMxxE703VDh9nIZULYI/uIb9HYHQoGYQ3WoUaWqtZg1x8pZP+Ad7ilUWk5ImRl57fTznNQiVdwlkS5Wgheh1yJCES570a4eujiK9OyB0ba4rKIcM', - signatureWithAbcSalt: 'HCm0FI1jE6wQgwwi0ZwPTkGjssxAPtRh6tWXhNd2J2IoJYj9oQMMjCEElnvQFBa/l00sIsw2YV1tKyoTABaSTGV4vlJcDF+K0g/wiAf30TRUZo72DZKDNdyffDlH0wBDkNVW+F6uqdciJqBC6zz+unNh7x+FRwYaY8xhudIPXdyP', - signatureWithCustomPrng: 'AGyN8xu+0yfCR1tyB9mCXcTGb2vdLnsX9ro2Qy5KV6Hw5YMVNltAt65dKR4Y8pfu6D4WUyyJRUtJ8td2ZHYzIVtWY6bG1xFt5rkjTVg4v1tzQgUQq8AHvRE2qLzwDXhazJ1e6Id2Nuxb1uInFyRC6/gLmiPga1WRDEVvFenuIA48' - }]; - for(var i = 0; i < tests.length; ++i) { - createTests(tests[i]); - } - - it('should ensure maximum message length for a 1024-bit key is exceeded', function() { - /* For PKCS#1 v1.5, the message must be padded with at least eight bytes, - two zero bytes and one byte telling what the block type is. This is 11 - extra bytes are added to the message. The test uses a message of 118 - bytes.Together with the 11 extra bytes the encryption block needs to be - at least 129 bytes long. This requires a key of 1025-bits. */ - var key = PKI.publicKeyFromPem(tests[0].publicKeyPem); - var message = UTIL.createBuffer().fillWithByte(0, 118); - ASSERT.throws(function() { - key.encrypt(message.getBytes()); - }); - }); - - it('should ensure maximum message length for a 1025-bit key is not exceeded', function() { - var key = PKI.publicKeyFromPem(tests[1].publicKeyPem); - var message = UTIL.createBuffer().fillWithByte(0, 118); - ASSERT.doesNotThrow(function() { - key.encrypt(message.getBytes()); - }); - }); - - /** - * Creates RSA encryption & decryption tests. - * - * Uses different key sizes (1024, 1025, 1031, 1032). The test functions are - * generated from "templates" below, one for each key size to provide sensible - * output. - * - * Key material in was created with OpenSSL using these commands: - * - * openssl genrsa -out rsa_1024_private.pem 1024 - * openssl rsa -in rsa_1024_private.pem -out rsa_1024_public.pem \ - * -outform PEM -pubout - * echo 'too many secrets' | openssl rsautl -encrypt \ - * -inkey rsa_1024_public.pem -pubin -out rsa_1024_encrypted.bin - * - * echo -n 'just testing' | openssl dgst -sha1 -binary > tosign.sha1 - * openssl pkeyutl -sign -in tosign.sha1 -inkey rsa_1024_private.pem \ - * -out rsa_1024_sig.bin -pkeyopt digest:sha1 - * openssl pkeyutl -sign -in tosign.sha1 -inkey rsa_1024_private.pem \ - * -out rsa_1024_sigpss.bin -pkeyopt digest:sha1 \ - * -pkeyopt rsa_padding_mode:pss -pkeyopt rsa_pss_saltlen:20 - * - * OpenSSL commands for signature verification: - * - * openssl pkeyutl -verify -in tosign.sha1 -sigfile rsa_1024_sig.bin \ - * -pubin -inkey rsa_1024_public.pem -pkeyopt digest:sha1 - * openssl pkeyutl -verify -in tosign.sha1 -sigfile rsa_1025_sigpss.bin \ - * -pubin -inkey rsa_1025_public.pem -pkeyopt digest:sha1 \ - * -pkeyopt rsa_padding_mode:pss -pkeyopt rsa_pss_saltlen:20 - */ - function createTests(params) { - var keySize = params.keySize; - - it('should rsa encrypt using a ' + keySize + '-bit key', function() { - var message = "it need's to be about 20% cooler"; // it need's better grammar too - - /* First step, do public key encryption */ - var key = PKI.publicKeyFromPem(params.publicKeyPem); - var data = key.encrypt(message); - - /* Second step, use private key decryption to verify successful - encryption. The encrypted message differs every time, since it is - padded with random data. Therefore just rely on the decryption - routine to work, which is tested seperately against an externally - provided encrypted message. */ - key = PKI.privateKeyFromPem(params.privateKeyPem); - ASSERT.equal(key.decrypt(data), message); - }); - - it('should rsa decrypt using a ' + keySize + '-bit key', function() { - var data = UTIL.decode64(params.encrypted); - var key = PKI.privateKeyFromPem(params.privateKeyPem); - ASSERT.equal(key.decrypt(data), 'too many secrets\n'); - }); - - it('should rsa sign using a ' + keySize + '-bit key and PKCS#1 v1.5 padding', function() { - var key = PKI.privateKeyFromPem(params.privateKeyPem); - - var md = MD.sha1.create(); - md.start(); - md.update('just testing'); - - var signature = UTIL.decode64(params.signature); - ASSERT.equal(key.sign(md), signature); - }); - - it('should verify an rsa signature using a ' + keySize + '-bit key and PKCS#1 v1.5 padding', function() { - var signature = UTIL.decode64(params.signature); - var key = PKI.publicKeyFromPem(params.publicKeyPem); - - var md = MD.sha1.create(); - md.start(); - md.update('just testing'); - - ASSERT.equal(key.verify(md.digest().getBytes(), signature), true); - }); - - /* Note: signatures are *not* deterministic (the point of RSASSA-PSS), - so they can't be compared easily -- instead they are just verified - using the verify() function which is tested against OpenSSL-generated - signatures. */ - it('should rsa sign using a ' + keySize + '-bit key and PSS padding', function() { - var privateKey = PKI.privateKeyFromPem(params.privateKeyPem); - var publicKey = PKI.publicKeyFromPem(params.publicKeyPem); - - var md = MD.sha1.create(); - md.start(); - md.update('just testing'); - - // create signature - var pss = PSS.create( - MD.sha1.create(), MGF.mgf1.create(MD.sha1.create()), 20); - var signature = privateKey.sign(md, pss); - - // verify signature - md.start(); - md.update('just testing'); - ASSERT.equal( - publicKey.verify(md.digest().getBytes(), signature, pss), true); - }); - - it('should verify an rsa signature using a ' + keySize + '-bit key and PSS padding', function() { - var signature = UTIL.decode64(params.signaturePss); - var key = PKI.publicKeyFromPem(params.publicKeyPem); - - var md = MD.sha1.create(); - md.start(); - md.update('just testing'); - - var pss = PSS.create( - MD.sha1.create(), MGF.mgf1.create(MD.sha1.create()), 20); - ASSERT.equal( - key.verify(md.digest().getBytes(), signature, pss), true); - }); - - it('should rsa sign using a ' + keySize + '-bit key and PSS padding using pss named-param API', function() { - var privateKey = PKI.privateKeyFromPem(params.privateKeyPem); - var publicKey = PKI.publicKeyFromPem(params.publicKeyPem); - - var md = MD.sha1.create(); - md.start(); - md.update('just testing'); - - // create signature - var pss = PSS.create({ - md: MD.sha1.create(), - mgf: MGF.mgf1.create(MD.sha1.create()), - saltLength: 20 - }); - var signature = privateKey.sign(md, pss); - - // verify signature - md.start(); - md.update('just testing'); - ASSERT.equal( - publicKey.verify(md.digest().getBytes(), signature, pss), true); - }); - - it('should verify an rsa signature using a ' + keySize + '-bit key and PSS padding using pss named-param API', function() { - var signature = UTIL.decode64(params.signaturePss); - var key = PKI.publicKeyFromPem(params.publicKeyPem); - - var md = MD.sha1.create(); - md.start(); - md.update('just testing'); - - var pss = PSS.create({ - md: MD.sha1.create(), - mgf: MGF.mgf1.create(MD.sha1.create()), - saltLength: 20 - }); - ASSERT.equal( - key.verify(md.digest().getBytes(), signature, pss), true); - }); - - it('should rsa sign using a ' + keySize + '-bit key and PSS padding using salt "abc"', function() { - var privateKey = PKI.privateKeyFromPem(params.privateKeyPem); - - var md = MD.sha1.create(); - md.start(); - md.update('just testing'); - - // create signature - var pss = PSS.create({ - md: MD.sha1.create(), - mgf: MGF.mgf1.create(MD.sha1.create()), - salt: UTIL.createBuffer('abc') - }); - var signature = privateKey.sign(md, pss); - var b64 = UTIL.encode64(signature); - ASSERT.equal(b64, params.signatureWithAbcSalt); - }); - - it('should verify an rsa signature using a ' + keySize + '-bit key and PSS padding using salt "abc"', function() { - var signature = UTIL.decode64(params.signatureWithAbcSalt); - var key = PKI.publicKeyFromPem(params.publicKeyPem); - - var md = MD.sha1.create(); - md.start(); - md.update('just testing'); - - var pss = PSS.create({ - md: MD.sha1.create(), - mgf: MGF.mgf1.create(MD.sha1.create()), - saltLength: 3 - }); - ASSERT.equal( - key.verify(md.digest().getBytes(), signature, pss), true); - }); - - it('should rsa sign using a ' + keySize + '-bit key and PSS padding using custom PRNG', function() { - var prng = RANDOM.createInstance(); - prng.seedFileSync = function(needed) { - return UTIL.fillString('a', needed); - }; - var privateKey = PKI.privateKeyFromPem(params.privateKeyPem); - - var md = MD.sha1.create(); - md.start(); - md.update('just testing'); - - // create signature - var pss = PSS.create({ - md: MD.sha1.create(), - mgf: MGF.mgf1.create(MD.sha1.create()), - saltLength: 20, - prng: prng - }); - var signature = privateKey.sign(md, pss); - var b64 = UTIL.encode64(signature); - ASSERT.equal(b64, params.signatureWithCustomPrng); - }); - - it('should verify an rsa signature using a ' + keySize + '-bit key and PSS padding using custom PRNG', function() { - var prng = RANDOM.createInstance(); - prng.seedFileSync = function(needed) { - return UTIL.fillString('a', needed); - }; - var signature = UTIL.decode64(params.signatureWithCustomPrng); - var key = PKI.publicKeyFromPem(params.publicKeyPem); - - var md = MD.sha1.create(); - md.start(); - md.update('just testing'); - - var pss = PSS.create({ - md: MD.sha1.create(), - mgf: MGF.mgf1.create(MD.sha1.create()), - saltLength: 20, - prng: prng - }); - ASSERT.equal( - key.verify(md.digest().getBytes(), signature, pss), true); - }); - } - })(); - }); -} - -// check for AMD -if(typeof define === 'function') { - define([ - 'forge/pki', - 'forge/rsa', - 'forge/md', - 'forge/mgf', - 'forge/pss', - 'forge/random', - 'forge/util' - ], function(PKI, RSA, MD, MGF, PSS, RANDOM, UTIL) { - Tests( - // Global provided by test harness - ASSERT, - PKI(), - RSA(), - MD(), - MGF(), - PSS(), - RANDOM(), - UTIL() - ); - }); -} else if(typeof module === 'object' && module.exports) { - // assume NodeJS - Tests( - require('assert'), - require('../../js/pki')(), - require('../../js/rsa')(), - require('../../js/md')(), - require('../../js/mgf')(), - require('../../js/pss')(), - require('../../js/random')(), - require('../../js/util')()); -} - -})(); diff --git a/alarm/node_modules/node-forge/nodejs/test/sha1.js b/alarm/node_modules/node-forge/nodejs/test/sha1.js deleted file mode 100644 index 3ffd985..0000000 --- a/alarm/node_modules/node-forge/nodejs/test/sha1.js +++ /dev/null @@ -1,75 +0,0 @@ -(function() { - -function Tests(ASSERT, SHA1, UTIL) { - describe('sha1', function() { - it('should digest the empty string', function() { - var md = SHA1.create(); - ASSERT.equal( - md.digest().toHex(), 'da39a3ee5e6b4b0d3255bfef95601890afd80709'); - }); - - it('should digest "abc"', function() { - var md = SHA1.create(); - md.update('abc'); - ASSERT.equal( - md.digest().toHex(), 'a9993e364706816aba3e25717850c26c9cd0d89d'); - }); - - it('should digest "The quick brown fox jumps over the lazy dog"', function() { - var md = SHA1.create(); - md.update('The quick brown fox jumps over the lazy dog'); - ASSERT.equal( - md.digest().toHex(), '2fd4e1c67a2d28fced849ee1bb76e7391b93eb12'); - }); - - it('should digest "c\'\u00e8"', function() { - var md = SHA1.create(); - md.update("c\'\u00e8", 'utf8'); - ASSERT.equal( - md.digest().toHex(), '98c9a3f804daa73b68a5660d032499a447350c0d'); - }); - - it('should digest "THIS IS A MESSAGE"', function() { - var md = SHA1.create(); - md.start(); - md.update('THIS IS '); - md.update('A MESSAGE'); - // do twice to check continuing digest - ASSERT.equal( - md.digest().toHex(), '5f24f4d6499fd2d44df6c6e94be8b14a796c071d'); - ASSERT.equal( - md.digest().toHex(), '5f24f4d6499fd2d44df6c6e94be8b14a796c071d'); - }); - - it('should digest a long message', function() { - // Note: might be too slow on old browsers - var md = SHA1.create(); - md.update(UTIL.fillString('a', 1000000)); - ASSERT.equal( - md.digest().toHex(), '34aa973cd4c4daa4f61eeb2bdbad27316534016f'); - }); - }); -} - -// check for AMD -if(typeof define === 'function') { - define([ - 'forge/sha1', - 'forge/util' - ], function(SHA1, UTIL) { - Tests( - // Global provided by test harness - ASSERT, - SHA1(), - UTIL() - ); - }); -} else if(typeof module === 'object' && module.exports) { - // assume NodeJS - Tests( - require('assert'), - require('../../js/sha1')(), - require('../../js/util')()); -} - -})(); diff --git a/alarm/node_modules/node-forge/nodejs/test/sha256.js b/alarm/node_modules/node-forge/nodejs/test/sha256.js deleted file mode 100644 index 2d5eb8a..0000000 --- a/alarm/node_modules/node-forge/nodejs/test/sha256.js +++ /dev/null @@ -1,81 +0,0 @@ -(function() { - -function Tests(ASSERT, SHA256, UTIL) { - describe('sha256', function() { - it('should digest the empty string', function() { - var md = SHA256.create(); - ASSERT.equal( - md.digest().toHex(), - 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855'); - }); - - it('should digest "abc"', function() { - var md = SHA256.create(); - md.update('abc'); - ASSERT.equal( - md.digest().toHex(), - 'ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad'); - }); - - it('should digest "The quick brown fox jumps over the lazy dog"', function() { - var md = SHA256.create(); - md.update('The quick brown fox jumps over the lazy dog'); - ASSERT.equal( - md.digest().toHex(), - 'd7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592'); - }); - - it('should digest "c\'\u00e8"', function() { - var md = SHA256.create(); - md.update("c\'\u00e8", 'utf8'); - ASSERT.equal( - md.digest().toHex(), - '1aa15c717afffd312acce2217ce1c2e5dabca53c92165999132ec9ca5decdaca'); - }); - - it('should digest "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"', function() { - var md = SHA256.create(); - md.start(); - md.update('abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq'); - // do twice to check continuing digest - ASSERT.equal( - md.digest().toHex(), - '248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1'); - ASSERT.equal( - md.digest().toHex(), - '248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1'); - }); - - it('should digest a long message', function() { - // Note: might be too slow on old browsers - var md = SHA256.create(); - md.update(UTIL.fillString('a', 1000000)); - ASSERT.equal( - md.digest().toHex(), - 'cdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd0'); - }); - }); -} - -// check for AMD -if(typeof define === 'function') { - define([ - 'forge/sha256', - 'forge/util' - ], function(SHA256, UTIL) { - Tests( - // Global provided by test harness - ASSERT, - SHA256(), - UTIL() - ); - }); -} else if(typeof module === 'object' && module.exports) { - // assume NodeJS - Tests( - require('assert'), - require('../../js/sha256')(), - require('../../js/util')()); -} - -})(); diff --git a/alarm/node_modules/node-forge/nodejs/test/sha512.js b/alarm/node_modules/node-forge/nodejs/test/sha512.js deleted file mode 100644 index 3cbc4dc..0000000 --- a/alarm/node_modules/node-forge/nodejs/test/sha512.js +++ /dev/null @@ -1,174 +0,0 @@ -(function() { - -function Tests(ASSERT, SHA512, UTIL) { - describe('sha512', function() { - it('should digest the empty string', function() { - var md = SHA512.create(); - ASSERT.equal( - md.digest().toHex(), - 'cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e'); - }); - - it('should digest "abc"', function() { - var md = SHA512.create(); - md.update('abc'); - ASSERT.equal( - md.digest().toHex(), - 'ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f'); - }); - - it('should digest "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"', function() { - var md = SHA512.create(); - md.update('abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu'); - ASSERT.equal( - md.digest().toHex(), - '8e959b75dae313da8cf4f72814fc143f8f7779c6eb9f7fa17299aeadb6889018501d289e4900f7e4331b99dec4b5433ac7d329eeb6dd26545e96e55b874be909'); - }); - - it('should digest "The quick brown fox jumps over the lazy dog"', function() { - var md = SHA512.create(); - md.update('The quick brown fox jumps over the lazy dog'); - ASSERT.equal( - md.digest().toHex(), - '07e547d9586f6a73f73fbac0435ed76951218fb7d0c8d788a309d785436bbb642e93a252a954f23912547d1e8a3b5ed6e1bfd7097821233fa0538f3db854fee6'); - }); - - it('should digest "c\'\u00e8"', function() { - var md = SHA512.create(); - md.update("c\'\u00e8", 'utf8'); - ASSERT.equal( - md.digest().toHex(), - '9afdc0390dd91e81c63f858d1c6fcd9f949f3fc89dbdaed9e4211505bad63d8e8787797e2e9ea651285eb6954e51c4f0299837c3108cb40f1420bca1d237355c'); - }); - - it('should digest "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"', function() { - var md = SHA512.create(); - md.start(); - md.update('abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq'); - // do twice to check continuing digest - ASSERT.equal( - md.digest().toHex(), - '204a8fc6dda82f0a0ced7beb8e08a41657c16ef468b228a8279be331a703c33596fd15c13b1b07f9aa1d3bea57789ca031ad85c7a71dd70354ec631238ca3445'); - ASSERT.equal( - md.digest().toHex(), - '204a8fc6dda82f0a0ced7beb8e08a41657c16ef468b228a8279be331a703c33596fd15c13b1b07f9aa1d3bea57789ca031ad85c7a71dd70354ec631238ca3445'); - }); - }); - - SHA384 = SHA512.sha384; - - describe('sha384', function() { - it('should digest the empty string', function() { - var md = SHA384.create(); - ASSERT.equal( - md.digest().toHex(), - '38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b'); - }); - - it('should digest "abc"', function() { - var md = SHA384.create(); - md.update('abc'); - ASSERT.equal( - md.digest().toHex(), - 'cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7'); - }); - - it('should digest "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"', function() { - var md = SHA384.create(); - md.update('abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu'); - ASSERT.equal( - md.digest().toHex(), - '09330c33f71147e83d192fc782cd1b4753111b173b3b05d22fa08086e3b0f712fcc7c71a557e2db966c3e9fa91746039'); - }); - - it('should digest "The quick brown fox jumps over the lazy dog"', function() { - var md = SHA384.create(); - md.update('The quick brown fox jumps over the lazy dog'); - ASSERT.equal( - md.digest().toHex(), - 'ca737f1014a48f4c0b6dd43cb177b0afd9e5169367544c494011e3317dbf9a509cb1e5dc1e85a941bbee3d7f2afbc9b1'); - }); - - it('should digest "c\'\u00e8"', function() { - var md = SHA384.create(); - md.update("c\'\u00e8", 'utf8'); - ASSERT.equal( - md.digest().toHex(), - '382ec8a92d50abf57f7d0f934ff3969d6d354d30c96f1616678a920677867aba49521d2d535c0f285a3c2961c2034ea3'); - }); - - it('should digest "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"', function() { - var md = SHA384.create(); - md.start(); - md.update('abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq'); - // do twice to check continuing digest - ASSERT.equal( - md.digest().toHex(), - '3391fdddfc8dc7393707a65b1b4709397cf8b1d162af05abfe8f450de5f36bc6b0455a8520bc4e6f5fe95b1fe3c8452b'); - ASSERT.equal( - md.digest().toHex(), - '3391fdddfc8dc7393707a65b1b4709397cf8b1d162af05abfe8f450de5f36bc6b0455a8520bc4e6f5fe95b1fe3c8452b'); - }); - }); - - SHA256 = SHA512.sha256; - - describe('sha512/256', function() { - it('should digest the empty string', function() { - var md = SHA256.create(); - ASSERT.equal( - md.digest().toHex(), - 'c672b8d1ef56ed28ab87c3622c5114069bdd3ad7b8f9737498d0c01ecef0967a'); - }); - - it('should digest "The quick brown fox jumps over the lazy dog"', function() { - var md = SHA256.create(); - md.update('The quick brown fox jumps over the lazy dog'); - ASSERT.equal( - md.digest().toHex(), - 'dd9d67b371519c339ed8dbd25af90e976a1eeefd4ad3d889005e532fc5bef04d'); - }); - }); - - SHA224 = SHA512.sha224; - - describe('sha512/224', function() { - it('should digest the empty string', function() { - var md = SHA224.create(); - ASSERT.equal( - md.digest().toHex(), - '6ed0dd02806fa89e25de060c19d3ac86cabb87d6a0ddd05c333b84f4'); - }); - - it('should digest "The quick brown fox jumps over the lazy dog"', function() { - var md = SHA224.create(); - md.update('The quick brown fox jumps over the lazy dog'); - ASSERT.equal( - md.digest().toHex(), - '944cd2847fb54558d4775db0485a50003111c8e5daa63fe722c6aa37'); - }); - }); -} - -// check for AMD -if(typeof define === 'function') { - define([ - 'forge/sha512', - 'forge/util' - ], function(SHA512, UTIL) { - Tests( - // Global provided by test harness - ASSERT, - SHA512(), - UTIL() - ); - }); -} else if(typeof module === 'object' && module.exports) { - // assume NodeJS - Tests( - require('assert'), - require('../../js/sha512')(), - require('../../js/util')()); -} - -})(); diff --git a/alarm/node_modules/node-forge/nodejs/test/ssh.js b/alarm/node_modules/node-forge/nodejs/test/ssh.js deleted file mode 100644 index c90eb26..0000000 --- a/alarm/node_modules/node-forge/nodejs/test/ssh.js +++ /dev/null @@ -1,193 +0,0 @@ -(function() { - -function Tests(ASSERT, forge) { - - // Original RSA key generated by openssh - var keystr = - '-----BEGIN RSA PRIVATE KEY-----\r\n' + - 'MIIEogIBAAKCAQEA301O+LBnd6ngw9i0Pb5iTwlQ1s37ay3DNpisjh+jPDDvaIZq\r\n' + - 'PC+44YV7RaR1ib2wEoQfg4DwqVw5wlA2x97Txngb+sJe0yUfmM9vMTxhXWuURVR6\r\n' + - '6DGd8t2eOBN8qDoYlpvdVf8Go5Btrb6NCexUbZtFS1AmumK2zQKxIizgVLK8dx4G\r\n' + - 'NYbqxibUxgYHbwRpu8ROrogVrZbMW1cOb4JE+DzG1FvfHSdzkxb9e5ARcsuLxCdP\r\n' + - 'ItUMVY8jjgER6b5lK+Nzr57hFdr08RjWGBldNGrCFqDdm+1WkGAHTRrg/i/MD8BU\r\n' + - '8NCFUBpQTSrhALkGqBdGZPN/PrXonXjhcd11awIDAQABAoIBAHGMESUaJnLN2jIc\r\n' + - 'RoLDBaBk/0tLEJaOfZ6Mgen/InUf+Q0wlGKobZ2Xz3g5SV9SKm8v6gpnjXjBIcmy\r\n' + - 'GjkGEK/yMWAQaEF7thZxHHxv1J65bnrWm2zolgWCNcsT9aZhbFFhTmpFNO4FKhBY\r\n' + - 'PcWW+9OESfci+Z57RbL3tHTJVwUZrthtagpFEgVceq18GLSS9N4TWJ8HX1CDxf9R\r\n' + - '4gzEy3+8oC0QONx+bgsWUmzNk9QNNW6yPV5NYZ3SwNLVgw3+6m8WDaqo5FWK7y2f\r\n' + - 'pa63DUzXlg5uSYnk4OFVxI6TLpmNQcjigpXnsd1PwcynW0AM83jzIYu0F31ppU61\r\n' + - '8flrqfECgYEA8j/joUve1F4lTt2U34RF+59giZ1r0ME4LafNEgN/ZLMB8ghToSqr\r\n' + - 'qzNnJnSppkAKTa2NVZGgJkvqn+qysM1HNm/3ksdUcE5yijgc3E17PNdBJwwNLZfP\r\n' + - 'p9jB/ZPaNMduGqltYamOVkbg/qS7O4rcUHstrGGGtJ9fveH+cu87emMCgYEA6/oX\r\n' + - '6A2fW88hw4hZwV2pCk6gumi89vXbKbhnD6j907TW583xIqXYsQBb7x/KGyPf65+k\r\n' + - 'Sou9MRyLhRu7qcc8INpSnFsra8ZQosP+ao8tUTq7p7N0H27qG5liTeAAksvk/xnq\r\n' + - '2VdL1YDRpo4tmRD7TAj8uc1sgXqdsBCPrqq4Q1kCgYAHcNjwEmGEymOA+aNh/jEc\r\n' + - 'Gngfofs2zUiJdncBD6RxFmJ/6auP7ryZJJoNf1XaqmrmmecWcsOliX1qbg4RCi0e\r\n' + - 'ye+jzYWVcYNpJXIVfjfD1aTFq0QYW2pgcHL88/am2l1SalPWxRt/IOw2Rh8OJCTC\r\n' + - 'QBZWDiTSFXceYPus0hZUmwKBgCc2FYbfzJ0q3Adrvs5cy9wEmLyg7tVyoQpbs/Rs\r\n' + - 'NlFZeWRnWixRtqIi1yPy+lhsK6cxjdE9SyDAB4cExrg9fQZQgO2uUJbGC1wgiUQX\r\n' + - 'qoYW5lvFfARFH+2aHTWnhTDfZJvnKJkY4mcF0tCES5tlsPw/eg89zUvunglFlzqE\r\n' + - '771xAoGAdYRG1PIkAzjuh785rc35885dsaXChZx1+7rfZ+AclyisRsmES9UfqL6M\r\n' + - '+SuluaBSWJQUBS7iaHazUeXmy5t+HBjSSLuAOHoZUckwDWD3EM7GHjFlWJOCArI3\r\n' + - 'hOYlsXSyl07rApzg/t+HxXcNpLZGJTgRwrRGF2OipUL0VPlTdRc=\r\n' + - '-----END RSA PRIVATE KEY-----\r\n'; - - var key = forge.pki.privateKeyFromPem(keystr); - - describe('ssh', function() { - it('should convert keys to openssh public keys', function() { - var expect = - 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDfTU74sGd3qeDD2LQ9vmJPCVD' + - 'WzftrLcM2mKyOH6M8MO9ohmo8L7jhhXtFpHWJvbAShB+DgPCpXDnCUDbH3tPGeB' + - 'v6wl7TJR+Yz28xPGFda5RFVHroMZ3y3Z44E3yoOhiWm91V/wajkG2tvo0J7FRtm' + - '0VLUCa6YrbNArEiLOBUsrx3HgY1hurGJtTGBgdvBGm7xE6uiBWtlsxbVw5vgkT4' + - 'PMbUW98dJ3OTFv17kBFyy4vEJ08i1QxVjyOOARHpvmUr43OvnuEV2vTxGNYYGV0' + - '0asIWoN2b7VaQYAdNGuD+L8wPwFTw0IVQGlBNKuEAuQaoF0Zk838+teideOFx3X' + - 'Vr A comment'; - - ASSERT.equal(forge.ssh.publicKeyToOpenSSH(key, 'A comment'), expect); - }); - - it('should convert keys to putty unencrypted keys', function() { - var expect = - 'PuTTY-User-Key-File-2: ssh-rsa\r\n' + - 'Encryption: none\r\n' + - 'Comment: imported-openssh-key\r\n' + - 'Public-Lines: 6\r\n' + - 'AAAAB3NzaC1yc2EAAAADAQABAAABAQDfTU74sGd3qeDD2LQ9vmJPCVDWzftrLcM2\r\n' + - 'mKyOH6M8MO9ohmo8L7jhhXtFpHWJvbAShB+DgPCpXDnCUDbH3tPGeBv6wl7TJR+Y\r\n' + - 'z28xPGFda5RFVHroMZ3y3Z44E3yoOhiWm91V/wajkG2tvo0J7FRtm0VLUCa6YrbN\r\n' + - 'ArEiLOBUsrx3HgY1hurGJtTGBgdvBGm7xE6uiBWtlsxbVw5vgkT4PMbUW98dJ3OT\r\n' + - 'Fv17kBFyy4vEJ08i1QxVjyOOARHpvmUr43OvnuEV2vTxGNYYGV00asIWoN2b7VaQ\r\n' + - 'YAdNGuD+L8wPwFTw0IVQGlBNKuEAuQaoF0Zk838+teideOFx3XVr\r\n' + - 'Private-Lines: 14\r\n' + - 'AAABAHGMESUaJnLN2jIcRoLDBaBk/0tLEJaOfZ6Mgen/InUf+Q0wlGKobZ2Xz3g5\r\n' + - 'SV9SKm8v6gpnjXjBIcmyGjkGEK/yMWAQaEF7thZxHHxv1J65bnrWm2zolgWCNcsT\r\n' + - '9aZhbFFhTmpFNO4FKhBYPcWW+9OESfci+Z57RbL3tHTJVwUZrthtagpFEgVceq18\r\n' + - 'GLSS9N4TWJ8HX1CDxf9R4gzEy3+8oC0QONx+bgsWUmzNk9QNNW6yPV5NYZ3SwNLV\r\n' + - 'gw3+6m8WDaqo5FWK7y2fpa63DUzXlg5uSYnk4OFVxI6TLpmNQcjigpXnsd1Pwcyn\r\n' + - 'W0AM83jzIYu0F31ppU618flrqfEAAACBAPI/46FL3tReJU7dlN+ERfufYImda9DB\r\n' + - 'OC2nzRIDf2SzAfIIU6Eqq6szZyZ0qaZACk2tjVWRoCZL6p/qsrDNRzZv95LHVHBO\r\n' + - 'coo4HNxNezzXQScMDS2Xz6fYwf2T2jTHbhqpbWGpjlZG4P6kuzuK3FB7LaxhhrSf\r\n' + - 'X73h/nLvO3pjAAAAgQDr+hfoDZ9bzyHDiFnBXakKTqC6aLz29dspuGcPqP3TtNbn\r\n' + - 'zfEipdixAFvvH8obI9/rn6RKi70xHIuFG7upxzwg2lKcWytrxlCiw/5qjy1ROrun\r\n' + - 's3QfbuobmWJN4ACSy+T/GerZV0vVgNGmji2ZEPtMCPy5zWyBep2wEI+uqrhDWQAA\r\n' + - 'AIB1hEbU8iQDOO6Hvzmtzfnzzl2xpcKFnHX7ut9n4ByXKKxGyYRL1R+ovoz5K6W5\r\n' + - 'oFJYlBQFLuJodrNR5ebLm34cGNJIu4A4ehlRyTANYPcQzsYeMWVYk4ICsjeE5iWx\r\n' + - 'dLKXTusCnOD+34fFdw2ktkYlOBHCtEYXY6KlQvRU+VN1Fw==\r\n' + - 'Private-MAC: 87fa1011848453317d8e41b00c927e9d17dc334e\r\n'; - - ASSERT.equal(forge.ssh.privateKeyToPutty(key, '', 'imported-openssh-key'), expect); - }); - - it('should convert keys to putty encrypted keys', function() { - var expect = - 'PuTTY-User-Key-File-2: ssh-rsa\r\n' + - 'Encryption: aes256-cbc\r\n' + - 'Comment: imported-openssh-key\r\n' + - 'Public-Lines: 6\r\n' + - 'AAAAB3NzaC1yc2EAAAADAQABAAABAQDfTU74sGd3qeDD2LQ9vmJPCVDWzftrLcM2\r\n' + - 'mKyOH6M8MO9ohmo8L7jhhXtFpHWJvbAShB+DgPCpXDnCUDbH3tPGeBv6wl7TJR+Y\r\n' + - 'z28xPGFda5RFVHroMZ3y3Z44E3yoOhiWm91V/wajkG2tvo0J7FRtm0VLUCa6YrbN\r\n' + - 'ArEiLOBUsrx3HgY1hurGJtTGBgdvBGm7xE6uiBWtlsxbVw5vgkT4PMbUW98dJ3OT\r\n' + - 'Fv17kBFyy4vEJ08i1QxVjyOOARHpvmUr43OvnuEV2vTxGNYYGV00asIWoN2b7VaQ\r\n' + - 'YAdNGuD+L8wPwFTw0IVQGlBNKuEAuQaoF0Zk838+teideOFx3XVr\r\n' + - 'Private-Lines: 14\r\n' + - 'EiVwpacmA7mhmGBTPXeIZZPkeRDtb4LOWzI+68cA5oM7UJTpBxh9zsnpAdWg2knP\r\n' + - 'snA5gpTSq0CJV9HWb8yAY3R5izflQ493fCbJzuPFTW6RJ2y/D5dUmDWccfMczPNT\r\n' + - 'GEDOfslCPe+Yz1h0y0y5NI5WwJowxv3nL9FTlQ9KDVrdoSizkVbTh4CJTrvqIc7c\r\n' + - 'sI/HU25OHS8kcIZPiPL8m40ot254rkbPCWrskm9H4n+EC+BwJNtEic9ZQfGPWOVl\r\n' + - 't8JxY35mHqGIlfhyVkdts/Rx7kwOHY+GPXDVRnHQZQOkFtVqCFGx8mL83CspIEq0\r\n' + - 'V8LaHuvxiadA4OEeR0azuDhfVJXvrUpHd4CPjAzJu4doHm98GJAyrz3mtCyxIguH\r\n' + - 'k8zKVJzbNawy5T43l5x9cR6VKzcl6d4V14vphiovxc8DG/J7RHBd4d1y6wxo5ZMY\r\n' + - 'qqQ0E6VHtq6auBZjnGzx0P/1lGjpZdxUf4OVTaZ+stCxX5wAH9exF+gdZAlk20Gp\r\n' + - 'Atg60boQuolHBiH66dQynyHp+6yuLPLKXy74EO+AEB3HvNK7aIQV8rCD7I7HEa12\r\n' + - 'xxqIH4l0FWQKHXNIrK45uo6Hdg1siYp9zU4FFgDcNGOZJsT6+etPp1sgAeBuBR4F\r\n' + - 'pnuX1KZzRTbG1kcRrTOjsMh0bKfZAn0+uwyuPBtwEnLziGoCXU+9+XO85zcPF2j1\r\n' + - 'Ip5AWAOBI82SKMLu51Dpdz1rwSZOPFWnHxRxfnUiQa9Kc7qBGrMxy1UNECAwMGzp\r\n' + - 'ljKesqZvoANo0voiodALXGs7kSpmXjcbHnUUt0SI/QHyajXabIiLHGf6lfvStYLP\r\n' + - 'L5bLfswsMqG/2lonYWrPl9YC0WzvfRpbHgpI9G1eLjFFRlaqJ3EpZf5Dy26Z0eh0\r\n' + - 'Private-MAC: 23aa5b6e2a411107c59e1e6c3bca06247e3c9627\r\n'; - - ASSERT.equal(forge.ssh.privateKeyToPutty(key, 'passphrase', 'imported-openssh-key'), expect); - }); - - it('should convert keys to openssh encrypted private keys', function() { - var expect = - '-----BEGIN RSA PRIVATE KEY-----\n' + - 'Proc-Type: 4,ENCRYPTED\n' + - 'DEK-Info: AES-128-CBC,2616162F269429AA628E42C3BD5A0027\n' + - '\n' + - 'p8+mGWeQxZrRg6OeeFqgEX8sXGGUqWJuK4XhtgRpxAQaSg8bK6m/ahArEonjzgrO\n' + - 'XMLow7N0aXqGJzL+n4c4EzL7e4SquzeYZLq0UCs8vbWE5GdTT6BxisWIJqzOaQW3\n' + - 'd3OqS2lM5o47cuADMIMp015b0dJn5nwJall20GSI1XnpTUHIJ1oFv7fW/s5g39VD\n' + - 'DSVmPzJEMhcTa8BskHrKITV6l+TuivGqrHH0LCYCfQ3IBLiRZrPINQLLkaHR6kis\n' + - '4qvFEMhQGAz0GrifwEob9+FPzDAHHnYTS0kG1jhZ3p92vaUi8sPxyv5ndRXOSZZg\n' + - 'vh6Cdrk62myG/rHbsBRrrpa+Ka+BX4ofedwP3SBHPwqBpksYhEF7MxsWKhmHY+d0\n' + - 'YINHrj0w+yfw4H3n1+0w4wajlHVUncp7RP8KKMtG3vvvfF1loWpLbyF0s6fgq7p4\n' + - '7kt1LcnRKB3U2IZYfMHuv94+5q0BKfGF6NmRpmgdJojyS2IXZyFaJRqrCa0mKcP9\n' + - 'PtDZFPTEy0VeNTL8KqjweEmjK3/JtZPVgXXkPWlFMw3Hc/dtP/l6VssGLk8P/DHD\n' + - 'yknagPsfa70iydTvDO+nrtS57DkoUqhMsU3BhCjMzZg+/bo1JgmxQUWT//PoQLSB\n' + - 'Z7/F59AfHzZIkWgqfvGRzX3y+G1M1l11dX658iWmN0kZ5MyHU0qwU9hVI6P/fcfk\n' + - '6MQKc/MzPnkjw/knREtYMtHrVsKrDVDizfguGFKFC8FVhhrDOFZUnza0nh6nt1HZ\n' + - 'Xk156MhATenWdHBW4Rn3ec1aMOD16k2SRIHd+nyJzx51H3PUdTtXBWqFNGggzoJG\n' + - '99ax3jD6pTLQY3BG146QKQ0csItMTIdwZPAidkzv8VVXC7HaqXk1K1pgfJT6mD4P\n' + - 'LaNbuA9r7mNiNoPzwzk0h3BomBTMXZpAyL9Jlre9jTu6lpyN/TkOzHhs/I1/lvKQ\n' + - 'Uki7BXv65Jq6RqkTbNc5plxBYggdzLGurr0ZIBDsoN6uXkzaM+fCMlJU8+MgAcBb\n' + - 'x88bj8h3t4akPd/WaSsWKeOzB3Uaw3ztYCpwSVv1F+N0u6C6zGo+9VFAQZh1uKvC\n' + - 'G9U5hvAG7WEoQ801/fvKj93lqLDhOarPJC8CcfMLwoIqj7zah7TtBYq8VsuF7Fsx\n' + - 'dEWNFiXhtFqUhgBMt1tcOXGiXA79NucSVzUBNzrRZKlLDYm2TKKyOqEbG9vF/YxL\n' + - 'ZG3TwmcFj0sko2K61ya7FGpKmfPQCJJoi0tIfnW4eIVcyeRpXYi5B2xqvSXcTdUx\n' + - '5y5Vpuu1CzrMZr50b3sSOFjcOXE5211RS8SHpOMWY+JDDB4vF4Dv94fqEIgnFtrR\n' + - 'oQgk3DueWb1x09NcJtEZsW6lT3Jw19ursb++XSejFZ9Xu5ED8fbewgGo2w/N5j1H\n' + - 'vQEnFkGcL1jLlLqp9PlvPIE4a///wy1y0XbnKMJs+dKxiesKVx1zZ1WDcK2Qgv4r\n' + - 'G+RsZzHZuCjUyty1+SMVOYM6+3zW6bjXN58xI3XeSxgE/JaJKjLWBZWx5+eU7b6a\n' + - '04mJDMhnpdLHG97m9p90L1yuudiJfq6ngha41xxv9xLmNatfrtStCrq/DR0KHm0K\n' + - '-----END RSA PRIVATE KEY-----\n'; - - // Unable to test -- uses a random IV that I can't control - //ASSERT.equal(forge.ssh.rsaPrivateKeyAsOpenSSH(key, 'passphrase'), expect); - }); - - it('should convert keys to openssh unencrypted private keys', function() { - var expect = keystr; - ASSERT.equal(forge.ssh.privateKeyToOpenSSH(key, ''), expect); - }); - - it('should get an MD5 SSH fingerprint', function() { - var fp = forge.ssh.getPublicKeyFingerprint(key); - ASSERT.equal(fp.toHex(), '46549abeb89422a0955d4041ae7322ec'); - }); - - it('should get a hex MD5 SSH fingerprint', function() { - var fp = forge.ssh.getPublicKeyFingerprint(key, {encoding: 'hex'}); - ASSERT.equal(fp, '46549abeb89422a0955d4041ae7322ec'); - }); - - it('should get a hex, colon-delimited MD5 SSH fingerprint', function() { - var fp = forge.ssh.getPublicKeyFingerprint( - key, {encoding: 'hex', delimiter: ':'}); - ASSERT.equal(fp, '46:54:9a:be:b8:94:22:a0:95:5d:40:41:ae:73:22:ec'); - }); - }); -} - -// check for AMD -if(typeof define === 'function') { - define([ - 'forge/forge' - ], function(forge) { - Tests( - // Global provided by test harness - ASSERT, - forge - ); - }); -} else if(typeof module === 'object' && module.exports) { - // assume NodeJS - Tests( - require('assert'), - require('../../js/forge')); -} - -})(); diff --git a/alarm/node_modules/node-forge/nodejs/test/tls.js b/alarm/node_modules/node-forge/nodejs/test/tls.js deleted file mode 100644 index d9ce944..0000000 --- a/alarm/node_modules/node-forge/nodejs/test/tls.js +++ /dev/null @@ -1,191 +0,0 @@ -(function() { - -function Tests(ASSERT, forge) { - describe('tls', function() { - it('should test TLS 1.0 PRF', function() { - // Note: This test vector is originally from: - // http://www.imc.org/ietf-tls/mail-archive/msg01589.html - // But that link is now dead. - var secret = forge.util.createBuffer().fillWithByte(0xAB, 48).getBytes(); - var seed = forge.util.createBuffer().fillWithByte(0xCD, 64).getBytes(); - var bytes = forge.tls.prf_tls1(secret, 'PRF Testvector', seed, 104); - var expect = - 'd3d4d1e349b5d515044666d51de32bab258cb521' + - 'b6b053463e354832fd976754443bcf9a296519bc' + - '289abcbc1187e4ebd31e602353776c408aafb74c' + - 'bc85eff69255f9788faa184cbb957a9819d84a5d' + - '7eb006eb459d3ae8de9810454b8b2d8f1afbc655' + - 'a8c9a013'; - ASSERT.equal(bytes.toHex(), expect); - }); - - it('should establish a TLS connection and transfer data', function(done) { - var end = {}; - var data = {}; - - createCertificate('server', data); - createCertificate('client', data); - data.client.connection = {}; - data.server.connection = {}; - - end.client = forge.tls.createConnection({ - server: false, - caStore: [data.server.cert], - sessionCache: {}, - cipherSuites: [ - forge.tls.CipherSuites.TLS_RSA_WITH_AES_128_CBC_SHA, - forge.tls.CipherSuites.TLS_RSA_WITH_AES_256_CBC_SHA], - virtualHost: 'server', - verify: function(c, verified, depth, certs) { - data.client.connection.commonName = - certs[0].subject.getField('CN').value; - data.client.connection.certVerified = verified; - return true; - }, - connected: function(c) { - c.prepare('Hello Server'); - }, - getCertificate: function(c, hint) { - return data.client.cert; - }, - getPrivateKey: function(c, cert) { - return data.client.privateKey; - }, - tlsDataReady: function(c) { - end.server.process(c.tlsData.getBytes()); - }, - dataReady: function(c) { - data.client.connection.data = c.data.getBytes(); - c.close(); - }, - closed: function(c) { - ASSERT.equal(data.client.connection.commonName, 'server'); - ASSERT.equal(data.client.connection.certVerified, true); - ASSERT.equal(data.client.connection.data, 'Hello Client'); - done(); - }, - error: function(c, error) { - ASSERT.equal(error.message, undefined); - } - }); - - end.server = forge.tls.createConnection({ - server: true, - caStore: [data.client.cert], - sessionCache: {}, - cipherSuites: [ - forge.tls.CipherSuites.TLS_RSA_WITH_AES_128_CBC_SHA, - forge.tls.CipherSuites.TLS_RSA_WITH_AES_256_CBC_SHA], - connected: function(c) { - }, - verifyClient: true, - verify: function(c, verified, depth, certs) { - data.server.connection.commonName = - certs[0].subject.getField('CN').value; - data.server.connection.certVerified = verified; - return true; - }, - getCertificate: function(c, hint) { - data.server.connection.certHint = hint[0]; - return data.server.cert; - }, - getPrivateKey: function(c, cert) { - return data.server.privateKey; - }, - tlsDataReady: function(c) { - end.client.process(c.tlsData.getBytes()); - }, - dataReady: function(c) { - data.server.connection.data = c.data.getBytes(); - c.prepare('Hello Client'); - c.close(); - }, - closed: function(c) { - ASSERT.equal(data.server.connection.certHint, 'server'); - ASSERT.equal(data.server.connection.commonName, 'client'); - ASSERT.equal(data.server.connection.certVerified, true); - ASSERT.equal(data.server.connection.data, 'Hello Server'); - }, - error: function(c, error) { - ASSERT.equal(error.message, undefined); - } - }); - - end.client.handshake(); - - function createCertificate(cn, data) { - var keys = forge.pki.rsa.generateKeyPair(512); - var cert = forge.pki.createCertificate(); - cert.publicKey = keys.publicKey; - cert.serialNumber = '01'; - cert.validity.notBefore = new Date(); - cert.validity.notAfter = new Date(); - cert.validity.notAfter.setFullYear( - cert.validity.notBefore.getFullYear() + 1); - var attrs = [{ - name: 'commonName', - value: cn - }, { - name: 'countryName', - value: 'US' - }, { - shortName: 'ST', - value: 'Virginia' - }, { - name: 'localityName', - value: 'Blacksburg' - }, { - name: 'organizationName', - value: 'Test' - }, { - shortName: 'OU', - value: 'Test' - }]; - cert.setSubject(attrs); - cert.setIssuer(attrs); - cert.setExtensions([{ - name: 'basicConstraints', - cA: true - }, { - name: 'keyUsage', - keyCertSign: true, - digitalSignature: true, - nonRepudiation: true, - keyEncipherment: true, - dataEncipherment: true - }, { - name: 'subjectAltName', - altNames: [{ - type: 6, // URI - value: 'https://myuri.com/webid#me' - }] - }]); - cert.sign(keys.privateKey); - data[cn] = { - cert: forge.pki.certificateToPem(cert), - privateKey: forge.pki.privateKeyToPem(keys.privateKey) - }; - } - }); - }); -} - -// check for AMD -if(typeof define === 'function') { - define([ - 'forge/forge' - ], function(forge) { - Tests( - // Global provided by test harness - ASSERT, - forge - ); - }); -} else if(typeof module === 'object' && module.exports) { - // assume NodeJS - Tests( - require('assert'), - require('../../js/forge')); -} - -})(); diff --git a/alarm/node_modules/node-forge/nodejs/test/util.js b/alarm/node_modules/node-forge/nodejs/test/util.js deleted file mode 100644 index 57104a1..0000000 --- a/alarm/node_modules/node-forge/nodejs/test/util.js +++ /dev/null @@ -1,406 +0,0 @@ -(function() { - -function Tests(ASSERT, UTIL) { - // custom assertion to test array-like objects - function assertArrayEqual(actual, expected) { - ASSERT.equal(actual.length, expected.length); - for (var idx = 0; idx < expected.length; idx++) { - ASSERT.equal(actual[idx], expected[idx]); - } - } - - describe('util', function() { - it('should put bytes into a buffer', function() { - var b = UTIL.createBuffer(); - b.putByte(1); - b.putByte(2); - b.putByte(3); - b.putByte(4); - b.putInt32(4); - b.putByte(1); - b.putByte(2); - b.putByte(3); - b.putInt32(4294967295); - var hex = b.toHex(); - ASSERT.equal(hex, '0102030400000004010203ffffffff'); - - var bytes = []; - while(b.length() > 0) { - bytes.push(b.getByte()); - } - ASSERT.deepEqual( - bytes, [1, 2, 3, 4, 0, 0, 0, 4, 1, 2, 3, 255, 255, 255, 255]); - }); - - it('should put bytes from an Uint8Array into a buffer', function() { - if(typeof Uint8Array === 'undefined') { - return; - } - var data = [1, 2, 3, 4, 0, 0, 0, 4, 1, 2, 3, 255, 255, 255, 255]; - var ab = new Uint8Array(data); - var b = UTIL.createBuffer(ab); - var hex = b.toHex(); - ASSERT.equal(hex, '0102030400000004010203ffffffff'); - - var bytes = []; - while(b.length() > 0) { - bytes.push(b.getByte()); - } - ASSERT.deepEqual(bytes, data); - }); - - it('should convert bytes from hex', function() { - var hex = '0102030400000004010203ffffffff'; - var b = UTIL.createBuffer(); - b.putBytes(UTIL.hexToBytes(hex)); - ASSERT.equal(b.toHex(), hex); - }); - - it('should put 0 into a buffer using two\'s complement', function() { - var b = UTIL.createBuffer(); - b.putSignedInt(0, 8); - ASSERT.equal(b.toHex(), '00'); - }); - - it('should put 0 into a buffer using two\'s complement w/2 bytes', function() { - var b = UTIL.createBuffer(); - b.putSignedInt(0, 16); - ASSERT.equal(b.toHex(), '0000'); - }); - - it('should put 127 into a buffer using two\'s complement', function() { - var b = UTIL.createBuffer(); - b.putSignedInt(127, 8); - ASSERT.equal(b.toHex(), '7f'); - }); - - it('should put 127 into a buffer using two\'s complement w/2 bytes', function() { - var b = UTIL.createBuffer(); - b.putSignedInt(127, 16); - ASSERT.equal(b.toHex(), '007f'); - }); - - it('should put 128 into a buffer using two\'s complement', function() { - var b = UTIL.createBuffer(); - b.putSignedInt(128, 16); - ASSERT.equal(b.toHex(), '0080'); - }); - - it('should put 256 into a buffer using two\'s complement', function() { - var b = UTIL.createBuffer(); - b.putSignedInt(256, 16); - ASSERT.equal(b.toHex(), '0100'); - }); - - it('should put -128 into a buffer using two\'s complement', function() { - var b = UTIL.createBuffer(); - b.putSignedInt(-128, 8); - ASSERT.equal(b.toHex(), '80'); - }); - - it('should put -129 into a buffer using two\'s complement', function() { - var b = UTIL.createBuffer(); - b.putSignedInt(-129, 16); - ASSERT.equal(b.toHex(), 'ff7f'); - }); - - it('should get 0 from a buffer using two\'s complement', function() { - var x = 0; - var n = 8; - var b = UTIL.createBuffer(); - b.putSignedInt(x, n); - ASSERT.equal(b.getSignedInt(x, n), x); - }); - - it('should get 127 from a buffer using two\'s complement', function() { - var x = 127; - var n = 8; - var b = UTIL.createBuffer(); - b.putSignedInt(x, n); - ASSERT.equal(b.getSignedInt(n), x); - }); - - it('should get 128 from a buffer using two\'s complement', function() { - var x = 128; - var n = 16; - var b = UTIL.createBuffer(); - b.putSignedInt(x, n); - ASSERT.equal(b.getSignedInt(n), x); - }); - - it('should get 256 from a buffer using two\'s complement', function() { - var x = 256; - var n = 16; - var b = UTIL.createBuffer(); - b.putSignedInt(x, n); - ASSERT.equal(b.getSignedInt(n), x); - }); - - it('should get -128 from a buffer using two\'s complement', function() { - var x = -128; - var n = 8; - var b = UTIL.createBuffer(); - b.putSignedInt(x, n); - ASSERT.equal(b.getSignedInt(n), x); - }); - - it('should get -129 from a buffer using two\'s complement', function() { - var x = -129; - var n = 16; - var b = UTIL.createBuffer(); - b.putSignedInt(x, n); - ASSERT.equal(b.getSignedInt(n), x); - }); - - it('should base64 encode some bytes', function() { - var s1 = '00010203050607080A0B0C0D0F1011121415161719'; - var s2 = 'MDAwMTAyMDMwNTA2MDcwODBBMEIwQzBEMEYxMDExMTIxNDE1MTYxNzE5'; - ASSERT.equal(UTIL.encode64(s1), s2); - }); - - it('should base64 decode some bytes', function() { - var s1 = '00010203050607080A0B0C0D0F1011121415161719'; - var s2 = 'MDAwMTAyMDMwNTA2MDcwODBBMEIwQzBEMEYxMDExMTIxNDE1MTYxNzE5'; - ASSERT.equal(UTIL.decode64(s2), s1); - }); - - it('should base64 encode some bytes using util.binary.base64', function() { - var s1 = new Uint8Array([ - 0x30, 0x30, 0x30, 0x31, 0x30, 0x32, 0x30, 0x33, 0x30, - 0x35, 0x30, 0x36, 0x30, 0x37, 0x30, 0x38, 0x30, 0x41, - 0x30, 0x42, 0x30, 0x43, 0x30, 0x44, 0x30, 0x46, 0x31, - 0x30, 0x31, 0x31, 0x31, 0x32, 0x31, 0x34, 0x31, 0x35, - 0x31, 0x36, 0x31, 0x37, 0x31, 0x39]); - var s2 = 'MDAwMTAyMDMwNTA2MDcwODBBMEIwQzBEMEYxMDExMTIxNDE1MTYxNzE5'; - ASSERT.equal(UTIL.binary.base64.encode(s1), s2); - }); - - it('should base64 encode some odd-length bytes using util.binary.base64', function() { - var s1 = new Uint8Array([ - 0x30, 0x30, 0x30, 0x31, 0x30, 0x32, 0x30, 0x33, 0x30, - 0x35, 0x30, 0x36, 0x30, 0x37, 0x30, 0x38, 0x30, 0x41, - 0x30, 0x42, 0x30, 0x43, 0x30, 0x44, 0x30, 0x46, 0x31, - 0x30, 0x31, 0x31, 0x31, 0x32, 0x31, 0x34, 0x31, 0x35, - 0x31, 0x36, 0x31, 0x37, 0x31, 0x39, 0x31, 0x41, 0x31, - 0x42]); - var s2 = 'MDAwMTAyMDMwNTA2MDcwODBBMEIwQzBEMEYxMDExMTIxNDE1MTYxNzE5MUExQg=='; - ASSERT.equal(UTIL.binary.base64.encode(s1), s2); - }); - - it('should base64 decode some bytes using util.binary.base64', function() { - var s1 = new Uint8Array([ - 0x30, 0x30, 0x30, 0x31, 0x30, 0x32, 0x30, 0x33, 0x30, - 0x35, 0x30, 0x36, 0x30, 0x37, 0x30, 0x38, 0x30, 0x41, - 0x30, 0x42, 0x30, 0x43, 0x30, 0x44, 0x30, 0x46, 0x31, - 0x30, 0x31, 0x31, 0x31, 0x32, 0x31, 0x34, 0x31, 0x35, - 0x31, 0x36, 0x31, 0x37, 0x31, 0x39]); - var s2 = 'MDAwMTAyMDMwNTA2MDcwODBBMEIwQzBEMEYxMDExMTIxNDE1MTYxNzE5'; - ASSERT.deepEqual(UTIL.binary.base64.decode(s2), s1); - }); - - it('should base64 decode some odd-length bytes using util.binary.base64', function() { - var s1 = new Uint8Array([ - 0x30, 0x30, 0x30, 0x31, 0x30, 0x32, 0x30, 0x33, 0x30, - 0x35, 0x30, 0x36, 0x30, 0x37, 0x30, 0x38, 0x30, 0x41, - 0x30, 0x42, 0x30, 0x43, 0x30, 0x44, 0x30, 0x46, 0x31, - 0x30, 0x31, 0x31, 0x31, 0x32, 0x31, 0x34, 0x31, 0x35, - 0x31, 0x36, 0x31, 0x37, 0x31, 0x39, 0x31, 0x41, 0x31, - 0x42]); - var s2 = 'MDAwMTAyMDMwNTA2MDcwODBBMEIwQzBEMEYxMDExMTIxNDE1MTYxNzE5MUExQg=='; - assertArrayEqual(UTIL.binary.base64.decode(s2), s1); - }); - - it('should convert IPv4 0.0.0.0 textual address to 4-byte address', function() { - var bytes = UTIL.bytesFromIP('0.0.0.0'); - var b = UTIL.createBuffer().fillWithByte(0, 4); - ASSERT.equal(bytes, b.getBytes()); - }); - - it('should convert IPv4 127.0.0.1 textual address to 4-byte address', function() { - var bytes = UTIL.bytesFromIP('127.0.0.1'); - var b = UTIL.createBuffer(); - b.putByte(127); - b.putByte(0); - b.putByte(0); - b.putByte(1); - ASSERT.equal(bytes, b.getBytes()); - }); - - it('should convert IPv6 :: textual address to 16-byte address', function() { - var bytes = UTIL.bytesFromIP('::'); - var b = UTIL.createBuffer().fillWithByte(0, 16); - ASSERT.equal(bytes, b.getBytes()); - }); - - it('should convert IPv6 ::0 textual address to 16-byte address', function() { - var bytes = UTIL.bytesFromIP('::0'); - var b = UTIL.createBuffer().fillWithByte(0, 16); - ASSERT.equal(bytes, b.getBytes()); - }); - - it('should convert IPv6 0:: textual address to 16-byte address', function() { - var bytes = UTIL.bytesFromIP('0::'); - var b = UTIL.createBuffer().fillWithByte(0, 16); - ASSERT.equal(bytes, b.getBytes()); - }); - - it('should convert IPv6 ::1 textual address to 16-byte address', function() { - var bytes = UTIL.bytesFromIP('::1'); - var b = UTIL.createBuffer().fillWithByte(0, 14); - b.putBytes(UTIL.hexToBytes('0001')); - ASSERT.equal(bytes, b.getBytes()); - }); - - it('should convert IPv6 1:: textual address to 16-byte address', function() { - var bytes = UTIL.bytesFromIP('1::'); - var b = UTIL.createBuffer(); - b.putBytes(UTIL.hexToBytes('0001')); - b.fillWithByte(0, 14); - ASSERT.equal(bytes, b.getBytes()); - }); - - it('should convert IPv6 1::1 textual address to 16-byte address', function() { - var bytes = UTIL.bytesFromIP('1::1'); - var b = UTIL.createBuffer(); - b.putBytes(UTIL.hexToBytes('0001')); - b.fillWithByte(0, 12); - b.putBytes(UTIL.hexToBytes('0001')); - ASSERT.equal(bytes, b.getBytes()); - }); - - it('should convert IPv6 1::1:0 textual address to 16-byte address', function() { - var bytes = UTIL.bytesFromIP('1::1:0'); - var b = UTIL.createBuffer(); - b.putBytes(UTIL.hexToBytes('0001')); - b.fillWithByte(0, 10); - b.putBytes(UTIL.hexToBytes('0001')); - b.putBytes(UTIL.hexToBytes('0000')); - ASSERT.equal(bytes, b.getBytes()); - }); - - it('should convert IPv6 2001:db8:0:1:1:1:1:1 textual address to 16-byte address', function() { - var bytes = UTIL.bytesFromIP('2001:db8:0:1:1:1:1:1'); - var b = UTIL.createBuffer(); - b.putBytes(UTIL.hexToBytes('2001')); - b.putBytes(UTIL.hexToBytes('0db8')); - b.putBytes(UTIL.hexToBytes('0000')); - b.putBytes(UTIL.hexToBytes('0001')); - b.putBytes(UTIL.hexToBytes('0001')); - b.putBytes(UTIL.hexToBytes('0001')); - b.putBytes(UTIL.hexToBytes('0001')); - b.putBytes(UTIL.hexToBytes('0001')); - ASSERT.equal(bytes, b.getBytes()); - }); - - it('should convert IPv4 0.0.0.0 byte address to textual representation', function() { - var addr = '0.0.0.0'; - var bytes = UTIL.createBuffer().fillWithByte(0, 4).getBytes(); - var addr = UTIL.bytesToIP(bytes); - ASSERT.equal(addr, '0.0.0.0'); - }); - - it('should convert IPv4 0.0.0.0 byte address to textual representation', function() { - var addr = '127.0.0.1'; - var bytes = UTIL.bytesFromIP(addr); - var addr = UTIL.bytesToIP(bytes); - ASSERT.equal(addr, '127.0.0.1'); - }); - - it('should convert IPv6 :: byte address to canonical textual representation (RFC 5952)', function() { - var addr = '::'; - var bytes = UTIL.createBuffer().fillWithByte(0, 16).getBytes(); - var addr = UTIL.bytesToIP(bytes); - ASSERT.equal(addr, '::'); - }); - - it('should convert IPv6 ::1 byte address to canonical textual representation (RFC 5952)', function() { - var addr = '::1'; - var bytes = UTIL.bytesFromIP(addr); - var addr = UTIL.bytesToIP(bytes); - ASSERT.equal(addr, '::1'); - }); - - it('should convert IPv6 1:: byte address to canonical textual representation (RFC 5952)', function() { - var addr = '1::'; - var bytes = UTIL.bytesFromIP(addr); - var addr = UTIL.bytesToIP(bytes); - ASSERT.equal(addr, '1::'); - }); - - it('should convert IPv6 0:0:0:0:0:0:0:1 byte address to canonical textual representation (RFC 5952)', function() { - var addr = '0:0:0:0:0:0:0:1'; - var bytes = UTIL.bytesFromIP(addr); - var addr = UTIL.bytesToIP(bytes); - ASSERT.equal(addr, '::1'); - }); - - it('should convert IPv6 1:0:0:0:0:0:0:0 byte address to canonical textual representation (RFC 5952)', function() { - var addr = '1:0:0:0:0:0:0:0'; - var bytes = UTIL.bytesFromIP(addr); - var addr = UTIL.bytesToIP(bytes); - ASSERT.equal(addr, '1::'); - }); - - it('should convert IPv6 1::1 byte address to canonical textual representation (RFC 5952)', function() { - var addr = '1::1'; - var bytes = UTIL.bytesFromIP(addr); - var addr = UTIL.bytesToIP(bytes); - ASSERT.equal(addr, '1::1'); - }); - - it('should convert IPv6 1:0:0:0:0:0:0:1 byte address to canonical textual representation (RFC 5952)', function() { - var addr = '1:0:0:0:0:0:0:1'; - var bytes = UTIL.bytesFromIP(addr); - var addr = UTIL.bytesToIP(bytes); - ASSERT.equal(addr, '1::1'); - }); - - it('should convert IPv6 1:0000:0000:0000:0000:0000:0000:1 byte address to canonical textual representation (RFC 5952)', function() { - var addr = '1:0000:0000:0000:0000:0000:0000:1'; - var bytes = UTIL.bytesFromIP(addr); - var addr = UTIL.bytesToIP(bytes); - ASSERT.equal(addr, '1::1'); - }); - - it('should convert IPv6 1:0:0:1:1:1:0:1 byte address to canonical textual representation (RFC 5952)', function() { - var addr = '1:0:0:1:1:1:0:1'; - var bytes = UTIL.bytesFromIP(addr); - var addr = UTIL.bytesToIP(bytes); - ASSERT.equal(addr, '1::1:1:1:0:1'); - }); - - it('should convert IPv6 1:0:1:1:1:0:0:1 byte address to canonical textual representation (RFC 5952)', function() { - var addr = '1:0:1:1:1:0:0:1'; - var bytes = UTIL.bytesFromIP(addr); - var addr = UTIL.bytesToIP(bytes); - ASSERT.equal(addr, '1:0:1:1:1::1'); - }); - - it('should convert IPv6 2001:db8:0:1:1:1:1:1 byte address to canonical textual representation (RFC 5952)', function() { - var addr = '2001:db8:0:1:1:1:1:1'; - var bytes = UTIL.bytesFromIP(addr); - var addr = UTIL.bytesToIP(bytes); - ASSERT.equal(addr, '2001:db8:0:1:1:1:1:1'); - }); - }); -} - -// check for AMD -if(typeof define === 'function') { - define([ - 'forge/util' - ], function(UTIL) { - Tests( - // Global provided by test harness - ASSERT, - UTIL() - ); - }); -} else if(typeof module === 'object' && module.exports) { - // assume NodeJS - Tests( - require('assert'), - require('../../js/util')()); -} - -})(); diff --git a/alarm/node_modules/node-forge/nodejs/test/x509.js b/alarm/node_modules/node-forge/nodejs/test/x509.js deleted file mode 100644 index 47a9e7f..0000000 --- a/alarm/node_modules/node-forge/nodejs/test/x509.js +++ /dev/null @@ -1,734 +0,0 @@ -(function() { - -function Tests(ASSERT, PKI, MD, UTIL) { - var _pem = { - privateKey: '-----BEGIN RSA PRIVATE KEY-----\r\n' + - 'MIICXQIBAAKBgQDL0EugUiNGMWscLAVM0VoMdhDZEJOqdsUMpx9U0YZI7szokJqQ\r\n' + - 'NIwokiQ6EonNnWSMlIvy46AhnlRYn+ezeTeU7eMGTkP3VF29vXBo+dLq5e+8VyAy\r\n' + - 'Q3FzM1wI4ts4hRACF8w6mqygXQ7i/SDu8/rXqRGtvnM+z0MYDdKo80efzwIDAQAB\r\n' + - 'AoGAIzkGONi5G+JifmXlLJdplom486p3upf4Ce2/7mqfaG9MnkyPSairKD/JXvfh\r\n' + - 'NNWkkN8DKKDKBcVVElPgORYT0qwrWc7ueLBMUCbRXb1ZyfEulimG0R3kjUh7NYau\r\n' + - 'DaIkVgfykXGSQMZx8FoaT6L080zd+0emKDDYRrb+/kgJNJECQQDoUZoiC2K/DWNY\r\n' + - 'h3/ppZ0ane2y4SBmJUHJVMPQ2CEgxsrJTxet668ckNCKaOP/3VFPoWC41f17DvKq\r\n' + - 'noYINNntAkEA4JbZBZBVUrQFhHlrpXT4jzqtO2RlKZzEq8qmFZfEErxOT1WMyyCi\r\n' + - 'lAQ5gUKardo1Kf0omC8Xq/uO9ZYdED55KwJBALs6cJ65UFaq4oLJiQPzLd7yokuE\r\n' + - 'dcj8g71PLBTW6jPxIiMFNA89nz3FU9wIVp+xbMNhSoMMKqIPVPC+m0Rn260CQQDA\r\n' + - 'I83fWK/mZWUjBM33a68KumRiH238v8XyQxj7+C8i6D8G2GXvkigFAehAkb7LZZd+\r\n' + - 'KLuGFyPlWv3fVWHf99KpAkBQFKk3MRMl6IGJZUEFQe4l5whm8LkGU4acSqv9B3xt\r\n' + - 'qROkCrsFrMPqjuuzEmyHoQZ64r2PLJg7FOuyhBnQUOt4\r\n' + - '-----END RSA PRIVATE KEY-----\r\n', - publicKey: '-----BEGIN PUBLIC KEY-----\r\n' + - 'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDL0EugUiNGMWscLAVM0VoMdhDZ\r\n' + - 'EJOqdsUMpx9U0YZI7szokJqQNIwokiQ6EonNnWSMlIvy46AhnlRYn+ezeTeU7eMG\r\n' + - 'TkP3VF29vXBo+dLq5e+8VyAyQ3FzM1wI4ts4hRACF8w6mqygXQ7i/SDu8/rXqRGt\r\n' + - 'vnM+z0MYDdKo80efzwIDAQAB\r\n' + - '-----END PUBLIC KEY-----\r\n', - certificate: '-----BEGIN CERTIFICATE-----\r\n' + - 'MIIDIjCCAougAwIBAgIJANE2aHSbwpaRMA0GCSqGSIb3DQEBBQUAMGoxCzAJBgNV\r\n' + - 'BAYTAlVTMREwDwYDVQQIEwhWaXJnaW5pYTETMBEGA1UEBxMKQmxhY2tzYnVyZzEN\r\n' + - 'MAsGA1UEChMEVGVzdDENMAsGA1UECxMEVGVzdDEVMBMGA1UEAxMMbXlzZXJ2ZXIu\r\n' + - 'Y29tMB4XDTEwMDYxOTE3MzYyOFoXDTExMDYxOTE3MzYyOFowajELMAkGA1UEBhMC\r\n' + - 'VVMxETAPBgNVBAgTCFZpcmdpbmlhMRMwEQYDVQQHEwpCbGFja3NidXJnMQ0wCwYD\r\n' + - 'VQQKEwRUZXN0MQ0wCwYDVQQLEwRUZXN0MRUwEwYDVQQDEwxteXNlcnZlci5jb20w\r\n' + - 'gZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMvQS6BSI0YxaxwsBUzRWgx2ENkQ\r\n' + - 'k6p2xQynH1TRhkjuzOiQmpA0jCiSJDoSic2dZIyUi/LjoCGeVFif57N5N5Tt4wZO\r\n' + - 'Q/dUXb29cGj50url77xXIDJDcXMzXAji2ziFEAIXzDqarKBdDuL9IO7z+tepEa2+\r\n' + - 'cz7PQxgN0qjzR5/PAgMBAAGjgc8wgcwwHQYDVR0OBBYEFPV1Y+DHXW6bA/r9sv1y\r\n' + - 'NJ8jAwMAMIGcBgNVHSMEgZQwgZGAFPV1Y+DHXW6bA/r9sv1yNJ8jAwMAoW6kbDBq\r\n' + - 'MQswCQYDVQQGEwJVUzERMA8GA1UECBMIVmlyZ2luaWExEzARBgNVBAcTCkJsYWNr\r\n' + - 'c2J1cmcxDTALBgNVBAoTBFRlc3QxDTALBgNVBAsTBFRlc3QxFTATBgNVBAMTDG15\r\n' + - 'c2VydmVyLmNvbYIJANE2aHSbwpaRMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEF\r\n' + - 'BQADgYEARdH2KOlJWTC1CS2y/PAvg4uiM31PXMC1hqSdJlnLM1MY4hRfuf9VyTeX\r\n' + - 'Y6FdybcyDLSxKn9id+g9229ci9/s9PI+QmD5vXd8yZyScLc2JkYB4GC6+9D1+/+x\r\n' + - 's2hzMxuK6kzZlP+0l9LGcraMQPGRydjCARZZm4Uegln9rh85XFQ=\r\n' + - '-----END CERTIFICATE-----\r\n' - }; - - describe('x509', function() { - it('should convert certificate to/from PEM', function() { - var certificate = PKI.certificateFromPem(_pem.certificate); - ASSERT.equal(PKI.certificateToPem(certificate), _pem.certificate); - }); - - it('should verify self-signed certificate', function() { - var certificate = PKI.certificateFromPem(_pem.certificate); - ASSERT.ok(certificate.verify(certificate)); - }); - - it('should generate and verify a self-signed certificate', function() { - var keys = { - privateKey: PKI.privateKeyFromPem(_pem.privateKey), - publicKey: PKI.publicKeyFromPem(_pem.publicKey) - }; - var attrs = [{ - name: 'commonName', - value: 'example.org' - }, { - name: 'countryName', - value: 'US' - }, { - shortName: 'ST', - value: 'Virginia' - }, { - name: 'localityName', - value: 'Blacksburg' - }, { - name: 'organizationName', - value: 'Test' - }, { - shortName: 'OU', - value: 'Test' - }]; - var cert = createCertificate({ - publicKey: keys.publicKey, - signingKey: keys.privateKey, - serialNumber: '01', - subject: attrs, - issuer: attrs, - isCA: true - }); - - var pem = PKI.certificateToPem(cert); - cert = PKI.certificateFromPem(pem); - - // verify certificate chain - var caStore = PKI.createCaStore(); - caStore.addCertificate(cert); - PKI.verifyCertificateChain(caStore, [cert], function(vfd, depth, chain) { - ASSERT.equal(vfd, true); - ASSERT.ok(cert.verifySubjectKeyIdentifier()); - return true; - }); - }); - - it('should generate and fail to verify a self-signed certificate that is not in the CA store', function() { - var keys = { - privateKey: PKI.privateKeyFromPem(_pem.privateKey), - publicKey: PKI.publicKeyFromPem(_pem.publicKey) - }; - var attrs = [{ - name: 'commonName', - value: 'example.org' - }, { - name: 'countryName', - value: 'US' - }, { - shortName: 'ST', - value: 'Virginia' - }, { - name: 'localityName', - value: 'Blacksburg' - }, { - name: 'organizationName', - value: 'Test' - }, { - shortName: 'OU', - value: 'Test' - }]; - var cert = createCertificate({ - publicKey: keys.publicKey, - signingKey: keys.privateKey, - serialNumber: '01', - subject: attrs, - issuer: attrs, - isCA: true - }); - - var pem = PKI.certificateToPem(cert); - cert = PKI.certificateFromPem(pem); - - // verify certificate chain - var caStore = PKI.createCaStore(); - PKI.verifyCertificateChain(caStore, [cert], function(vfd, depth, chain) { - ASSERT.equal(vfd, PKI.certificateError.unknown_ca); - return true; - }); - }); - - it('should verify certificate chain ending with intermediate certificate from CA store', function() { - var keys = { - privateKey: PKI.privateKeyFromPem(_pem.privateKey), - publicKey: PKI.publicKeyFromPem(_pem.publicKey) - }; - var entity = [{ - name: 'commonName', - value: 'example.org' - }, { - name: 'countryName', - value: 'US' - }, { - shortName: 'ST', - value: 'Virginia' - }, { - name: 'localityName', - value: 'Blacksburg' - }, { - name: 'organizationName', - value: 'Test' - }, { - shortName: 'OU', - value: 'Test' - }]; - var intermediate = [{ - name: 'commonName', - value: 'intermediate' - }, { - name: 'countryName', - value: 'US' - }, { - shortName: 'ST', - value: 'Virginia' - }, { - name: 'localityName', - value: 'Blacksburg' - }, { - name: 'organizationName', - value: 'Test' - }, { - shortName: 'OU', - value: 'Test' - }]; - var root = [{ - name: 'commonName', - value: 'root' - }, { - name: 'countryName', - value: 'US' - }, { - shortName: 'ST', - value: 'Virginia' - }, { - name: 'localityName', - value: 'Blacksburg' - }, { - name: 'organizationName', - value: 'Test' - }, { - shortName: 'OU', - value: 'Test' - }]; - - var intermediateCert = createCertificate({ - publicKey: keys.publicKey, - signingKey: keys.privateKey, - serialNumber: '01', - subject: intermediate, - issuer: root, - isCA: true - }); - - var entityCert = createCertificate({ - publicKey: keys.publicKey, - signingKey: keys.privateKey, - serialNumber: '01', - subject: entity, - issuer: intermediate, - isCA: false - }); - - // verify certificate chain - var caStore = PKI.createCaStore(); - caStore.addCertificate(intermediateCert); - var chain = [entityCert, intermediateCert]; - PKI.verifyCertificateChain(caStore, chain, function(vfd, depth, chain) { - ASSERT.equal(vfd, true); - return true; - }); - }); - - it('should fail to verify certificate chain ending with non-CA intermediate certificate from CA store', function() { - var keys = { - privateKey: PKI.privateKeyFromPem(_pem.privateKey), - publicKey: PKI.publicKeyFromPem(_pem.publicKey) - }; - var entity = [{ - name: 'commonName', - value: 'example.org' - }, { - name: 'countryName', - value: 'US' - }, { - shortName: 'ST', - value: 'Virginia' - }, { - name: 'localityName', - value: 'Blacksburg' - }, { - name: 'organizationName', - value: 'Test' - }, { - shortName: 'OU', - value: 'Test' - }]; - var intermediate = [{ - name: 'commonName', - value: 'intermediate' - }, { - name: 'countryName', - value: 'US' - }, { - shortName: 'ST', - value: 'Virginia' - }, { - name: 'localityName', - value: 'Blacksburg' - }, { - name: 'organizationName', - value: 'Test' - }, { - shortName: 'OU', - value: 'Test' - }]; - var root = [{ - name: 'commonName', - value: 'root' - }, { - name: 'countryName', - value: 'US' - }, { - shortName: 'ST', - value: 'Virginia' - }, { - name: 'localityName', - value: 'Blacksburg' - }, { - name: 'organizationName', - value: 'Test' - }, { - shortName: 'OU', - value: 'Test' - }]; - - var intermediateCert = createCertificate({ - publicKey: keys.publicKey, - signingKey: keys.privateKey, - serialNumber: '01', - subject: intermediate, - issuer: root, - isCA: false - }); - - var entityCert = createCertificate({ - publicKey: keys.publicKey, - signingKey: keys.privateKey, - serialNumber: '01', - subject: entity, - issuer: intermediate, - isCA: false - }); - - // verify certificate chain - var caStore = PKI.createCaStore(); - caStore.addCertificate(intermediateCert); - var chain = [entityCert, intermediateCert]; - PKI.verifyCertificateChain(caStore, chain, function(vfd, depth, chain) { - if(depth === 0) { - ASSERT.equal(vfd, true); - } else { - ASSERT.equal(vfd, PKI.certificateError.bad_certificate); - } - return true; - }); - }); - - it('should verify certificate with sha1WithRSAEncryption signature', function() { - var certPem = '-----BEGIN CERTIFICATE-----\r\n' + - 'MIIDZDCCAs2gAwIBAgIKQ8fjjgAAAABh3jANBgkqhkiG9w0BAQUFADBGMQswCQYD\r\n' + - 'VQQGEwJVUzETMBEGA1UEChMKR29vZ2xlIEluYzEiMCAGA1UEAxMZR29vZ2xlIElu\r\n' + - 'dGVybmV0IEF1dGhvcml0eTAeFw0xMjA2MjcxMzU5MTZaFw0xMzA2MDcxOTQzMjda\r\n' + - 'MGcxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1N\r\n' + - 'b3VudGFpbiBWaWV3MRMwEQYDVQQKEwpHb29nbGUgSW5jMRYwFAYDVQQDEw13d3cu\r\n' + - 'Z29vZ2xlLmRlMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCw2Hw3vNy5QMSd\r\n' + - '0/iMCS8lwZk9lnEk2NmrJt6vGJfRGlBprtHp5lpMFMoi+x8m8EwGVxXHGp7hLyN/\r\n' + - 'gXuUjL7/DY9fxxx9l77D+sDZz7jfUfWmhS03Ra1FbT6myF8miVZFChJ8XgWzioJY\r\n' + - 'gyNdRUC9149yrXdPWrSmSVaT0+tUCwIDAQABo4IBNjCCATIwHQYDVR0lBBYwFAYI\r\n' + - 'KwYBBQUHAwEGCCsGAQUFBwMCMB0GA1UdDgQWBBTiQGhrO3785rMPIKZ/zQEl5RyS\r\n' + - '0TAfBgNVHSMEGDAWgBS/wDDr9UMRPme6npH7/Gra42sSJDBbBgNVHR8EVDBSMFCg\r\n' + - 'TqBMhkpodHRwOi8vd3d3LmdzdGF0aWMuY29tL0dvb2dsZUludGVybmV0QXV0aG9y\r\n' + - 'aXR5L0dvb2dsZUludGVybmV0QXV0aG9yaXR5LmNybDBmBggrBgEFBQcBAQRaMFgw\r\n' + - 'VgYIKwYBBQUHMAKGSmh0dHA6Ly93d3cuZ3N0YXRpYy5jb20vR29vZ2xlSW50ZXJu\r\n' + - 'ZXRBdXRob3JpdHkvR29vZ2xlSW50ZXJuZXRBdXRob3JpdHkuY3J0MAwGA1UdEwEB\r\n' + - '/wQCMAAwDQYJKoZIhvcNAQEFBQADgYEAVJ0qt/MBvHEPuWHeH51756qy+lBNygLA\r\n' + - 'Xp5Gq+xHUTOzRty61BR05zv142hYAGWvpvnEOJ/DI7V3QlXK8a6dQ+du97obQJJx\r\n' + - '7ekqtfxVzmlSb23halYSoXmWgP8Tq0VUDsgsSLE7fS8JuO1soXUVKj1/6w189HL6\r\n' + - 'LsngXwZSuL0=\r\n' + - '-----END CERTIFICATE-----\r\n'; - var issuerPem = '-----BEGIN CERTIFICATE-----\r\n' + - 'MIICsDCCAhmgAwIBAgIDC2dxMA0GCSqGSIb3DQEBBQUAME4xCzAJBgNVBAYTAlVT\r\n' + - 'MRAwDgYDVQQKEwdFcXVpZmF4MS0wKwYDVQQLEyRFcXVpZmF4IFNlY3VyZSBDZXJ0\r\n' + - 'aWZpY2F0ZSBBdXRob3JpdHkwHhcNMDkwNjA4MjA0MzI3WhcNMTMwNjA3MTk0MzI3\r\n' + - 'WjBGMQswCQYDVQQGEwJVUzETMBEGA1UEChMKR29vZ2xlIEluYzEiMCAGA1UEAxMZ\r\n' + - 'R29vZ2xlIEludGVybmV0IEF1dGhvcml0eTCBnzANBgkqhkiG9w0BAQEFAAOBjQAw\r\n' + - 'gYkCgYEAye23pIucV+eEPkB9hPSP0XFjU5nneXQUr0SZMyCSjXvlKAy6rWxJfoNf\r\n' + - 'NFlOCnowzdDXxFdF7dWq1nMmzq0yE7jXDx07393cCDaob1FEm8rWIFJztyaHNWrb\r\n' + - 'qeXUWaUr/GcZOfqTGBhs3t0lig4zFEfC7wFQeeT9adGnwKziV28CAwEAAaOBozCB\r\n' + - 'oDAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFL/AMOv1QxE+Z7qekfv8atrjaxIk\r\n' + - 'MB8GA1UdIwQYMBaAFEjmaPkr0rKV10fYIyAQTzOYkJ/UMBIGA1UdEwEB/wQIMAYB\r\n' + - 'Af8CAQAwOgYDVR0fBDMwMTAvoC2gK4YpaHR0cDovL2NybC5nZW90cnVzdC5jb20v\r\n' + - 'Y3Jscy9zZWN1cmVjYS5jcmwwDQYJKoZIhvcNAQEFBQADgYEAuIojxkiWsRF8YHde\r\n' + - 'BZqrocb6ghwYB8TrgbCoZutJqOkM0ymt9e8kTP3kS8p/XmOrmSfLnzYhLLkQYGfN\r\n' + - '0rTw8Ktx5YtaiScRhKqOv5nwnQkhClIZmloJ0pC3+gz4fniisIWvXEyZ2VxVKfml\r\n' + - 'UUIuOss4jHg7y/j7lYe8vJD5UDI=\r\n' + - '-----END CERTIFICATE-----\r\n'; - var cert = PKI.certificateFromPem(certPem, true); - var issuer = PKI.certificateFromPem(issuerPem); - ASSERT.ok(issuer.verify(cert)); - }); - - it('should verify certificate with sha256WithRSAEncryption signature', function() { - var certPem = '-----BEGIN CERTIFICATE-----\r\n' + - 'MIIDuzCCAqOgAwIBAgIEO5vZjDANBgkqhkiG9w0BAQsFADBGMQswCQYDVQQGEwJE\r\n' + - 'RTEPMA0GA1UEChMGRWxzdGVyMQswCQYDVQQLEwJDQTEZMBcGA1UEAxMQRWxzdGVy\r\n' + - 'U29mdFRlc3RDQTAeFw0xMDA5MTUwNTM4MjRaFw0xMzA5MTUwNTM4MjRaMCsxFDAS\r\n' + - 'BgNVBAUTCzEwMDIzMTQ5OTRDMRMwEQYDVQQDEwoxMDAyMzE0OTk0MIGfMA0GCSqG\r\n' + - 'SIb3DQEBAQUAA4GNADCBiQKBgQCLPqjbwjsugzw6+qwwm/pdzDwk7ASIsBYJ17GT\r\n' + - 'qyT0zCnYmdDDGWsYc+xxFVVIi8xBt6Mlq8Rwj+02UJhY9qm6zRA9MqFZC3ih+HoW\r\n' + - 'xq7H8N2d10N0rX6h5PSjkF5fU5ugncZmppsRGJ9DNXgwjpf/CsH2rqThUzK4xfrq\r\n' + - 'jpDS/wIDAQABo4IBTjCCAUowDgYDVR0PAQH/BAQDAgUgMAwGA1UdEwEB/wQCMAAw\r\n' + - 'HQYDVR0OBBYEFF1h7H37OQivS57GD8+nK6VsgMPTMIGXBgNVHR8EgY8wgYwwgYmg\r\n' + - 'gYaggYOGgYBsZGFwOi8vMTkyLjE2OC42LjI0OjM4OS9sJTNkQ0ElMjBaZXJ0aWZp\r\n' + - 'a2F0ZSxvdSUzZENBLGNuJTNkRWxzdGVyU29mdFRlc3RDQSxkYyUzZHdpZXNlbCxk\r\n' + - 'YyUzZGVsc3RlcixkYyUzZGRlPz9iYXNlPyhvYmplY3RDbGFzcz0qKTBxBgNVHSME\r\n' + - 'ajBogBRBILMYmlZu//pj3wjDe2UPkq7jk6FKpEgwRjELMAkGA1UEBhMCREUxDzAN\r\n' + - 'BgNVBAoTBkVsc3RlcjEPMA0GA1UECxMGUm9vdENBMRUwEwYDVQQDEwxFbHN0ZXJS\r\n' + - 'b290Q0GCBDuayikwDQYJKoZIhvcNAQELBQADggEBAK8Z1+/VNyU5w/EiyhFH5aRE\r\n' + - 'Mzxo0DahqKEm4pW5haBgKubJwZGs+CrBZR70TPbZGgJd36eyMgeXb/06lBnxewii\r\n' + - 'I/aY6wMTviQTpqFnz5m0Le8UhH+hY1bqNG/vf6J+1gbOSrZyhAUV+MDJbL/OkzX4\r\n' + - 'voVAfUBqSODod0f5wCW2RhvBmB9E62baP6qizdxyPA4iV16H4C0etd/7coLX6NZC\r\n' + - 'oz3Yu0IRTQCH+YrpfIbxGb0grNhtCTfFpa287fuzu8mIEvLNr8GibhBXmQg7iJ+y\r\n' + - 'q0VIyZLY8k6jEPrUB5Iv5ouSR19Dda/2+xJPlT/bosuNcErEuk/yKAHWAzwm1wQ=\r\n' + - '-----END CERTIFICATE-----\r\n'; - var issuerPem = '-----BEGIN CERTIFICATE-----\r\n' + - 'MIIESjCCAzKgAwIBAgIEO5rKKTANBgkqhkiG9w0BAQsFADBGMQswCQYDVQQGEwJE\r\n' + - 'RTEPMA0GA1UEChMGRWxzdGVyMQ8wDQYDVQQLEwZSb290Q0ExFTATBgNVBAMTDEVs\r\n' + - 'c3RlclJvb3RDQTAeFw0wOTA3MjgwODE5MTFaFw0xNDA3MjgwODE5MTFaMEYxCzAJ\r\n' + - 'BgNVBAYTAkRFMQ8wDQYDVQQKEwZFbHN0ZXIxCzAJBgNVBAsTAkNBMRkwFwYDVQQD\r\n' + - 'ExBFbHN0ZXJTb2Z0VGVzdENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC\r\n' + - 'AQEAv5uoKLnxXQe75iqwqgyt3H6MDAx/wvUVs26+2+yHpEUb/2gA3L8E+NChSb9E\r\n' + - 'aNgxxoac3Yhvxzq2mPpih3vkY7Xw512Tm8l/OPbT8kbmBJmYZneFALXHytAIZiEf\r\n' + - 'e0ZYNKAlClFIgNP5bE9UjTqVEEoSiUhpTubM6c5xEYVznnwPBoYQ0ari7RTDYnME\r\n' + - 'HK4vMfoeBeWHYPiEygNHnGUG8d3merRC/lQASUtL6ikmLWKCKHfyit5ACzPNKAtw\r\n' + - 'IzHAzD5ek0BpcUTci8hUsKz2ZvmoZcjPyj63veQuMYS5cTMgr3bfz9uz1xuoEDsb\r\n' + - 'Sv9rQX9Iw3N7yMpxTDJTqGKhYwIDAQABo4IBPjCCATowDgYDVR0PAQH/BAQDAgEG\r\n' + - 'MBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFEEgsxiaVm7/+mPfCMN7ZQ+S\r\n' + - 'ruOTMIGXBgNVHR8EgY8wgYwwgYmggYaggYOGgYBsZGFwOi8vMTkyLjE2OC42LjI0\r\n' + - 'OjM4OS9sJTNkQ0ElMjBaZXJ0aWZpa2F0ZSxvdSUzZFJvb3RDQSxjbiUzZEVsc3Rl\r\n' + - 'clJvb3RDQSxkYyUzZHdpZXNlbCxkYyUzZGVsc3RlcixkYyUzZGRlPz9iYXNlPyhv\r\n' + - 'YmplY3RDbGFzcz0qKTBbBgNVHSMEVDBSoUqkSDBGMQswCQYDVQQGEwJERTEPMA0G\r\n' + - 'A1UEChMGRWxzdGVyMQ8wDQYDVQQLEwZSb290Q0ExFTATBgNVBAMTDEVsc3RlclJv\r\n' + - 'b3RDQYIEO5rKADANBgkqhkiG9w0BAQsFAAOCAQEAFauDnfHSbgRmbFkpQUXM5wKi\r\n' + - 'K5STAaVps201iAjacX5EsOs5L37VUMoT9G2DAE8Z6B1pIiR3zcd3UpiHnFlUTC0f\r\n' + - 'ZdOCXzDkOfziKY/RzuUsLNFUhBizCIA0+XcKgm3dSA5ex8fChLJddSYheSLuPua7\r\n' + - 'iNMuzaU2YnevbMwpdEsl55Qr/uzcc0YM/mCuM4vsNFyFml91SQyPPmdR3VvGOoGl\r\n' + - 'qS1R0HSoPJUvr0N0kARwD7kO3ikcJ6FxBCsgVLZHGJC+q8PQNZmVMbfgjH4nAyP8\r\n' + - 'u7Qe03v2WLW0UgKu2g0UcQXWXbovktpZoK0fUOwv3bqsZ0K1IjVvMKG8OysUvA==\r\n' + - '-----END CERTIFICATE-----\r\n'; - var cert = PKI.certificateFromPem(certPem, true); - var issuer = PKI.certificateFromPem(issuerPem); - ASSERT.ok(issuer.verify(cert)); - }); - - it('should import certificate with sha256 RSASSA-PSS signature', function() { - var certPem = '-----BEGIN CERTIFICATE-----\r\n' + - 'MIIERzCCAvugAwIBAgIEO50CcjBBBgkqhkiG9w0BAQowNKAPMA0GCWCGSAFlAwQC\r\n' + - 'AQUAoRwwGgYJKoZIhvcNAQEIMA0GCWCGSAFlAwQCAQUAogMCASAwRjELMAkGA1UE\r\n' + - 'BhMCREUxDzANBgNVBAoTBkVsc3RlcjELMAkGA1UECxMCQ0ExGTAXBgNVBAMTEEVs\r\n' + - 'c3RlclNvZnRUZXN0Q0EwHhcNMTEwNzI4MTIxMzU3WhcNMTQwNzI4MTIxMzU3WjAr\r\n' + - 'MRQwEgYDVQQFEwsxMDAyNzUzMzI1QzETMBEGA1UEAxMKMTAwMjc1MzMyNTCCASIw\r\n' + - 'DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALHCogo7LVUkxWsMIc/0jgH2PCLt\r\n' + - 'ukbATPehxWBG1XUPrz53lWgFJzlZaKLlLVVnXrfULaifuOKlZP6SM1JQlL1JuYgY\r\n' + - 'AdgZyHjderNIk5NsSTmefwonSn/ukri5IRTH420oHtSjxk6+/DXlWnQy5OzTN6Bq\r\n' + - 'jVJo8L+TTmf2jWuEam5cWa+YVP2k3tIqX5yMUDFjKO4znHdtIkHnBE0Kx03rWQRB\r\n' + - 'TSYWDgDm2gttdOs9JVeuW0nnwQj27uo9gOR0iyaUjVrKLZ95p6zpXhM4uMSVRNeo\r\n' + - 'LqkdqP2n+4pDXZVqLNgjkHQUS/xq9Q/kYgT2J7wkGfYxP9to7TG7vra1eOECAwEA\r\n' + - 'AaOB7zCB7DAOBgNVHQ8BAf8EBAMCBSAwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQU\r\n' + - 'NDJ2BZIk6ukLqkdmttH12bu2leswOgYDVR0fBDMwMTAvoC2gK4YpaHR0cDovL2Ny\r\n' + - 'bC5lbHN0ZXIuZGUvRWxzdGVyU29mdFRlc3RDQS5jcmwwcQYDVR0jBGowaIAU1R9A\r\n' + - 'HmpdzaxK3v+ihQsEpAFgzOKhSqRIMEYxCzAJBgNVBAYTAkRFMQ8wDQYDVQQKEwZF\r\n' + - 'bHN0ZXIxDzANBgNVBAsTBlJvb3RDQTEVMBMGA1UEAxMMRWxzdGVyUm9vdENBggQ7\r\n' + - 'msqPMEEGCSqGSIb3DQEBCjA0oA8wDQYJYIZIAWUDBAIBBQChHDAaBgkqhkiG9w0B\r\n' + - 'AQgwDQYJYIZIAWUDBAIBBQCiAwIBIAOCAQEAJBYNRZpe+z3yPPLV539Yci6OfjVg\r\n' + - 'vs1e3rvSvcpFaqRJ8vZ8WNx3uuRQZ6B4Z3YEc00UJAOl3wU6KhamyryK2YvCrPg+\r\n' + - 'TS5QDXNaO2z/rAnY1wWSlwBPlhqpMRrNv9cRXBcgK5YxprjytCVYN0UHdintgYxG\r\n' + - 'fg7QYiFb00UXxAza1AFrpG+RqySFfO1scmu4kgpeb6A3USnQ0r6rZz6dt6NqgZZ6\r\n' + - 'oUpDOCvnS9XSOWuvJirV8hIU0KAagguTbwfTqt9nt0wDlwZpemsJZ4Vvnvy8d9Jf\r\n' + - 'zA68EWHbZLr2QP9hb3sHCWJgplMsTJnUwRfi2hf5KNtP8Xg5DSLMfTEbhw==\r\n' + - '-----END CERTIFICATE-----\r\n'; - var cert = PKI.certificateFromPem(certPem, true); - - ASSERT.equal(cert.signatureOid, PKI.oids['RSASSA-PSS']); - ASSERT.equal(cert.signatureParameters.hash.algorithmOid, PKI.oids['sha256']); - ASSERT.equal(cert.signatureParameters.mgf.algorithmOid, PKI.oids['mgf1']); - ASSERT.equal(cert.signatureParameters.mgf.hash.algorithmOid, PKI.oids['sha256']); - ASSERT.equal(cert.siginfo.algorithmOid, PKI.oids['RSASSA-PSS']); - ASSERT.equal(cert.siginfo.parameters.hash.algorithmOid, PKI.oids['sha256']); - ASSERT.equal(cert.siginfo.parameters.mgf.algorithmOid, PKI.oids['mgf1']); - ASSERT.equal(cert.siginfo.parameters.mgf.hash.algorithmOid, PKI.oids['sha256']); - }); - - it('should export certificate with sha256 RSASSA-PSS signature', function() { - var certPem = '-----BEGIN CERTIFICATE-----\r\n' + - 'MIIERzCCAvugAwIBAgIEO50CcjBBBgkqhkiG9w0BAQowNKAPMA0GCWCGSAFlAwQC\r\n' + - 'AQUAoRwwGgYJKoZIhvcNAQEIMA0GCWCGSAFlAwQCAQUAogMCASAwRjELMAkGA1UE\r\n' + - 'BhMCREUxDzANBgNVBAoTBkVsc3RlcjELMAkGA1UECxMCQ0ExGTAXBgNVBAMTEEVs\r\n' + - 'c3RlclNvZnRUZXN0Q0EwHhcNMTEwNzI4MTIxMzU3WhcNMTQwNzI4MTIxMzU3WjAr\r\n' + - 'MRQwEgYDVQQFEwsxMDAyNzUzMzI1QzETMBEGA1UEAxMKMTAwMjc1MzMyNTCCASIw\r\n' + - 'DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALHCogo7LVUkxWsMIc/0jgH2PCLt\r\n' + - 'ukbATPehxWBG1XUPrz53lWgFJzlZaKLlLVVnXrfULaifuOKlZP6SM1JQlL1JuYgY\r\n' + - 'AdgZyHjderNIk5NsSTmefwonSn/ukri5IRTH420oHtSjxk6+/DXlWnQy5OzTN6Bq\r\n' + - 'jVJo8L+TTmf2jWuEam5cWa+YVP2k3tIqX5yMUDFjKO4znHdtIkHnBE0Kx03rWQRB\r\n' + - 'TSYWDgDm2gttdOs9JVeuW0nnwQj27uo9gOR0iyaUjVrKLZ95p6zpXhM4uMSVRNeo\r\n' + - 'LqkdqP2n+4pDXZVqLNgjkHQUS/xq9Q/kYgT2J7wkGfYxP9to7TG7vra1eOECAwEA\r\n' + - 'AaOB7zCB7DAOBgNVHQ8BAf8EBAMCBSAwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQU\r\n' + - 'NDJ2BZIk6ukLqkdmttH12bu2leswOgYDVR0fBDMwMTAvoC2gK4YpaHR0cDovL2Ny\r\n' + - 'bC5lbHN0ZXIuZGUvRWxzdGVyU29mdFRlc3RDQS5jcmwwcQYDVR0jBGowaIAU1R9A\r\n' + - 'HmpdzaxK3v+ihQsEpAFgzOKhSqRIMEYxCzAJBgNVBAYTAkRFMQ8wDQYDVQQKEwZF\r\n' + - 'bHN0ZXIxDzANBgNVBAsTBlJvb3RDQTEVMBMGA1UEAxMMRWxzdGVyUm9vdENBggQ7\r\n' + - 'msqPMEEGCSqGSIb3DQEBCjA0oA8wDQYJYIZIAWUDBAIBBQChHDAaBgkqhkiG9w0B\r\n' + - 'AQgwDQYJYIZIAWUDBAIBBQCiAwIBIAOCAQEAJBYNRZpe+z3yPPLV539Yci6OfjVg\r\n' + - 'vs1e3rvSvcpFaqRJ8vZ8WNx3uuRQZ6B4Z3YEc00UJAOl3wU6KhamyryK2YvCrPg+\r\n' + - 'TS5QDXNaO2z/rAnY1wWSlwBPlhqpMRrNv9cRXBcgK5YxprjytCVYN0UHdintgYxG\r\n' + - 'fg7QYiFb00UXxAza1AFrpG+RqySFfO1scmu4kgpeb6A3USnQ0r6rZz6dt6NqgZZ6\r\n' + - 'oUpDOCvnS9XSOWuvJirV8hIU0KAagguTbwfTqt9nt0wDlwZpemsJZ4Vvnvy8d9Jf\r\n' + - 'zA68EWHbZLr2QP9hb3sHCWJgplMsTJnUwRfi2hf5KNtP8Xg5DSLMfTEbhw==\r\n' + - '-----END CERTIFICATE-----\r\n'; - var cert = PKI.certificateFromPem(certPem, true); - ASSERT.equal(PKI.certificateToPem(cert), certPem); - }); - - it('should verify certificate with sha256 RSASSA-PSS signature', function() { - var certPem = '-----BEGIN CERTIFICATE-----\r\n' + - 'MIIERzCCAvugAwIBAgIEO50CcjBBBgkqhkiG9w0BAQowNKAPMA0GCWCGSAFlAwQC\r\n' + - 'AQUAoRwwGgYJKoZIhvcNAQEIMA0GCWCGSAFlAwQCAQUAogMCASAwRjELMAkGA1UE\r\n' + - 'BhMCREUxDzANBgNVBAoTBkVsc3RlcjELMAkGA1UECxMCQ0ExGTAXBgNVBAMTEEVs\r\n' + - 'c3RlclNvZnRUZXN0Q0EwHhcNMTEwNzI4MTIxMzU3WhcNMTQwNzI4MTIxMzU3WjAr\r\n' + - 'MRQwEgYDVQQFEwsxMDAyNzUzMzI1QzETMBEGA1UEAxMKMTAwMjc1MzMyNTCCASIw\r\n' + - 'DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALHCogo7LVUkxWsMIc/0jgH2PCLt\r\n' + - 'ukbATPehxWBG1XUPrz53lWgFJzlZaKLlLVVnXrfULaifuOKlZP6SM1JQlL1JuYgY\r\n' + - 'AdgZyHjderNIk5NsSTmefwonSn/ukri5IRTH420oHtSjxk6+/DXlWnQy5OzTN6Bq\r\n' + - 'jVJo8L+TTmf2jWuEam5cWa+YVP2k3tIqX5yMUDFjKO4znHdtIkHnBE0Kx03rWQRB\r\n' + - 'TSYWDgDm2gttdOs9JVeuW0nnwQj27uo9gOR0iyaUjVrKLZ95p6zpXhM4uMSVRNeo\r\n' + - 'LqkdqP2n+4pDXZVqLNgjkHQUS/xq9Q/kYgT2J7wkGfYxP9to7TG7vra1eOECAwEA\r\n' + - 'AaOB7zCB7DAOBgNVHQ8BAf8EBAMCBSAwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQU\r\n' + - 'NDJ2BZIk6ukLqkdmttH12bu2leswOgYDVR0fBDMwMTAvoC2gK4YpaHR0cDovL2Ny\r\n' + - 'bC5lbHN0ZXIuZGUvRWxzdGVyU29mdFRlc3RDQS5jcmwwcQYDVR0jBGowaIAU1R9A\r\n' + - 'HmpdzaxK3v+ihQsEpAFgzOKhSqRIMEYxCzAJBgNVBAYTAkRFMQ8wDQYDVQQKEwZF\r\n' + - 'bHN0ZXIxDzANBgNVBAsTBlJvb3RDQTEVMBMGA1UEAxMMRWxzdGVyUm9vdENBggQ7\r\n' + - 'msqPMEEGCSqGSIb3DQEBCjA0oA8wDQYJYIZIAWUDBAIBBQChHDAaBgkqhkiG9w0B\r\n' + - 'AQgwDQYJYIZIAWUDBAIBBQCiAwIBIAOCAQEAJBYNRZpe+z3yPPLV539Yci6OfjVg\r\n' + - 'vs1e3rvSvcpFaqRJ8vZ8WNx3uuRQZ6B4Z3YEc00UJAOl3wU6KhamyryK2YvCrPg+\r\n' + - 'TS5QDXNaO2z/rAnY1wWSlwBPlhqpMRrNv9cRXBcgK5YxprjytCVYN0UHdintgYxG\r\n' + - 'fg7QYiFb00UXxAza1AFrpG+RqySFfO1scmu4kgpeb6A3USnQ0r6rZz6dt6NqgZZ6\r\n' + - 'oUpDOCvnS9XSOWuvJirV8hIU0KAagguTbwfTqt9nt0wDlwZpemsJZ4Vvnvy8d9Jf\r\n' + - 'zA68EWHbZLr2QP9hb3sHCWJgplMsTJnUwRfi2hf5KNtP8Xg5DSLMfTEbhw==\r\n' + - '-----END CERTIFICATE-----\r\n'; - var issuerPem = '-----BEGIN CERTIFICATE-----\r\n' + - 'MIIEZDCCAxigAwIBAgIEO5rKjzBBBgkqhkiG9w0BAQowNKAPMA0GCWCGSAFlAwQC\r\n' + - 'AQUAoRwwGgYJKoZIhvcNAQEIMA0GCWCGSAFlAwQCAQUAogMCASAwRjELMAkGA1UE\r\n' + - 'BhMCREUxDzANBgNVBAoTBkVsc3RlcjEPMA0GA1UECxMGUm9vdENBMRUwEwYDVQQD\r\n' + - 'EwxFbHN0ZXJSb290Q0EwHhcNMTEwNzI4MTExNzI4WhcNMTYwNzI4MTExNzI4WjBG\r\n' + - 'MQswCQYDVQQGEwJERTEPMA0GA1UEChMGRWxzdGVyMQswCQYDVQQLEwJDQTEZMBcG\r\n' + - 'A1UEAxMQRWxzdGVyU29mdFRlc3RDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC\r\n' + - 'AQoCggEBAMFpz3sXnXq4ZUBdYdpG5DJVfITLXYwXPfEJzr1pLRfJ2eMPn7k3B/2g\r\n' + - 'bvuH30zKmDRjlfV51sFw4l1l+cQugzy5FEOrfE6g7IvhpBUf9SQujVWtE3BoSRR5\r\n' + - 'pSGbIWC7sm2SG0drpoCRpL0xmWZlAUS5mz7hBecJC/kKkKeOxUg5h492XQgWd0ow\r\n' + - '6GlyQBxJCmxgQBMnLS0stecs234hR5gvTHic50Ey+gRMPsTyco2Fm0FqvXtBuOsj\r\n' + - 'zAW7Nk2hnM6awFHVMDBLm+ClE1ww0dLW0ujkdoGsTEbvmM/w8MBI6WAiWaanjK/x\r\n' + - 'lStmQeUVXKd+AfuzT/FIPrwANcC1qGUCAwEAAaOB8TCB7jAOBgNVHQ8BAf8EBAMC\r\n' + - 'AQYwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQU1R9AHmpdzaxK3v+ihQsE\r\n' + - 'pAFgzOIwNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL2NybC5lbHN0ZXIuZGUvRWxz\r\n' + - 'dGVyUm9vdENBLmNybDBxBgNVHSMEajBogBS3zfTokckL2H/fTojW02K+metEcaFK\r\n' + - 'pEgwRjELMAkGA1UEBhMCREUxDzANBgNVBAoTBkVsc3RlcjEPMA0GA1UECxMGUm9v\r\n' + - 'dENBMRUwEwYDVQQDEwxFbHN0ZXJSb290Q0GCBDuaylowQQYJKoZIhvcNAQEKMDSg\r\n' + - 'DzANBglghkgBZQMEAgEFAKEcMBoGCSqGSIb3DQEBCDANBglghkgBZQMEAgEFAKID\r\n' + - 'AgEgA4IBAQBjT107fBmSfQNUYCpXIlaS/pogPoCahuC1g8QDtq6IEVXoEgXCzfVN\r\n' + - 'JYHyYOQOraP4O2LEcXpo/oc0MMpVF06QLKG/KieUE0mrZnsCJ3GLSJkM8tI8bRHj\r\n' + - '8tAhlViMacUqnKKufCs/rIN25JB57+sCyFqjtRbSt88e+xqFJ5I79Btp/bNtoj2G\r\n' + - 'OJGl997EPua9/yJuvdA9W67WO/KwEh+FqylB1pAapccOHqttwu4QJIc/XJfG5rrf\r\n' + - '8QZz8HIuOcroA4zIrprQ1nJRCuMII04ueDtBVz1eIEmqNEUkr09JdK8M0LKH0lMK\r\n' + - 'Ysgjai/P2mPVVwhVw6dHzUVRLXh3xIQr\r\n' + - '-----END CERTIFICATE-----\r\n'; - var cert = PKI.certificateFromPem(certPem, true); - var issuer = PKI.certificateFromPem(issuerPem); - ASSERT.ok(issuer.verify(cert)); - }); - }); - - describe('public key fingerprints', function() { - it('should get a SHA-1 RSAPublicKey fingerprint', function() { - var publicKey = PKI.publicKeyFromPem(_pem.publicKey); - var fp = PKI.getPublicKeyFingerprint(publicKey, {type: 'RSAPublicKey'}); - ASSERT.equal(fp.toHex(), 'f57563e0c75d6e9b03fafdb2fd72349f23030300'); - }); - - it('should get a SHA-1 SubjectPublicKeyInfo fingerprint', function() { - var publicKey = PKI.publicKeyFromPem(_pem.publicKey); - var fp = PKI.getPublicKeyFingerprint( - publicKey, {type: 'SubjectPublicKeyInfo'}); - ASSERT.equal(fp.toHex(), '984724bc548bbc2c8acbac044bd8d518abd26dd8'); - }); - - it('should get a hex SHA-1 RSAPublicKey fingerprint', function() { - var publicKey = PKI.publicKeyFromPem(_pem.publicKey); - var fp = PKI.getPublicKeyFingerprint( - publicKey, {type: 'RSAPublicKey', encoding: 'hex'}); - ASSERT.equal(fp, 'f57563e0c75d6e9b03fafdb2fd72349f23030300'); - }); - - it('should get a hex, colon-delimited SHA-1 RSAPublicKey fingerprint', function() { - var publicKey = PKI.publicKeyFromPem(_pem.publicKey); - var fp = PKI.getPublicKeyFingerprint( - publicKey, {type: 'RSAPublicKey', encoding: 'hex', delimiter: ':'}); - ASSERT.equal( - fp, 'f5:75:63:e0:c7:5d:6e:9b:03:fa:fd:b2:fd:72:34:9f:23:03:03:00'); - }); - - it('should get a hex, colon-delimited SHA-1 SubjectPublicKeyInfo fingerprint', function() { - var publicKey = PKI.publicKeyFromPem(_pem.publicKey); - var fp = PKI.getPublicKeyFingerprint( - publicKey, { - type: 'SubjectPublicKeyInfo', - encoding: 'hex', - delimiter: ':' - }); - ASSERT.equal( - fp, '98:47:24:bc:54:8b:bc:2c:8a:cb:ac:04:4b:d8:d5:18:ab:d2:6d:d8'); - }); - - it('should get an MD5 RSAPublicKey fingerprint', function() { - var publicKey = PKI.publicKeyFromPem(_pem.publicKey); - var fp = PKI.getPublicKeyFingerprint( - publicKey, {md: MD.md5.create(), type: 'RSAPublicKey'}); - ASSERT.equal(fp.toHex(), 'c7da180cc48d31a071d31a78bc43d9d7'); - }); - - it('should get an MD5 SubjectPublicKeyInfo fingerprint', function() { - var publicKey = PKI.publicKeyFromPem(_pem.publicKey); - var fp = PKI.getPublicKeyFingerprint( - publicKey, {md: MD.md5.create(), type: 'SubjectPublicKeyInfo'}); - ASSERT.equal(fp.toHex(), 'e5c5ba577fe24fb8a678d8d58f539cd7'); - }); - - it('should get a hex MD5 RSAPublicKey fingerprint', function() { - var publicKey = PKI.publicKeyFromPem(_pem.publicKey); - var fp = PKI.getPublicKeyFingerprint( - publicKey, - {md: MD.md5.create(), type: 'RSAPublicKey', encoding: 'hex'}); - ASSERT.equal(fp, 'c7da180cc48d31a071d31a78bc43d9d7'); - }); - - it('should get a hex, colon-delimited MD5 RSAPublicKey fingerprint', function() { - var publicKey = PKI.publicKeyFromPem(_pem.publicKey); - var fp = PKI.getPublicKeyFingerprint( - publicKey, { - md: MD.md5.create(), - type: 'RSAPublicKey', - encoding: 'hex', - delimiter: ':' - }); - ASSERT.equal(fp, 'c7:da:18:0c:c4:8d:31:a0:71:d3:1a:78:bc:43:d9:d7'); - }); - - it('should get a hex, colon-delimited MD5 SubjectPublicKeyInfo fingerprint', function() { - var publicKey = PKI.publicKeyFromPem(_pem.publicKey); - var fp = PKI.getPublicKeyFingerprint( - publicKey, { - md: MD.md5.create(), - type: 'SubjectPublicKeyInfo', - encoding: 'hex', - delimiter: ':' - }); - ASSERT.equal(fp, 'e5:c5:ba:57:7f:e2:4f:b8:a6:78:d8:d5:8f:53:9c:d7'); - }); - }); - - function createCertificate(options) { - var publicKey = options.publicKey; - var signingKey = options.signingKey; - var subject = options.subject; - var issuer = options.issuer; - var isCA = options.isCA; - var serialNumber = options.serialNumber || '01'; - - var cert = PKI.createCertificate(); - cert.publicKey = publicKey; - cert.serialNumber = serialNumber; - cert.validity.notBefore = new Date(); - cert.validity.notAfter = new Date(); - cert.validity.notAfter.setFullYear( - cert.validity.notBefore.getFullYear() + 1); - cert.setSubject(subject); - cert.setIssuer(issuer); - var extensions = []; - if(isCA) { - extensions.push({ - name: 'basicConstraints', - cA: true - }); - } - extensions.push({ - name: 'keyUsage', - keyCertSign: true, - digitalSignature: true, - nonRepudiation: true, - keyEncipherment: true, - dataEncipherment: true - }, { - name: 'extKeyUsage', - serverAuth: true, - clientAuth: true, - codeSigning: true, - emailProtection: true, - timeStamping: true - }, { - name: 'nsCertType', - client: true, - server: true, - email: true, - objsign: true, - sslCA: true, - emailCA: true, - objCA: true - }, { - name: 'subjectAltName', - altNames: [{ - type: 6, // URI - value: 'http://example.org/webid#me' - }] - }, { - name: 'subjectKeyIdentifier' - }); - // FIXME: add authorityKeyIdentifier extension - cert.setExtensions(extensions); - - cert.sign(signingKey); - - return cert; - } -} - -// check for AMD -if(typeof define === 'function') { - define([ - 'forge/pki', - 'forge/md', - 'forge/util' - ], function(PKI, MD, UTIL) { - Tests( - // Global provided by test harness - ASSERT, - PKI(), - MD(), - UTIL() - ); - }); -} else if(typeof module === 'object' && module.exports) { - // assume NodeJS - Tests( - require('assert'), - require('../../js/pki')(), - require('../../js/md')(), - require('../../js/util')()); -} - -})(); diff --git a/alarm/node_modules/node-forge/nodejs/ui/index.html b/alarm/node_modules/node-forge/nodejs/ui/index.html deleted file mode 100644 index 25e81b4..0000000 --- a/alarm/node_modules/node-forge/nodejs/ui/index.html +++ /dev/null @@ -1,12 +0,0 @@ -<!DOCTYPE html> -<html> -<head> - <link rel="stylesheet" href="mocha/mocha.css"> - <script src="mocha/mocha.js" type="text/javascript" charset="utf-8"></script> - <script src="chai/chai.js" type="text/javascript" charset="utf-8"></script> - <script src="require.js" data-main="test" type="text/javascript" charset="utf-8"></script> -</head> -<body> - <div id="mocha"></div> -</body> -</html> diff --git a/alarm/node_modules/node-forge/nodejs/ui/require.js b/alarm/node_modules/node-forge/nodejs/ui/require.js deleted file mode 100644 index 7df5d90..0000000 --- a/alarm/node_modules/node-forge/nodejs/ui/require.js +++ /dev/null @@ -1,35 +0,0 @@ -/* - RequireJS 2.1.5 Copyright (c) 2010-2012, The Dojo Foundation All Rights Reserved. - Available via the MIT or new BSD license. - see: http://github.com/jrburke/requirejs for details -*/ -var requirejs,require,define; -(function(aa){function I(b){return"[object Function]"===L.call(b)}function J(b){return"[object Array]"===L.call(b)}function y(b,c){if(b){var d;for(d=0;d<b.length&&(!b[d]||!c(b[d],d,b));d+=1);}}function M(b,c){if(b){var d;for(d=b.length-1;-1<d&&(!b[d]||!c(b[d],d,b));d-=1);}}function s(b,c){return ga.call(b,c)}function m(b,c){return s(b,c)&&b[c]}function G(b,c){for(var d in b)if(s(b,d)&&c(b[d],d))break}function R(b,c,d,m){c&&G(c,function(c,j){if(d||!s(b,j))m&&"string"!==typeof c?(b[j]||(b[j]={}),R(b[j], -c,d,m)):b[j]=c});return b}function u(b,c){return function(){return c.apply(b,arguments)}}function ba(b){if(!b)return b;var c=aa;y(b.split("."),function(b){c=c[b]});return c}function B(b,c,d,m){c=Error(c+"\nhttp://requirejs.org/docs/errors.html#"+b);c.requireType=b;c.requireModules=m;d&&(c.originalError=d);return c}function ha(b){function c(a,f,b){var e,n,c,g,d,S,i,h=f&&f.split("/");e=h;var j=k.map,l=j&&j["*"];if(a&&"."===a.charAt(0))if(f){e=m(k.pkgs,f)?h=[f]:h.slice(0,h.length-1);f=a=e.concat(a.split("/")); -for(e=0;f[e];e+=1)if(n=f[e],"."===n)f.splice(e,1),e-=1;else if(".."===n)if(1===e&&(".."===f[2]||".."===f[0]))break;else 0<e&&(f.splice(e-1,2),e-=2);e=m(k.pkgs,f=a[0]);a=a.join("/");e&&a===f+"/"+e.main&&(a=f)}else 0===a.indexOf("./")&&(a=a.substring(2));if(b&&j&&(h||l)){f=a.split("/");for(e=f.length;0<e;e-=1){c=f.slice(0,e).join("/");if(h)for(n=h.length;0<n;n-=1)if(b=m(j,h.slice(0,n).join("/")))if(b=m(b,c)){g=b;d=e;break}if(g)break;!S&&(l&&m(l,c))&&(S=m(l,c),i=e)}!g&&S&&(g=S,d=i);g&&(f.splice(0,d, -g),a=f.join("/"))}return a}function d(a){A&&y(document.getElementsByTagName("script"),function(f){if(f.getAttribute("data-requiremodule")===a&&f.getAttribute("data-requirecontext")===i.contextName)return f.parentNode.removeChild(f),!0})}function z(a){var f=m(k.paths,a);if(f&&J(f)&&1<f.length)return d(a),f.shift(),i.require.undef(a),i.require([a]),!0}function h(a){var f,b=a?a.indexOf("!"):-1;-1<b&&(f=a.substring(0,b),a=a.substring(b+1,a.length));return[f,a]}function j(a,f,b,e){var n,C,g=null,d=f?f.name: -null,j=a,l=!0,k="";a||(l=!1,a="_@r"+(M+=1));a=h(a);g=a[0];a=a[1];g&&(g=c(g,d,e),C=m(q,g));a&&(g?k=C&&C.normalize?C.normalize(a,function(a){return c(a,d,e)}):c(a,d,e):(k=c(a,d,e),a=h(k),g=a[0],k=a[1],b=!0,n=i.nameToUrl(k)));b=g&&!C&&!b?"_unnormalized"+(Q+=1):"";return{prefix:g,name:k,parentMap:f,unnormalized:!!b,url:n,originalName:j,isDefine:l,id:(g?g+"!"+k:k)+b}}function r(a){var f=a.id,b=m(p,f);b||(b=p[f]=new i.Module(a));return b}function t(a,f,b){var e=a.id,n=m(p,e);if(s(q,e)&&(!n||n.defineEmitComplete))"defined"=== -f&&b(q[e]);else r(a).on(f,b)}function v(a,f){var b=a.requireModules,e=!1;if(f)f(a);else if(y(b,function(f){if(f=m(p,f))f.error=a,f.events.error&&(e=!0,f.emit("error",a))}),!e)l.onError(a)}function w(){T.length&&(ia.apply(H,[H.length-1,0].concat(T)),T=[])}function x(a){delete p[a];delete V[a]}function F(a,f,b){var e=a.map.id;a.error?a.emit("error",a.error):(f[e]=!0,y(a.depMaps,function(e,c){var g=e.id,d=m(p,g);d&&(!a.depMatched[c]&&!b[g])&&(m(f,g)?(a.defineDep(c,q[g]),a.check()):F(d,f,b))}),b[e]=!0)} -function D(){var a,f,b,e,n=(b=1E3*k.waitSeconds)&&i.startTime+b<(new Date).getTime(),c=[],g=[],h=!1,j=!0;if(!W){W=!0;G(V,function(b){a=b.map;f=a.id;if(b.enabled&&(a.isDefine||g.push(b),!b.error))if(!b.inited&&n)z(f)?h=e=!0:(c.push(f),d(f));else if(!b.inited&&(b.fetched&&a.isDefine)&&(h=!0,!a.prefix))return j=!1});if(n&&c.length)return b=B("timeout","Load timeout for modules: "+c,null,c),b.contextName=i.contextName,v(b);j&&y(g,function(a){F(a,{},{})});if((!n||e)&&h)if((A||da)&&!X)X=setTimeout(function(){X= -0;D()},50);W=!1}}function E(a){s(q,a[0])||r(j(a[0],null,!0)).init(a[1],a[2])}function K(a){var a=a.currentTarget||a.srcElement,b=i.onScriptLoad;a.detachEvent&&!Y?a.detachEvent("onreadystatechange",b):a.removeEventListener("load",b,!1);b=i.onScriptError;(!a.detachEvent||Y)&&a.removeEventListener("error",b,!1);return{node:a,id:a&&a.getAttribute("data-requiremodule")}}function L(){var a;for(w();H.length;){a=H.shift();if(null===a[0])return v(B("mismatch","Mismatched anonymous define() module: "+a[a.length- -1]));E(a)}}var W,Z,i,N,X,k={waitSeconds:7,baseUrl:"./",paths:{},pkgs:{},shim:{},config:{}},p={},V={},$={},H=[],q={},U={},M=1,Q=1;N={require:function(a){return a.require?a.require:a.require=i.makeRequire(a.map)},exports:function(a){a.usingExports=!0;if(a.map.isDefine)return a.exports?a.exports:a.exports=q[a.map.id]={}},module:function(a){return a.module?a.module:a.module={id:a.map.id,uri:a.map.url,config:function(){return k.config&&m(k.config,a.map.id)||{}},exports:q[a.map.id]}}};Z=function(a){this.events= -m($,a.id)||{};this.map=a;this.shim=m(k.shim,a.id);this.depExports=[];this.depMaps=[];this.depMatched=[];this.pluginMaps={};this.depCount=0};Z.prototype={init:function(a,b,c,e){e=e||{};if(!this.inited){this.factory=b;if(c)this.on("error",c);else this.events.error&&(c=u(this,function(a){this.emit("error",a)}));this.depMaps=a&&a.slice(0);this.errback=c;this.inited=!0;this.ignore=e.ignore;e.enabled||this.enabled?this.enable():this.check()}},defineDep:function(a,b){this.depMatched[a]||(this.depMatched[a]= -!0,this.depCount-=1,this.depExports[a]=b)},fetch:function(){if(!this.fetched){this.fetched=!0;i.startTime=(new Date).getTime();var a=this.map;if(this.shim)i.makeRequire(this.map,{enableBuildCallback:!0})(this.shim.deps||[],u(this,function(){return a.prefix?this.callPlugin():this.load()}));else return a.prefix?this.callPlugin():this.load()}},load:function(){var a=this.map.url;U[a]||(U[a]=!0,i.load(this.map.id,a))},check:function(){if(this.enabled&&!this.enabling){var a,b,c=this.map.id;b=this.depExports; -var e=this.exports,n=this.factory;if(this.inited)if(this.error)this.emit("error",this.error);else{if(!this.defining){this.defining=!0;if(1>this.depCount&&!this.defined){if(I(n)){if(this.events.error)try{e=i.execCb(c,n,b,e)}catch(d){a=d}else e=i.execCb(c,n,b,e);this.map.isDefine&&((b=this.module)&&void 0!==b.exports&&b.exports!==this.exports?e=b.exports:void 0===e&&this.usingExports&&(e=this.exports));if(a)return a.requireMap=this.map,a.requireModules=[this.map.id],a.requireType="define",v(this.error= -a)}else e=n;this.exports=e;if(this.map.isDefine&&!this.ignore&&(q[c]=e,l.onResourceLoad))l.onResourceLoad(i,this.map,this.depMaps);x(c);this.defined=!0}this.defining=!1;this.defined&&!this.defineEmitted&&(this.defineEmitted=!0,this.emit("defined",this.exports),this.defineEmitComplete=!0)}}else this.fetch()}},callPlugin:function(){var a=this.map,b=a.id,d=j(a.prefix);this.depMaps.push(d);t(d,"defined",u(this,function(e){var n,d;d=this.map.name;var g=this.map.parentMap?this.map.parentMap.name:null,h= -i.makeRequire(a.parentMap,{enableBuildCallback:!0});if(this.map.unnormalized){if(e.normalize&&(d=e.normalize(d,function(a){return c(a,g,!0)})||""),e=j(a.prefix+"!"+d,this.map.parentMap),t(e,"defined",u(this,function(a){this.init([],function(){return a},null,{enabled:!0,ignore:!0})})),d=m(p,e.id)){this.depMaps.push(e);if(this.events.error)d.on("error",u(this,function(a){this.emit("error",a)}));d.enable()}}else n=u(this,function(a){this.init([],function(){return a},null,{enabled:!0})}),n.error=u(this, -function(a){this.inited=!0;this.error=a;a.requireModules=[b];G(p,function(a){0===a.map.id.indexOf(b+"_unnormalized")&&x(a.map.id)});v(a)}),n.fromText=u(this,function(e,c){var d=a.name,g=j(d),C=O;c&&(e=c);C&&(O=!1);r(g);s(k.config,b)&&(k.config[d]=k.config[b]);try{l.exec(e)}catch(ca){return v(B("fromtexteval","fromText eval for "+b+" failed: "+ca,ca,[b]))}C&&(O=!0);this.depMaps.push(g);i.completeLoad(d);h([d],n)}),e.load(a.name,h,n,k)}));i.enable(d,this);this.pluginMaps[d.id]=d},enable:function(){V[this.map.id]= -this;this.enabling=this.enabled=!0;y(this.depMaps,u(this,function(a,b){var c,e;if("string"===typeof a){a=j(a,this.map.isDefine?this.map:this.map.parentMap,!1,!this.skipMap);this.depMaps[b]=a;if(c=m(N,a.id)){this.depExports[b]=c(this);return}this.depCount+=1;t(a,"defined",u(this,function(a){this.defineDep(b,a);this.check()}));this.errback&&t(a,"error",this.errback)}c=a.id;e=p[c];!s(N,c)&&(e&&!e.enabled)&&i.enable(a,this)}));G(this.pluginMaps,u(this,function(a){var b=m(p,a.id);b&&!b.enabled&&i.enable(a, -this)}));this.enabling=!1;this.check()},on:function(a,b){var c=this.events[a];c||(c=this.events[a]=[]);c.push(b)},emit:function(a,b){y(this.events[a],function(a){a(b)});"error"===a&&delete this.events[a]}};i={config:k,contextName:b,registry:p,defined:q,urlFetched:U,defQueue:H,Module:Z,makeModuleMap:j,nextTick:l.nextTick,onError:v,configure:function(a){a.baseUrl&&"/"!==a.baseUrl.charAt(a.baseUrl.length-1)&&(a.baseUrl+="/");var b=k.pkgs,c=k.shim,e={paths:!0,config:!0,map:!0};G(a,function(a,b){e[b]? -"map"===b?(k.map||(k.map={}),R(k[b],a,!0,!0)):R(k[b],a,!0):k[b]=a});a.shim&&(G(a.shim,function(a,b){J(a)&&(a={deps:a});if((a.exports||a.init)&&!a.exportsFn)a.exportsFn=i.makeShimExports(a);c[b]=a}),k.shim=c);a.packages&&(y(a.packages,function(a){a="string"===typeof a?{name:a}:a;b[a.name]={name:a.name,location:a.location||a.name,main:(a.main||"main").replace(ja,"").replace(ea,"")}}),k.pkgs=b);G(p,function(a,b){!a.inited&&!a.map.unnormalized&&(a.map=j(b))});if(a.deps||a.callback)i.require(a.deps||[], -a.callback)},makeShimExports:function(a){return function(){var b;a.init&&(b=a.init.apply(aa,arguments));return b||a.exports&&ba(a.exports)}},makeRequire:function(a,f){function d(e,c,h){var g,k;f.enableBuildCallback&&(c&&I(c))&&(c.__requireJsBuild=!0);if("string"===typeof e){if(I(c))return v(B("requireargs","Invalid require call"),h);if(a&&s(N,e))return N[e](p[a.id]);if(l.get)return l.get(i,e,a,d);g=j(e,a,!1,!0);g=g.id;return!s(q,g)?v(B("notloaded",'Module name "'+g+'" has not been loaded yet for context: '+ -b+(a?"":". Use require([])"))):q[g]}L();i.nextTick(function(){L();k=r(j(null,a));k.skipMap=f.skipMap;k.init(e,c,h,{enabled:!0});D()});return d}f=f||{};R(d,{isBrowser:A,toUrl:function(b){var d,f=b.lastIndexOf("."),g=b.split("/")[0];if(-1!==f&&(!("."===g||".."===g)||1<f))d=b.substring(f,b.length),b=b.substring(0,f);return i.nameToUrl(c(b,a&&a.id,!0),d,!0)},defined:function(b){return s(q,j(b,a,!1,!0).id)},specified:function(b){b=j(b,a,!1,!0).id;return s(q,b)||s(p,b)}});a||(d.undef=function(b){w();var c= -j(b,a,!0),d=m(p,b);delete q[b];delete U[c.url];delete $[b];d&&(d.events.defined&&($[b]=d.events),x(b))});return d},enable:function(a){m(p,a.id)&&r(a).enable()},completeLoad:function(a){var b,c,e=m(k.shim,a)||{},d=e.exports;for(w();H.length;){c=H.shift();if(null===c[0]){c[0]=a;if(b)break;b=!0}else c[0]===a&&(b=!0);E(c)}c=m(p,a);if(!b&&!s(q,a)&&c&&!c.inited){if(k.enforceDefine&&(!d||!ba(d)))return z(a)?void 0:v(B("nodefine","No define call for "+a,null,[a]));E([a,e.deps||[],e.exportsFn])}D()},nameToUrl:function(a, -b,c){var e,d,h,g,j,i;if(l.jsExtRegExp.test(a))g=a+(b||"");else{e=k.paths;d=k.pkgs;g=a.split("/");for(j=g.length;0<j;j-=1)if(i=g.slice(0,j).join("/"),h=m(d,i),i=m(e,i)){J(i)&&(i=i[0]);g.splice(0,j,i);break}else if(h){a=a===h.name?h.location+"/"+h.main:h.location;g.splice(0,j,a);break}g=g.join("/");g+=b||(/\?/.test(g)||c?"":".js");g=("/"===g.charAt(0)||g.match(/^[\w\+\.\-]+:/)?"":k.baseUrl)+g}return k.urlArgs?g+((-1===g.indexOf("?")?"?":"&")+k.urlArgs):g},load:function(a,b){l.load(i,a,b)},execCb:function(a, -b,c,d){return b.apply(d,c)},onScriptLoad:function(a){if("load"===a.type||ka.test((a.currentTarget||a.srcElement).readyState))P=null,a=K(a),i.completeLoad(a.id)},onScriptError:function(a){var b=K(a);if(!z(b.id))return v(B("scripterror","Script error",a,[b.id]))}};i.require=i.makeRequire();return i}var l,w,x,D,t,E,P,K,Q,fa,la=/(\/\*([\s\S]*?)\*\/|([^:]|^)\/\/(.*)$)/mg,ma=/[^.]\s*require\s*\(\s*["']([^'"\s]+)["']\s*\)/g,ea=/\.js$/,ja=/^\.\//;w=Object.prototype;var L=w.toString,ga=w.hasOwnProperty,ia= -Array.prototype.splice,A=!!("undefined"!==typeof window&&navigator&&document),da=!A&&"undefined"!==typeof importScripts,ka=A&&"PLAYSTATION 3"===navigator.platform?/^complete$/:/^(complete|loaded)$/,Y="undefined"!==typeof opera&&"[object Opera]"===opera.toString(),F={},r={},T=[],O=!1;if("undefined"===typeof define){if("undefined"!==typeof requirejs){if(I(requirejs))return;r=requirejs;requirejs=void 0}"undefined"!==typeof require&&!I(require)&&(r=require,require=void 0);l=requirejs=function(b,c,d,z){var h, -j="_";!J(b)&&"string"!==typeof b&&(h=b,J(c)?(b=c,c=d,d=z):b=[]);h&&h.context&&(j=h.context);(z=m(F,j))||(z=F[j]=l.s.newContext(j));h&&z.configure(h);return z.require(b,c,d)};l.config=function(b){return l(b)};l.nextTick="undefined"!==typeof setTimeout?function(b){setTimeout(b,4)}:function(b){b()};require||(require=l);l.version="2.1.5";l.jsExtRegExp=/^\/|:|\?|\.js$/;l.isBrowser=A;w=l.s={contexts:F,newContext:ha};l({});y(["toUrl","undef","defined","specified"],function(b){l[b]=function(){var c=F._;return c.require[b].apply(c, -arguments)}});if(A&&(x=w.head=document.getElementsByTagName("head")[0],D=document.getElementsByTagName("base")[0]))x=w.head=D.parentNode;l.onError=function(b){throw b;};l.load=function(b,c,d){var l=b&&b.config||{},h;if(A)return h=l.xhtml?document.createElementNS("http://www.w3.org/1999/xhtml","html:script"):document.createElement("script"),h.type=l.scriptType||"text/javascript",h.charset="utf-8",h.async=!0,h.setAttribute("data-requirecontext",b.contextName),h.setAttribute("data-requiremodule",c), -h.attachEvent&&!(h.attachEvent.toString&&0>h.attachEvent.toString().indexOf("[native code"))&&!Y?(O=!0,h.attachEvent("onreadystatechange",b.onScriptLoad)):(h.addEventListener("load",b.onScriptLoad,!1),h.addEventListener("error",b.onScriptError,!1)),h.src=d,K=h,D?x.insertBefore(h,D):x.appendChild(h),K=null,h;if(da)try{importScripts(d),b.completeLoad(c)}catch(j){b.onError(B("importscripts","importScripts failed for "+c+" at "+d,j,[c]))}};A&&M(document.getElementsByTagName("script"),function(b){x||(x= -b.parentNode);if(t=b.getAttribute("data-main"))return r.baseUrl||(E=t.split("/"),Q=E.pop(),fa=E.length?E.join("/")+"/":"./",r.baseUrl=fa,t=Q),t=t.replace(ea,""),r.deps=r.deps?r.deps.concat(t):[t],!0});define=function(b,c,d){var l,h;"string"!==typeof b&&(d=c,c=b,b=null);J(c)||(d=c,c=[]);!c.length&&I(d)&&d.length&&(d.toString().replace(la,"").replace(ma,function(b,d){c.push(d)}),c=(1===d.length?["require"]:["require","exports","module"]).concat(c));if(O){if(!(l=K))P&&"interactive"===P.readyState||M(document.getElementsByTagName("script"), -function(b){if("interactive"===b.readyState)return P=b}),l=P;l&&(b||(b=l.getAttribute("data-requiremodule")),h=F[l.getAttribute("data-requirecontext")])}(h?h.defQueue:T).push([b,c,d])};define.amd={jQuery:!0};l.exec=function(b){return eval(b)};l(r)}})(this);
\ No newline at end of file diff --git a/alarm/node_modules/node-forge/nodejs/ui/test.js b/alarm/node_modules/node-forge/nodejs/ui/test.js deleted file mode 100644 index fa51fe2..0000000 --- a/alarm/node_modules/node-forge/nodejs/ui/test.js +++ /dev/null @@ -1,36 +0,0 @@ -var ASSERT = chai.assert; -mocha.setup({ - ui: 'bdd', - timeout: 30000 -}); -requirejs.config({ - paths: { - forge: 'forge', - test: 'test' - } -}); -requirejs([ - 'test/util', - 'test/md5', - 'test/sha1', - 'test/sha256', - 'test/hmac', - 'test/pbkdf2', - 'test/mgf1', - 'test/random', - 'test/asn1', - 'test/pem', - 'test/rsa', - 'test/kem', - 'test/pkcs1', - 'test/x509', - 'test/csr', - 'test/aes', - 'test/rc2', - 'test/des', - 'test/pkcs7', - 'test/pkcs12', - 'test/tls' -], function() { - mocha.run(); -}); diff --git a/alarm/node_modules/node-forge/nodejs/ui/test.min.js b/alarm/node_modules/node-forge/nodejs/ui/test.min.js deleted file mode 100644 index e94e9e0..0000000 --- a/alarm/node_modules/node-forge/nodejs/ui/test.min.js +++ /dev/null @@ -1 +0,0 @@ -(function(){function e(e){var t=e.util=e.util||{};typeof process=="undefined"||!process.nextTick?typeof setImmediate=="function"?(t.setImmediate=setImmediate,t.nextTick=function(e){return setImmediate(e)}):(t.setImmediate=function(e){setTimeout(e,0)},t.nextTick=t.setImmediate):(t.nextTick=process.nextTick,typeof setImmediate=="function"?t.setImmediate=setImmediate:t.setImmediate=t.nextTick),t.isArray=Array.isArray||function(e){return Object.prototype.toString.call(e)==="[object Array]"},t.ByteBuffer=function(e){this.data=e||"",this.read=0},t.ByteBuffer.prototype.length=function(){return this.data.length-this.read},t.ByteBuffer.prototype.isEmpty=function(){return this.length()<=0},t.ByteBuffer.prototype.putByte=function(e){return this.data+=String.fromCharCode(e),this},t.ByteBuffer.prototype.fillWithByte=function(e,t){e=String.fromCharCode(e);var n=this.data;while(t>0)t&1&&(n+=e),t>>>=1,t>0&&(e+=e);return this.data=n,this},t.ByteBuffer.prototype.putBytes=function(e){return this.data+=e,this},t.ByteBuffer.prototype.putString=function(e){return this.data+=t.encodeUtf8(e),this},t.ByteBuffer.prototype.putInt16=function(e){return this.data+=String.fromCharCode(e>>8&255)+String.fromCharCode(e&255),this},t.ByteBuffer.prototype.putInt24=function(e){return this.data+=String.fromCharCode(e>>16&255)+String.fromCharCode(e>>8&255)+String.fromCharCode(e&255),this},t.ByteBuffer.prototype.putInt32=function(e){return this.data+=String.fromCharCode(e>>24&255)+String.fromCharCode(e>>16&255)+String.fromCharCode(e>>8&255)+String.fromCharCode(e&255),this},t.ByteBuffer.prototype.putInt16Le=function(e){return this.data+=String.fromCharCode(e&255)+String.fromCharCode(e>>8&255),this},t.ByteBuffer.prototype.putInt24Le=function(e){return this.data+=String.fromCharCode(e&255)+String.fromCharCode(e>>8&255)+String.fromCharCode(e>>16&255),this},t.ByteBuffer.prototype.putInt32Le=function(e){return this.data+=String.fromCharCode(e&255)+String.fromCharCode(e>>8&255)+String.fromCharCode(e>>16&255)+String.fromCharCode(e>>24&255),this},t.ByteBuffer.prototype.putInt=function(e,t){do t-=8,this.data+=String.fromCharCode(e>>t&255);while(t>0);return this},t.ByteBuffer.prototype.putBuffer=function(e){return this.data+=e.getBytes(),this},t.ByteBuffer.prototype.getByte=function(){return this.data.charCodeAt(this.read++)},t.ByteBuffer.prototype.getInt16=function(){var e=this.data.charCodeAt(this.read)<<8^this.data.charCodeAt(this.read+1);return this.read+=2,e},t.ByteBuffer.prototype.getInt24=function(){var e=this.data.charCodeAt(this.read)<<16^this.data.charCodeAt(this.read+1)<<8^this.data.charCodeAt(this.read+2);return this.read+=3,e},t.ByteBuffer.prototype.getInt32=function(){var e=this.data.charCodeAt(this.read)<<24^this.data.charCodeAt(this.read+1)<<16^this.data.charCodeAt(this.read+2)<<8^this.data.charCodeAt(this.read+3);return this.read+=4,e},t.ByteBuffer.prototype.getInt16Le=function(){var e=this.data.charCodeAt(this.read)^this.data.charCodeAt(this.read+1)<<8;return this.read+=2,e},t.ByteBuffer.prototype.getInt24Le=function(){var e=this.data.charCodeAt(this.read)^this.data.charCodeAt(this.read+1)<<8^this.data.charCodeAt(this.read+2)<<16;return this.read+=3,e},t.ByteBuffer.prototype.getInt32Le=function(){var e=this.data.charCodeAt(this.read)^this.data.charCodeAt(this.read+1)<<8^this.data.charCodeAt(this.read+2)<<16^this.data.charCodeAt(this.read+3)<<24;return this.read+=4,e},t.ByteBuffer.prototype.getInt=function(e){var t=0;do t=(t<<8)+this.data.charCodeAt(this.read++),e-=8;while(e>0);return t},t.ByteBuffer.prototype.getBytes=function(e){var t;return e?(e=Math.min(this.length(),e),t=this.data.slice(this.read,this.read+e),this.read+=e):e===0?t="":(t=this.read===0?this.data:this.data.slice(this.read),this.clear()),t},t.ByteBuffer.prototype.bytes=function(e){return typeof e=="undefined"?this.data.slice(this.read):this.data.slice(this.read,this.read+e)},t.ByteBuffer.prototype.at=function(e){return this.data.charCodeAt(this.read+e)},t.ByteBuffer.prototype.setAt=function(e,t){return this.data=this.data.substr(0,this.read+e)+String.fromCharCode(t)+this.data.substr(this.read+e+1),this},t.ByteBuffer.prototype.last=function(){return this.data.charCodeAt(this.data.length-1)},t.ByteBuffer.prototype.copy=function(){var e=t.createBuffer(this.data);return e.read=this.read,e},t.ByteBuffer.prototype.compact=function(){return this.read>0&&(this.data=this.data.slice(this.read),this.read=0),this},t.ByteBuffer.prototype.clear=function(){return this.data="",this.read=0,this},t.ByteBuffer.prototype.truncate=function(e){var t=Math.max(0,this.length()-e);return this.data=this.data.substr(this.read,t),this.read=0,this},t.ByteBuffer.prototype.toHex=function(){var e="";for(var t=this.read;t<this.data.length;++t){var n=this.data.charCodeAt(t);n<16&&(e+="0"),e+=n.toString(16)}return e},t.ByteBuffer.prototype.toString=function(){return t.decodeUtf8(this.bytes())},t.createBuffer=function(e,n){return n=n||"raw",e!==undefined&&n==="utf8"&&(e=t.encodeUtf8(e)),new t.ByteBuffer(e)},t.fillString=function(e,t){var n="";while(t>0)t&1&&(n+=e),t>>>=1,t>0&&(e+=e);return n},t.xorBytes=function(e,t,n){var r="",i="",s="",o=0,u=0;for(;n>0;--n,++o)i=e.charCodeAt(o)^t.charCodeAt(o),u>=10&&(r+=s,s="",u=0),s+=String.fromCharCode(i),++u;return r+=s,r},t.hexToBytes=function(e){var t="",n=0;e.length&!0&&(n=1,t+=String.fromCharCode(parseInt(e[0],16)));for(;n<e.length;n+=2)t+=String.fromCharCode(parseInt(e.substr(n,2),16));return t},t.bytesToHex=function(e){return t.createBuffer(e).toHex()},t.int32ToBytes=function(e){return String.fromCharCode(e>>24&255)+String.fromCharCode(e>>16&255)+String.fromCharCode(e>>8&255)+String.fromCharCode(e&255)};var n="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",r=[62,-1,-1,-1,63,52,53,54,55,56,57,58,59,60,61,-1,-1,-1,64,-1,-1,-1,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,-1,-1,-1,-1,-1,-1,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51];t.encode64=function(e,t){var r="",i="",s,o,u,a=0;while(a<e.length)s=e.charCodeAt(a++),o=e.charCodeAt(a++),u=e.charCodeAt(a++),r+=n.charAt(s>>2),r+=n.charAt((s&3)<<4|o>>4),isNaN(o)?r+="==":(r+=n.charAt((o&15)<<2|u>>6),r+=isNaN(u)?"=":n.charAt(u&63)),t&&r.length>t&&(i+=r.substr(0,t)+"\r\n",r=r.substr(t));return i+=r,i},t.decode64=function(e){e=e.replace(/[^A-Za-z0-9\+\/\=]/g,"");var t="",n,i,s,o,u=0;while(u<e.length)n=r[e.charCodeAt(u++)-43],i=r[e.charCodeAt(u++)-43],s=r[e.charCodeAt(u++)-43],o=r[e.charCodeAt(u++)-43],t+=String.fromCharCode(n<<2|i>>4),s!==64&&(t+=String.fromCharCode((i&15)<<4|s>>2),o!==64&&(t+=String.fromCharCode((s&3)<<6|o)));return t},t.encodeUtf8=function(e){return unescape(encodeURIComponent(e))},t.decodeUtf8=function(e){return decodeURIComponent(escape(e))},t.deflate=function(e,n,r){n=t.decode64(e.deflate(t.encode64(n)).rval);if(r){var i=2,s=n.charCodeAt(1);s&32&&(i=6),n=n.substring(i,n.length-4)}return n},t.inflate=function(e,n,r){var i=e.inflate(t.encode64(n)).rval;return i===null?null:t.decode64(i)};var i=function(e,n,r){if(!e)throw{message:"WebStorage not available."};var i;r===null?i=e.removeItem(n):(r=t.encode64(JSON.stringify(r)),i=e.setItem(n,r));if(typeof i!="undefined"&&i.rval!==!0)throw i.error},s=function(e,n){if(!e)throw{message:"WebStorage not available."};var r=e.getItem(n);if(e.init)if(r.rval===null){if(r.error)throw r.error;r=null}else r=r.rval;return r!==null&&(r=JSON.parse(t.decode64(r))),r},o=function(e,t,n,r){var o=s(e,t);o===null&&(o={}),o[n]=r,i(e,t,o)},u=function(e,t,n){var r=s(e,t);return r!==null&&(r=n in r?r[n]:null),r},a=function(e,t,n){var r=s(e,t);if(r!==null&&n in r){delete r[n];var o=!0;for(var u in r){o=!1;break}o&&(r=null),i(e,t,r)}},f=function(e,t){i(e,t,null)},l=function(e,t,n){var r=null;typeof n=="undefined"&&(n=["web","flash"]);var i,s=!1,o=null;for(var u in n){i=n[u];try{if(i==="flash"||i==="both"){if(t[0]===null)throw{message:"Flash local storage not available."};r=e.apply(this,t),s=i==="flash"}if(i==="web"||i==="both")t[0]=localStorage,r=e.apply(this,t),s=!0}catch(a){o=a}if(s)break}if(!s)throw o;return r};t.setItem=function(e,t,n,r,i){l(o,arguments,i)},t.getItem=function(e,t,n,r){return l(u,arguments,r)},t.removeItem=function(e,t,n,r){l(a,arguments,r)},t.clearItems=function(e,t,n){l(f,arguments,n)},t.parseUrl=function(e){var t=/^(https?):\/\/([^:&^\/]*):?(\d*)(.*)$/g;t.lastIndex=0;var n=t.exec(e),r=n===null?null:{full:e,scheme:n[1],host:n[2],port:n[3],path:n[4]};return r&&(r.fullHost=r.host,r.port?r.port!==80&&r.scheme==="http"?r.fullHost+=":"+r.port:r.port!==443&&r.scheme==="https"&&(r.fullHost+=":"+r.port):r.scheme==="http"?r.port=80:r.scheme==="https"&&(r.port=443),r.full=r.scheme+"://"+r.fullHost),r};var c=null;t.getQueryVariables=function(e){var t=function(e){var t={},n=e.split("&");for(var r=0;r<n.length;r++){var i=n[r].indexOf("="),s,o;i>0?(s=n[r].substring(0,i),o=n[r].substring(i+1)):(s=n[r],o=null),s in t||(t[s]=[]),!(s in Object.prototype)&&o!==null&&t[s].push(unescape(o))}return t},n;return typeof e=="undefined"?(c===null&&(typeof window=="undefined"?c={}:c=t(window.location.search.substring(1))),n=c):n=t(e),n},t.parseFragment=function(e){var n=e,r="",i=e.indexOf("?");i>0&&(n=e.substring(0,i),r=e.substring(i+1));var s=n.split("/");s.length>0&&s[0]===""&&s.shift();var o=r===""?{}:t.getQueryVariables(r);return{pathString:n,queryString:r,path:s,query:o}},t.makeRequest=function(e){var n=t.parseFragment(e),r={path:n.pathString,query:n.queryString,getPath:function(e){return typeof e=="undefined"?n.path:n.path[e]},getQuery:function(e,t){var r;return typeof e=="undefined"?r=n.query:(r=n.query[e],r&&typeof t!="undefined"&&(r=r[t])),r},getQueryLast:function(e,t){var n,i=r.getQuery(e);return i?n=i[i.length-1]:n=t,n}};return r},t.makeLink=function(e,t,n){e=jQuery.isArray(e)?e.join("/"):e;var r=jQuery.param(t||{});return n=n||"",e+(r.length>0?"?"+r:"")+(n.length>0?"#"+n:"")},t.setPath=function(e,t,n){if(typeof e=="object"&&e!==null){var r=0,i=t.length;while(r<i){var s=t[r++];if(r==i)e[s]=n;else{var o=s in e;if(!o||o&&typeof e[s]!="object"||o&&e[s]===null)e[s]={};e=e[s]}}}},t.getPath=function(e,t,n){var r=0,i=t.length,s=!0;while(s&&r<i&&typeof e=="object"&&e!==null){var o=t[r++];s=o in e,s&&(e=e[o])}return s?e:n},t.deletePath=function(e,t){if(typeof e=="object"&&e!==null){var n=0,r=t.length;while(n<r){var i=t[n++];if(n==r)delete e[i];else{if(!(i in e&&typeof e[i]=="object"&&e[i]!==null))break;e=e[i]}}}},t.isEmpty=function(e){for(var t in e)if(e.hasOwnProperty(t))return!1;return!0},t.format=function(e){var t=/%./g,n,r,i=0,s=[],o=0;while(n=t.exec(e)){r=e.substring(o,t.lastIndex-2),r.length>0&&s.push(r),o=t.lastIndex;var u=n[0][1];switch(u){case"s":case"o":i<arguments.length?s.push(arguments[i++ +1]):s.push("<?>");break;case"%":s.push("%");break;default:s.push("<%"+u+"?>")}}return s.push(e.substring(o)),s.join("")},t.formatNumber=function(e,t,n,r){var i=e,s=isNaN(t=Math.abs(t))?2:t,o=n===undefined?",":n,u=r===undefined?".":r,a=i<0?"-":"",f=parseInt(i=Math.abs(+i||0).toFixed(s),10)+"",l=f.length>3?f.length%3:0;return a+(l?f.substr(0,l)+u:"")+f.substr(l).replace(/(\d{3})(?=\d)/g,"$1"+u)+(s?o+Math.abs(i-f).toFixed(s).slice(2):"")},t.formatSize=function(e){return e>=1073741824?e=t.formatNumber(e/1073741824,2,".","")+" GiB":e>=1048576?e=t.formatNumber(e/1048576,2,".","")+" MiB":e>=1024?e=t.formatNumber(e/1024,0)+" KiB":e=t.formatNumber(e,0)+" bytes",e}}var t="util";if(typeof define!="function"){if(typeof module!="object"||!module.exports)return typeof forge=="undefined"&&(forge={}),e(forge);var n=!0;define=function(e,t){t(require,module)}}var r,i=function(n,i){i.exports=function(i){var s=r.map(function(e){return n(e)}).concat(e);i=i||{},i.defined=i.defined||{};if(i.defined[t])return i[t];i.defined[t]=!0;for(var o=0;o<s.length;++o)s[o](i);return i[t]}},s=define;define=function(e,t){return r=typeof e=="string"?t.slice(2):e.slice(2),n?(delete define,s.apply(null,Array.prototype.slice.call(arguments,0))):(define=s,define.apply(null,Array.prototype.slice.call(arguments,0)))},define("forge/util",["require","module"],function(){i.apply(null,Array.prototype.slice.call(arguments,0))})})(),function(){function e(e,t){describe("util",function(){it("should put bytes into a buffer",function(){var n=t.createBuffer();n.putByte(1),n.putByte(2),n.putByte(3),n.putByte(4),n.putInt32(4),n.putByte(1),n.putByte(2),n.putByte(3),n.putInt32(4294967295);var r=n.toHex();e.equal(r,"0102030400000004010203ffffffff");var i=[];while(n.length()>0)i.push(n.getByte());e.deepEqual(i,[1,2,3,4,0,0,0,4,1,2,3,255,255,255,255])}),it("should convert bytes from hex",function(){var n="0102030400000004010203ffffffff",r=t.createBuffer();r.putBytes(t.hexToBytes(n)),e.equal(r.toHex(),n)}),it("should base64 encode some bytes",function(){var n="00010203050607080A0B0C0D0F1011121415161719",r="MDAwMTAyMDMwNTA2MDcwODBBMEIwQzBEMEYxMDExMTIxNDE1MTYxNzE5";e.equal(t.encode64(n),r)}),it("should base64 decode some bytes",function(){var n="00010203050607080A0B0C0D0F1011121415161719",r="MDAwMTAyMDMwNTA2MDcwODBBMEIwQzBEMEYxMDExMTIxNDE1MTYxNzE5";e.equal(t.decode64(r),n)})})}typeof define=="function"?define("test/util",["forge/util"],function(t){e(ASSERT,t())}):typeof module=="object"&&module.exports&&e(require("assert"),require("../../js/util")())}(),function(){function e(e){var t=e.md5=e.md5||{};e.md=e.md||{},e.md.algorithms=e.md.algorithms||{},e.md.md5=e.md.algorithms.md5=t;var n=null,r=null,i=null,s=null,o=!1,u=function(){n=String.fromCharCode(128),n+=e.util.fillString(String.fromCharCode(0),64),r=[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,1,6,11,0,5,10,15,4,9,14,3,8,13,2,7,12,5,8,11,14,1,4,7,10,13,0,3,6,9,12,15,2,0,7,14,5,12,3,10,1,8,15,6,13,4,11,2,9],i=[7,12,17,22,7,12,17,22,7,12,17,22,7,12,17,22,5,9,14,20,5,9,14,20,5,9,14,20,5,9,14,20,4,11,16,23,4,11,16,23,4,11,16,23,4,11,16,23,6,10,15,21,6,10,15,21,6,10,15,21,6,10,15,21],s=new Array(64);for(var t=0;t<64;++t)s[t]=Math.floor(Math.abs(Math.sin(t+1))*4294967296);o=!0},a=function(e,t,n){var o,u,a,f,l,c,h,p,d=n.length();while(d>=64){u=e.h0,a=e.h1,f=e.h2,l=e.h3;for(p=0;p<16;++p)t[p]=n.getInt32Le(),c=l^a&(f^l),o=u+c+s[p]+t[p],h=i[p],u=l,l=f,f=a,a+=o<<h|o>>>32-h;for(;p<32;++p)c=f^l&(a^f),o=u+c+s[p]+t[r[p]],h=i[p],u=l,l=f,f=a,a+=o<<h|o>>>32-h;for(;p<48;++p)c=a^f^l,o=u+c+s[p]+t[r[p]],h=i[p],u=l,l=f,f=a,a+=o<<h|o>>>32-h;for(;p<64;++p)c=f^(a|~l),o=u+c+s[p]+t[r[p]],h=i[p],u=l,l=f,f=a,a+=o<<h|o>>>32-h;e.h0=e.h0+u&4294967295,e.h1=e.h1+a&4294967295,e.h2=e.h2+f&4294967295,e.h3=e.h3+l&4294967295,d-=64}};t.create=function(){o||u();var t=null,r=e.util.createBuffer(),i=new Array(16),s={algorithm:"md5",blockLength:64,digestLength:16,messageLength:0};return s.start=function(){return s.messageLength=0,r=e.util.createBuffer(),t={h0:1732584193,h1:4023233417,h2:2562383102,h3:271733878},s},s.start(),s.update=function(n,o){return o==="utf8"&&(n=e.util.encodeUtf8(n)),s.messageLength+=n.length,r.putBytes(n),a(t,i,r),(r.read>2048||r.length()===0)&&r.compact(),s},s.digest=function(){var o=s.messageLength,u=e.util.createBuffer();u.putBytes(r.bytes()),u.putBytes(n.substr(0,64-(o+8)%64)),u.putInt32Le(o<<3&4294967295),u.putInt32Le(o>>>29&255);var f={h0:t.h0,h1:t.h1,h2:t.h2,h3:t.h3};a(f,i,u);var l=e.util.createBuffer();return l.putInt32Le(f.h0),l.putInt32Le(f.h1),l.putInt32Le(f.h2),l.putInt32Le(f.h3),l},s}}var t="md5";if(typeof define!="function"){if(typeof module!="object"||!module.exports)return typeof forge=="undefined"&&(forge={}),e(forge);var n=!0;define=function(e,t){t(require,module)}}var r,i=function(n,i){i.exports=function(i){var s=r.map(function(e){return n(e)}).concat(e);i=i||{},i.defined=i.defined||{};if(i.defined[t])return i[t];i.defined[t]=!0;for(var o=0;o<s.length;++o)s[o](i);return i[t]}},s=define;define=function(e,t){return r=typeof e=="string"?t.slice(2):e.slice(2),n?(delete define,s.apply(null,Array.prototype.slice.call(arguments,0))):(define=s,define.apply(null,Array.prototype.slice.call(arguments,0)))},define("forge/md5",["require","module","./util"],function(){i.apply(null,Array.prototype.slice.call(arguments,0))})}(),function(){function e(e,t,n){describe("md5",function(){it("should digest the empty string",function(){var n=t.create();e.equal(n.digest().toHex(),"d41d8cd98f00b204e9800998ecf8427e")}),it('should digest "abc"',function(){var n=t.create();n.update("abc"),e.equal(n.digest().toHex(),"900150983cd24fb0d6963f7d28e17f72")}),it('should digest "The quick brown fox jumps over the lazy dog"',function(){var n=t.create();n.update("The quick brown fox jumps over the lazy dog"),e.equal(n.digest().toHex(),"9e107d9d372bb6826bd81d3542a419d6")}),it('should digest "c\'è"',function(){var n=t.create();n.update("c'è","utf8"),e.equal(n.digest().toHex(),"8ef7c2941d78fe89f31e614437c9db59")}),it('should digest "THIS IS A MESSAGE"',function(){var n=t.create();n.start(),n.update("THIS IS "),n.update("A MESSAGE"),e.equal(n.digest().toHex(),"78eebfd9d42958e3f31244f116ab7bbe"),e.equal(n.digest().toHex(),"78eebfd9d42958e3f31244f116ab7bbe")}),it("should digest a long message",function(){var r=n.hexToBytes("0100002903018d32e9c6dc423774c4c39a5a1b78f44cc2cab5f676d39f703d29bfa27dfeb870000002002f01000200004603014c2c1e835d39da71bc0857eb04c2b50fe90dbb2a8477fe7364598d6f0575999c20a6c7248c5174da6d03ac711888f762fc4ed54f7254b32273690de849c843073d002f000b0003d20003cf0003cc308203c8308202b0a003020102020100300d06092a864886f70d0101050500308186310b3009060355040613025553311d301b060355040a13144469676974616c2042617a6161722c20496e632e31443042060355040b133b4269746d756e6b206c6f63616c686f73742d6f6e6c7920436572746966696361746573202d20417574686f72697a6174696f6e207669612042545031123010060355040313096c6f63616c686f7374301e170d3130303231343137303931395a170d3230303231333137303931395a308186310b3009060355040613025553311d301b060355040a13144469676974616c2042617a6161722c20496e632e31443042060355040b133b4269746d756e6b206c6f63616c686f73742d6f6e6c7920436572746966696361746573202d20417574686f72697a6174696f6e207669612042545031123010060355040313096c6f63616c686f737430820122300d06092a864886f70d01010105000382010f003082010a0282010100dc436f17d6909d8a9d6186ea218eb5c86b848bae02219bd56a71203daf07e81bc19e7e98134136bcb012881864bf03b3774652ad5eab85dba411a5114ffeac09babce75f31314345512cd87c91318b2e77433270a52185fc16f428c3ca412ad6e9484bc2fb87abb4e8fb71bf0f619e31a42340b35967f06c24a741a31c979c0bb8921a90a47025fbeb8adca576979e70a56830c61170c9647c18c0794d68c0df38f3aac5fc3b530e016ea5659715339f3f3c209cdee9dbe794b5af92530c5754c1d874b78974bfad994e0dfc582275e79feb522f6e4bcc2b2945baedfb0dbdaebb605f9483ff0bea29ecd5f4d6f2769965d1b3e04f8422716042680011ff676f0203010001a33f303d300c0603551d130101ff04023000300e0603551d0f0101ff0404030204f0301d0603551d250416301406082b0601050507030106082b06010505070302300d06092a864886f70d010105050003820101009c4562be3f2d8d8e388085a697f2f106eaeff4992a43f198fe3dcf15c8229cf1043f061a38204f73d86f4fb6348048cc5279ed719873aa10e3773d92b629c2c3fcce04012c81ba3b4ec451e9644ec5191078402d845e05d02c7b4d974b4588276e5037aba7ef26a8bddeb21e10698c82f425e767dc401adf722fa73ab78cfa069bd69052d7ca6a75cc9225550e315d71c5f8764362ea4dbc6ecb837a8471043c5a7f826a71af145a053090bd4bccca6a2c552841cdb1908a8352f49283d2e641acdef667c7543af441a16f8294251e2ac376fa507b53ae418dd038cd20cef1e7bfbf5ae03a7c88d93d843abaabbdc5f3431132f3e559d2dd414c3eda38a210b80e00000010000102010026a220b7be857402819b78d81080d01a682599bbd00902985cc64edf8e520e4111eb0e1729a14ffa3498ca259cc9ad6fc78fa130d968ebdb78dc0b950c0aa44355f13ba678419185d7e4608fe178ca6b2cef33e4193778d1a70fe4d0dfcb110be4bbb4dbaa712177655728f914ab4c0f6c4aef79a46b3d996c82b2ebe9ed1748eb5cace7dc44fb67e73f452a047f2ed199b3d50d5db960acf03244dc8efa4fc129faf8b65f9e52e62b5544722bd17d2358e817a777618a4265a3db277fc04851a82a91fe6cdcb8127f156e0b4a5d1f54ce2742eb70c895f5f8b85f5febe69bc73e891f9280826860a0c2ef94c7935e6215c3c4cd6b0e43e80cca396d913d36be"),i=t.create();i.update(r),e.equal(i.digest().toHex(),"d15a2da0e92c3da55dc573f885b6e653")})})}typeof define=="function"?define("test/md5",["forge/md5","forge/util"],function(t,n){e(ASSERT,t(),n())}):typeof module=="object"&&module.exports&&e(require("assert"),require("../../js/md5")(),require("../../js/util")())}(),function(){function e(e){var t=e.sha1=e.sha1||{};e.md=e.md||{},e.md.algorithms=e.md.algorithms||{},e.md.sha1=e.md.algorithms.sha1=t;var n=null,r=!1,i=function(){n=String.fromCharCode(128),n+=e.util.fillString(String.fromCharCode(0),64),r=!0},s=function(e,t,n){var r,i,s,o,u,a,f,l,c=n.length();while(c>=64){i=e.h0,s=e.h1,o=e.h2,u=e.h3,a=e.h4;for(l=0;l<16;++l)r=n.getInt32(),t[l]=r,f=u^s&(o^u),r=(i<<5|i>>>27)+f+a+1518500249+r,a=u,u=o,o=s<<30|s>>>2,s=i,i=r;for(;l<20;++l)r=t[l-3]^t[l-8]^t[l-14]^t[l-16],r=r<<1|r>>>31,t[l]=r,f=u^s&(o^u),r=(i<<5|i>>>27)+f+a+1518500249+r,a=u,u=o,o=s<<30|s>>>2,s=i,i=r;for(;l<32;++l)r=t[l-3]^t[l-8]^t[l-14]^t[l-16],r=r<<1|r>>>31,t[l]=r,f=s^o^u,r=(i<<5|i>>>27)+f+a+1859775393+r,a=u,u=o,o=s<<30|s>>>2,s=i,i=r;for(;l<40;++l)r=t[l-6]^t[l-16]^t[l-28]^t[l-32],r=r<<2|r>>>30,t[l]=r,f=s^o^u,r=(i<<5|i>>>27)+f+a+1859775393+r,a=u,u=o,o=s<<30|s>>>2,s=i,i=r;for(;l<60;++l)r=t[l-6]^t[l-16]^t[l-28]^t[l-32],r=r<<2|r>>>30,t[l]=r,f=s&o|u&(s^o),r=(i<<5|i>>>27)+f+a+2400959708+r,a=u,u=o,o=s<<30|s>>>2,s=i,i=r;for(;l<80;++l)r=t[l-6]^t[l-16]^t[l-28]^t[l-32],r=r<<2|r>>>30,t[l]=r,f=s^o^u,r=(i<<5|i>>>27)+f+a+3395469782+r,a=u,u=o,o=s<<30|s>>>2,s=i,i=r;e.h0+=i,e.h1+=s,e.h2+=o,e.h3+=u,e.h4+=a,c-=64}};t.create=function(){r||i();var t=null,o=e.util.createBuffer(),u=new Array(80),a={algorithm:"sha1",blockLength:64,digestLength:20,messageLength:0};return a.start=function(){return a.messageLength=0,o=e.util.createBuffer(),t={h0:1732584193,h1:4023233417,h2:2562383102,h3:271733878,h4:3285377520},a},a.start(),a.update=function(n,r){return r==="utf8"&&(n=e.util.encodeUtf8(n)),a.messageLength+=n.length,o.putBytes(n),s(t,u,o),(o.read>2048||o.length()===0)&&o.compact(),a},a.digest=function(){var r=a.messageLength,i=e.util.createBuffer();i.putBytes(o.bytes()),i.putBytes(n.substr(0,64-(r+8)%64)),i.putInt32(r>>>29&255),i.putInt32(r<<3&4294967295);var f={h0:t.h0,h1:t.h1,h2:t.h2,h3:t.h3,h4:t.h4};s(f,u,i);var l=e.util.createBuffer();return l.putInt32(f.h0),l.putInt32(f.h1),l.putInt32(f.h2),l.putInt32(f.h3),l.putInt32(f.h4),l},a}}var t="sha1";if(typeof define!="function"){if(typeof module!="object"||!module.exports)return typeof forge=="undefined"&&(forge={}),e(forge);var n=!0;define=function(e,t){t(require,module)}}var r,i=function(n,i){i.exports=function(i){var s=r.map(function(e){return n(e)}).concat(e);i=i||{},i.defined=i.defined||{};if(i.defined[t])return i[t];i.defined[t]=!0;for(var o=0;o<s.length;++o)s[o](i);return i[t]}},s=define;define=function(e,t){return r=typeof e=="string"?t.slice(2):e.slice(2),n?(delete define,s.apply(null,Array.prototype.slice.call(arguments,0))):(define=s,define.apply(null,Array.prototype.slice.call(arguments,0)))},define("forge/sha1",["require","module","./util"],function(){i.apply(null,Array.prototype.slice.call(arguments,0))})}(),function(){function e(e,t,n){describe("sha1",function(){it("should digest the empty string",function(){var n=t.create();e.equal(n.digest().toHex(),"da39a3ee5e6b4b0d3255bfef95601890afd80709")}),it('should digest "abc"',function(){var n=t.create();n.update("abc"),e.equal(n.digest().toHex(),"a9993e364706816aba3e25717850c26c9cd0d89d")}),it('should digest "The quick brown fox jumps over the lazy dog"',function(){var n=t.create();n.update("The quick brown fox jumps over the lazy dog"),e.equal(n.digest().toHex(),"2fd4e1c67a2d28fced849ee1bb76e7391b93eb12")}),it('should digest "c\'è"',function(){var n=t.create();n.update("c'è","utf8"),e.equal(n.digest().toHex(),"98c9a3f804daa73b68a5660d032499a447350c0d")}),it('should digest "THIS IS A MESSAGE"',function(){var n=t.create();n.start(),n.update("THIS IS "),n.update("A MESSAGE"),e.equal(n.digest().toHex(),"5f24f4d6499fd2d44df6c6e94be8b14a796c071d"),e.equal(n.digest().toHex(),"5f24f4d6499fd2d44df6c6e94be8b14a796c071d")}),it("should digest a long message",function(){var r=t.create();r.update(n.fillString("a",1e6)),e.equal(r.digest().toHex(),"34aa973cd4c4daa4f61eeb2bdbad27316534016f")})})}typeof define=="function"?define("test/sha1",["forge/sha1","forge/util"],function(t,n){e(ASSERT,t(),n())}):typeof module=="object"&&module.exports&&e(require("assert"),require("../../js/sha1")(),require("../../js/util")())}(),function(){function e(e){var t=e.sha256=e.sha256||{};e.md=e.md||{},e.md.algorithms=e.md.algorithms||{},e.md.sha256=e.md.algorithms.sha256=t;var n=null,r=!1,i=null,s=function(){n=String.fromCharCode(128),n+=e.util.fillString(String.fromCharCode(0),64),i=[1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298],r=!0},o=function(e,t,n){var r,s,o,u,a,f,l,c,h,p,d,v,m,g,y,b=n.length();while(b>=64){for(l=0;l<16;++l)t[l]=n.getInt32();for(;l<64;++l)r=t[l-2],r=(r>>>17|r<<15)^(r>>>19|r<<13)^r>>>10,s=t[l-15],s=(s>>>7|s<<25)^(s>>>18|s<<14)^s>>>3,t[l]=r+t[l-7]+s+t[l-16]&4294967295;c=e.h0,h=e.h1,p=e.h2,d=e.h3,v=e.h4,m=e.h5,g=e.h6,y=e.h7;for(l=0;l<64;++l)u=(v>>>6|v<<26)^(v>>>11|v<<21)^(v>>>25|v<<7),a=g^v&(m^g),o=(c>>>2|c<<30)^(c>>>13|c<<19)^(c>>>22|c<<10),f=c&h|p&(c^h),r=y+u+a+i[l]+t[l],s=o+f,y=g,g=m,m=v,v=d+r&4294967295,d=p,p=h,h=c,c=r+s&4294967295;e.h0=e.h0+c&4294967295,e.h1=e.h1+h&4294967295,e.h2=e.h2+p&4294967295,e.h3=e.h3+d&4294967295,e.h4=e.h4+v&4294967295,e.h5=e.h5+m&4294967295,e.h6=e.h6+g&4294967295,e.h7=e.h7+y&4294967295,b-=64}};t.create=function(){r||s();var t=null,i=e.util.createBuffer(),u=new Array(64),a={algorithm:"sha256",blockLength:64,digestLength:32,messageLength:0};return a.start=function(){return a.messageLength=0,i=e.util.createBuffer(),t={h0:1779033703,h1:3144134277,h2:1013904242,h3:2773480762,h4:1359893119,h5:2600822924,h6:528734635,h7:1541459225},a},a.start(),a.update=function(n,r){return r==="utf8"&&(n=e.util.encodeUtf8(n)),a.messageLength+=n.length,i.putBytes(n),o(t,u,i),(i.read>2048||i.length()===0)&&i.compact(),a},a.digest=function(){var r=a.messageLength,s=e.util.createBuffer();s.putBytes(i.bytes()),s.putBytes(n.substr(0,64-(r+8)%64)),s.putInt32(r>>>29&255),s.putInt32(r<<3&4294967295);var f={h0:t.h0,h1:t.h1,h2:t.h2,h3:t.h3,h4:t.h4,h5:t.h5,h6:t.h6,h7:t.h7};o(f,u,s);var l=e.util.createBuffer();return l.putInt32(f.h0),l.putInt32(f.h1),l.putInt32(f.h2),l.putInt32(f.h3),l.putInt32(f.h4),l.putInt32(f.h5),l.putInt32(f.h6),l.putInt32(f.h7),l},a}}var t="sha256";if(typeof define!="function"){if(typeof module!="object"||!module.exports)return typeof forge=="undefined"&&(forge={}),e(forge);var n=!0;define=function(e,t){t(require,module)}}var r,i=function(n,i){i.exports=function(i){var s=r.map(function(e){return n(e)}).concat(e);i=i||{},i.defined=i.defined||{};if(i.defined[t])return i[t];i.defined[t]=!0;for(var o=0;o<s.length;++o)s[o](i);return i[t]}},s=define;define=function(e,t){return r=typeof e=="string"?t.slice(2):e.slice(2),n?(delete define,s.apply(null,Array.prototype.slice.call(arguments,0))):(define=s,define.apply(null,Array.prototype.slice.call(arguments,0)))},define("forge/sha256",["require","module","./util"],function(){i.apply(null,Array.prototype.slice.call(arguments,0))})}(),function(){function e(e,t,n){describe("sha256",function(){it("should digest the empty string",function(){var n=t.create();e.equal(n.digest().toHex(),"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855")}),it('should digest "abc"',function(){var n=t.create();n.update("abc"),e.equal(n.digest().toHex(),"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad")}),it('should digest "The quick brown fox jumps over the lazy dog"',function(){var n=t.create();n.update("The quick brown fox jumps over the lazy dog"),e.equal(n.digest().toHex(),"d7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592")}),it('should digest "c\'è"',function(){var n=t.create();n.update("c'è","utf8"),e.equal(n.digest().toHex(),"1aa15c717afffd312acce2217ce1c2e5dabca53c92165999132ec9ca5decdaca")}),it('should digest "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"',function(){var n=t.create();n.start(),n.update("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"),e.equal(n.digest().toHex(),"248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1"),e.equal(n.digest().toHex(),"248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1")}),it("should digest a long message",function(){var r=t.create();r.update(n.fillString("a",1e6)),e.equal(r.digest().toHex(),"cdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd0")})})}typeof define=="function"?define("test/sha256",["forge/sha256","forge/util"],function(t,n){e(ASSERT,t(),n())}):typeof module=="object"&&module.exports&&e(require("assert"),require("../../js/sha256")(),require("../../js/util")())}(),function(){function e(e){e.md=e.md||{},e.md.algorithms={md5:e.md5,sha1:e.sha1,sha256:e.sha256},e.md.md5=e.md5,e.md.sha1=e.sha1,e.md.sha256=e.sha256}var t="md";if(typeof define!="function"){if(typeof module!="object"||!module.exports)return typeof forge=="undefined"&&(forge={}),e(forge);var n=!0;define=function(e,t){t(require,module)}}var r,i=function(n,i){i.exports=function(i){var s=r.map(function(e){return n(e)}).concat(e);i=i||{},i.defined=i.defined||{};if(i.defined[t])return i[t];i.defined[t]=!0;for(var o=0;o<s.length;++o)s[o](i);return i[t]}},s=define;define=function(e,t){return r=typeof e=="string"?t.slice(2):e.slice(2),n?(delete define,s.apply(null,Array.prototype.slice.call(arguments,0))):(define=s,define.apply(null,Array.prototype.slice.call(arguments,0)))},define("forge/md",["require","module","./md5","./sha1","./sha256"],function(){i.apply(null,Array.prototype.slice.call(arguments,0))})}(),function(){function e(e){var t=e.hmac=e.hmac||{};t.create=function(){var t=null,n=null,r=null,i=null,s={};return s.start=function(s,o){if(s!==null)if(typeof s=="string"){s=s.toLowerCase();if(!(s in e.md.algorithms))throw'Unknown hash algorithm "'+s+'"';n=e.md.algorithms[s].create()}else n=s;if(o===null)o=t;else{if(typeof o=="string")o=e.util.createBuffer(o);else if(e.util.isArray(o)){var u=o;o=e.util.createBuffer();for(var a=0;a<u.length;++a)o.putByte(u[a])}var f=o.length();f>n.blockLength&&(n.start(),n.update(o.bytes()),o=n.digest()),r=e.util.createBuffer(),i=e.util.createBuffer(),f=o.length();for(var a=0;a<f;++a){var u=o.at(a);r.putByte(54^u),i.putByte(92^u)}if(f<n.blockLength){var u=n.blockLength-f;for(var a=0;a<u;++a)r.putByte(54),i.putByte(92)}t=o,r=r.bytes(),i=i.bytes()}n.start(),n.update(r)},s.update=function(e){n.update(e)},s.getMac=function(){var e=n.digest().bytes();return n.start(),n.update(i),n.update(e),n.digest()},s.digest=s.getMac,s}}var t="hmac";if(typeof define!="function"){if(typeof module!="object"||!module.exports)return typeof forge=="undefined"&&(forge={}),e(forge);var n=!0;define=function(e,t){t(require,module)}}var r,i=function(n,i){i.exports=function(i){var s=r.map(function(e){return n(e)}).concat(e);i=i||{},i.defined=i.defined||{};if(i.defined[t])return i[t];i.defined[t]=!0;for(var o=0;o<s.length;++o)s[o](i);return i[t]}},s=define;define=function(e,t){return r=typeof e=="string"?t.slice(2):e.slice(2),n?(delete define,s.apply(null,Array.prototype.slice.call(arguments,0))):(define=s,define.apply(null,Array.prototype.slice.call(arguments,0)))},define("forge/hmac",["require","module","./md","./util"],function(){i.apply(null,Array.prototype.slice.call(arguments,0))})}(),function(){function e(e,t,n){describe("hmac",function(){it('should md5 hash "Hi There", 16-byte key',function(){var r=n.hexToBytes("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b"),i=t.create();i.start("MD5",r),i.update("Hi There"),e.equal(i.digest().toHex(),"9294727a3638bb1c13f48ef8158bfc9d")}),it('should md5 hash "what do ya want for nothing?", "Jefe" key',function(){var n=t.create();n.start("MD5","Jefe"),n.update("what do ya want for nothing?"),e.equal(n.digest().toHex(),"750c783e6ab0b503eaa86e310a5db738")}),it('should md5 hash "Test Using Larger Than Block-Size Key - Hash Key First", 80-byte key',function(){var r=n.hexToBytes("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"),i=t.create();i.start("MD5",r),i.update("Test Using Larger Than Block-Size Key - Hash Key First"),e.equal(i.digest().toHex(),"6b1ab7fe4bd7bf8f0b62e6ce61b9d0cd")}),it('should sha1 hash "Hi There", 20-byte key',function(){var r=n.hexToBytes("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b"),i=t.create();i.start("SHA1",r),i.update("Hi There"),e.equal(i.digest().toHex(),"b617318655057264e28bc0b6fb378c8ef146be00")}),it('should sha1 hash "what do ya want for nothing?", "Jefe" key',function(){var n=t.create();n.start("SHA1","Jefe"),n.update("what do ya want for nothing?"),e.equal(n.digest().toHex(),"effcdf6ae5eb2fa2d27416d5f184df9c259a7c79")}),it('should sha1 hash "Test Using Larger Than Block-Size Key - Hash Key First", 80-byte key',function(){var r=n.hexToBytes("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"),i=t.create();i.start("SHA1",r),i.update("Test Using Larger Than Block-Size Key - Hash Key First"),e.equal(i.digest().toHex(),"aa4ae5e15272d00e95705637ce8a3b55ed402112")})})}typeof define=="function"?define("test/hmac",["forge/hmac","forge/util"],function(t,n){e(ASSERT,t(),n())}):typeof module=="object"&&module.exports&&e(require("assert"),require("../../js/hmac")(),require("../../js/util")())}(),function(){function e(e){var t=e.pkcs5=e.pkcs5||{};e.pbkdf2=t.pbkdf2=function(t,n,r,i,s){if(typeof s=="undefined"||s===null)s=e.md.sha1.create();var o=s.digestLength;if(i>4294967295*o)throw{message:"Derived key is too long."};var u=Math.ceil(i/o),a=i-(u-1)*o,f=e.hmac.create();f.start(s,t);var l="",c,h,p;for(var d=1;d<=u;++d){f.update(n),f.update(e.util.int32ToBytes(d)),c=p=f.digest().getBytes();for(var v=2;v<=r;++v)f.start(null,null),f.update(p),h=f.digest().getBytes(),c=e.util.xorBytes(c,h,o),p=h;l+=d<u?c:c.substr(0,a)}return l}}var t="pbkdf2";if(typeof define!="function"){if(typeof module!="object"||!module.exports)return typeof forge=="undefined"&&(forge={}),e(forge);var n=!0;define=function(e,t){t(require,module)}}var r,i=function(n,i){i.exports=function(i){var s=r.map(function(e){return n(e)}).concat(e);i=i||{},i.defined=i.defined||{};if(i.defined[t])return i[t];i.defined[t]=!0;for(var o=0;o<s.length;++o)s[o](i);return i[t]}},s=define;define=function(e,t){return r=typeof e=="string"?t.slice(2):e.slice(2),n?(delete define,s.apply(null,Array.prototype.slice.call(arguments,0))):(define=s,define.apply(null,Array.prototype.slice.call(arguments,0)))},define("forge/pbkdf2",["require","module","./hmac","./md","./util"],function(){i.apply(null,Array.prototype.slice.call(arguments,0))})}(),function(){function e(e,t,n){describe("pbkdf2",function(){it("should derive a password with hmac-sha-1 c=1",function(){var r=n.bytesToHex(t("password","salt",1,20));e.equal(r,"0c60c80f961f0e71f3a9b524af6012062fe037a6")}),it("should derive a password with hmac-sha-1 c=2",function(){var r=n.bytesToHex(t("password","salt",2,20));e.equal(r,"ea6c014dc72d6f8ccd1ed92ace1d41f0d8de8957")}),it("should derive a password with hmac-sha-1 c=5 keylen=8",function(){var r=n.hexToBytes("1234567878563412"),i=n.bytesToHex(t("password",r,5,8));e.equal(i,"d1daa78615f287e6")}),it("should derive a password with hmac-sha-1 c=4096",function(){var r=n.bytesToHex(t("password","salt",4096,20));e.equal(r,"4b007901b765489abead49d926f721d065a429c1")})})}typeof define=="function"?define("test/pbkdf2",["forge/pbkdf2","forge/util"],function(t,n){e(ASSERT,t(),n())}):typeof module=="object"&&module.exports&&e(require("assert"),require("../../js/pbkdf2")(),require("../../js/util")())}(),function(){function e(e){e.mgf=e.mgf||{};var t=e.mgf.mgf1=e.mgf1=e.mgf1||{};t.create=function(t){var n={generate:function(n,r){var i=new e.util.ByteBuffer,s=Math.ceil(r/t.digestLength);for(var o=0;o<s;o++){var u=new e.util.ByteBuffer;u.putInt32(o),t.start(),t.update(n+u.getBytes()),i.putBuffer(t.digest())}return i.truncate(i.length()-r),i.getBytes()}};return n}}var t="mgf1";if(typeof define!="function"){if(typeof module!="object"||!module.exports)return typeof forge=="undefined"&&(forge={}),e(forge);var n=!0;define=function(e,t){t(require,module)}}var r,i=function(n,i){i.exports=function(i){var s=r.map(function(e){return n(e)}).concat(e);i=i||{},i.defined=i.defined||{};if(i.defined[t])return i[t];i.defined[t]=!0;for(var o=0;o<s.length;++o)s[o](i);return i[t]}},s=define;define=function(e,t){return r=typeof e=="string"?t.slice(2):e.slice(2),n?(delete define,s.apply(null,Array.prototype.slice.call(arguments,0))):(define=s,define.apply(null,Array.prototype.slice.call(arguments,0)))},define("forge/mgf1",["require","module","./util"],function(){i.apply(null,Array.prototype.slice.call(arguments,0))})}(),function(){function e(e){e.mgf=e.mgf||{},e.mgf.mgf1=e.mgf1}var t="mgf";if(typeof define!="function"){if(typeof module!="object"||!module.exports)return typeof forge=="undefined"&&(forge={}),e(forge);var n=!0;define=function(e,t){t(require,module)}}var r,i=function(n,i){i.exports=function(i){var s=r.map(function(e){return n(e)}).concat(e);i=i||{},i.defined=i.defined||{};if(i.defined[t])return i[t];i.defined[t]=!0;for(var o=0;o<s.length;++o)s[o](i);return i[t]}},s=define;define=function(e,t){return r=typeof e=="string"?t.slice(2):e.slice(2),n?(delete define,s.apply(null,Array.prototype.slice.call(arguments,0))):(define=s,define.apply(null,Array.prototype.slice.call(arguments,0)))},define("forge/mgf",["require","module","./mgf1"],function(){i.apply(null,Array.prototype.slice.call(arguments,0))})}(),function(){function e(e,t,n,r){describe("mgf1",function(){it("should digest the empty string",function(){var i=r.hexToBytes("032e45326fa859a72ec235acff929b15d1372e30b207255f0611b8f785d764374152e0ac009e509e7ba30cd2f1778e113b64e135cf4e2292c75efe5288edfda4"),s=r.hexToBytes("5f8de105b5e96b2e490ddecbd147dd1def7e3b8e0e6a26eb7b956ccb8b3bdc1ca975bc57c3989e8fbad31a224655d800c46954840ff32052cdf0d640562bdfadfa263cfccf3c52b29f2af4a1869959bc77f854cf15bd7a25192985a842dbff8e13efee5b7e7e55bbe4d389647c686a9a9ab3fb889b2d7767d3837eea4e0a2f04"),o=t.mgf1.create(n.sha1.create()),u=o.generate(i,s.length);e.equal(u,s)})})}typeof define=="function"?define("test/mgf1",["forge/mgf","forge/md","forge/util"],function(t,n,r){e(ASSERT,t(),n(),r())}):typeof module=="object"&&module.exports&&e(require("assert"),require("../../js/mgf")(),require("../../js/md")(),require("../../js/util")())}(),function(){function e(e){var t=!1,n=4,r,i,s,o,u,a=function(){t=!0,s=[0,1,2,4,8,16,32,64,128,27,54];var e=new Array(256);for(var n=0;n<128;++n)e[n]=n<<1,e[n+128]=n+128<<1^283;r=new Array(256),i=new Array(256),o=new Array(4),u=new Array(4);for(var n=0;n<4;++n)o[n]=new Array(256),u[n]=new Array(256);var a=0,f=0,l,c,h,p,d,v,m;for(var n=0;n<256;++n){p=f^f<<1^f<<2^f<<3^f<<4,p=p>>8^p&255^99,r[a]=p,i[p]=a,d=e[p],l=e[a],c=e[l],h=e[c],v=d<<24^p<<16^p<<8^(p^d),m=(l^c^h)<<24^(a^h)<<16^(a^c^h)<<8^(a^l^h);for(var g=0;g<4;++g)o[g][a]=v,u[g][p]=m,v=v<<24|v>>>8,m=m<<24|m>>>8;a===0?a=f=1:(a=l^e[e[e[l^h]]],f^=e[e[f]])}},f=function(e,t){var i=e.slice(0),o,a=1,f=i.length,l=f+6+1,c=n*l;for(var h=f;h<c;++h)o=i[h-1],h%f===0?(o=r[o>>>16&255]<<24^r[o>>>8&255]<<16^r[o&255]<<8^r[o>>>24]^s[a]<<24,a++):f>6&&h%f===4&&(o=r[o>>>24]<<24^r[o>>>16&255]<<16^r[o>>>8&255]<<8^r[o&255]),i[h]=i[h-f]^o;if(t){var p,d=u[0],v=u[1],m=u[2],g=u[3],y=i.slice(0),c=i.length;for(var h=0,b=c-n;h<c;h+=n,b-=n)if(h===0||h===c-n)y[h]=i[b],y[h+1]=i[b+3],y[h+2]=i[b+2],y[h+3]=i[b+1];else for(var w=0;w<n;++w)p=i[b+w],y[h+(3&-w)]=d[r[p>>>24]]^v[r[p>>>16&255]]^m[r[p>>>8&255]]^g[r[p&255]];i=y}return i},l=function(e,t,n,s){var a=e.length/4-1,f,l,c,h,p;s?(f=u[0],l=u[1],c=u[2],h=u[3],p=i):(f=o[0],l=o[1],c=o[2],h=o[3],p=r);var d,v,m,g,y,b,w;d=t[0]^e[0],v=t[s?3:1]^e[1],m=t[2]^e[2],g=t[s?1:3]^e[3];var E=3;for(var S=1;S<a;++S)y=f[d>>>24]^l[v>>>16&255]^c[m>>>8&255]^h[g&255]^e[++E],b=f[v>>>24]^l[m>>>16&255]^c[g>>>8&255]^h[d&255]^e[++E],w=f[m>>>24]^l[g>>>16&255]^c[d>>>8&255]^h[v&255]^e[++E],g=f[g>>>24]^l[d>>>16&255]^c[v>>>8&255]^h[m&255]^e[++E],d=y,v=b,m=w;n[0]=p[d>>>24]<<24^p[v>>>16&255]<<16^p[m>>>8&255]<<8^p[g&255]^e[++E],n[s?3:1]=p[v>>>24]<<24^p[m>>>16&255]<<16^p[g>>>8&255]<<8^p[d&255]^e[++E],n[2]=p[m>>>24]<<24^p[g>>>16&255]<<16^p[d>>>8&255]<<8^p[v&255]^e[++E],n[s?1:3]=p[g>>>24]<<24^p[d>>>16&255]<<16^p[v>>>8&255]<<8^p[m&255]^e[++E]},c=function(r,i,s,o,u){function C(){if(o)for(var e=0;e<n;++e)E[e]=b.getInt32();else for(var e=0;e<n;++e)E[e]=x[e]^b.getInt32();l(g,E,S,o);if(o){for(var e=0;e<n;++e)w.putInt32(x[e]^S[e]);x=E.slice(0)}else{for(var e=0;e<n;++e)w.putInt32(S[e]);x=S}}function k(){l(g,E,S,!1);for(var e=0;e<n;++e)E[e]=b.getInt32();for(var e=0;e<n;++e){var t=E[e]^S[e];o||(E[e]=t),w.putInt32(t)}}function L(){l(g,E,S,!1);for(var e=0;e<n;++e)E[e]=b.getInt32();for(var e=0;e<n;++e)w.putInt32(E[e]^S[e]),E[e]=S[e]}function A(){l(g,E,S,!1);for(var e=n-1;e>=0;--e){if(E[e]!==4294967295){++E[e];break}E[e]=0}for(var e=0;e<n;++e)w.putInt32(b.getInt32()^S[e])}var c=null;t||a(),u=(u||"CBC").toUpperCase();if(typeof r!="string"||r.length!==16&&r.length!==24&&r.length!==32){if(e.util.isArray(r)&&(r.length===16||r.length===24||r.length===32)){var h=r,r=e.util.createBuffer();for(var p=0;p<h.length;++p)r.putByte(h[p])}}else r=e.util.createBuffer(r);if(!e.util.isArray(r)){var h=r;r=[];var d=h.length();if(d===16||d===24||d===32){d>>>=2;for(var p=0;p<d;++p)r.push(h.getInt32())}}if(!e.util.isArray(r)||r.length!==4&&r.length!==6&&r.length!==8)return c;var v=["CFB","OFB","CTR"].indexOf(u)!==-1,m=u==="CBC",g=f(r,o&&!v),y=n<<2,b,w,E,S,x,T,N;c={output:null};if(u==="CBC")N=C;else if(u==="CFB")N=k;else if(u==="OFB")N=L;else{if(u!=="CTR")throw{message:'Unsupported block cipher mode of operation: "'+u+'"'};N=A}return c.update=function(e){T||b.putBuffer(e);while(b.length()>=y||b.length()>0&&T)N()},c.finish=function(e){var t=!0,r=b.length()%y;if(!o)if(e)t=e(y,b,o);else if(m){var i=b.length()===y?y:y-b.length();b.fillWithByte(i,i)}t&&(T=!0,c.update());if(o){m&&(t=r===0);if(t)if(e)t=e(y,w,o);else if(m){var s=w.length(),u=w.at(s-1);u>n<<2?t=!1:w.truncate(u)}}return!m&&!e&&r>0&&w.truncate(y-r),t},c.start=function(t,r){t===null&&(t=x.slice(0));if(typeof t=="string"&&t.length===16)t=e.util.createBuffer(t);else if(e.util.isArray(t)&&t.length===16){var i=t,t=e.util.createBuffer();for(var s=0;s<16;++s)t.putByte(i[s])}if(!e.util.isArray(t)){var i=t;t=new Array(4),t[0]=i.getInt32(),t[1]=i.getInt32(),t[2]=i.getInt32(),t[3]=i.getInt32()}b=e.util.createBuffer(),w=r||e.util.createBuffer(),x=t.slice(0),E=new Array(n),S=new Array(n),T=!1,c.output=w;if(["CFB","OFB","CTR"].indexOf(u)!==-1){for(var s=0;s<n;++s)E[s]=x[s];x=null}},i!==null&&c.start(i,s),c};e.aes=e.aes||{},e.aes.startEncrypting=function(e,t,n,r){return c(e,t,n,!1,r)},e.aes.createEncryptionCipher=function(e,t){return c(e,null,null,!1,t)},e.aes.startDecrypting=function(e,t,n,r){return c(e,t,n,!0,r)},e.aes.createDecryptionCipher=function(e,t){return c(e,null,null,!0,t)},e.aes._expandKey=function(e,n){return t||a(),f(e,n)},e.aes._updateBlock=l}var t="aes";if(typeof define!="function"){if(typeof module!="object"||!module.exports)return typeof forge=="undefined"&&(forge={}),e(forge);var n=!0;define=function(e,t){t(require,module)}}var r,i=function(n,i){i.exports=function(i){var s=r.map(function(e){return n(e)}).concat(e);i=i||{},i.defined=i.defined||{};if(i.defined[t])return i[t];i.defined[t]=!0;for(var o=0;o<s.length;++o)s[o](i);return i[t]}},s=define;define=function(e,t){return r=typeof e=="string"?t.slice(2):e.slice(2),n?(delete define,s.apply(null,Array.prototype.slice.call(arguments,0))):(define=s,define.apply(null,Array.prototype.slice.call(arguments,0)))},define("forge/aes",["require","module","./util"],function(){i.apply(null,Array.prototype.slice.call(arguments,0))})}(),function(){function e(e){var t=typeof process!="undefined"&&process.versions&&process.versions.node,n=null;!e.disableNativeCode&&t&&(n=require("crypto"));var r=e.prng=e.prng||{};r.create=function(t){function u(e){if(r.pools[0].messageLength>=32)return f(),e();var t=32-r.pools[0].messageLength<<5;r.seedFile(t,function(t,n){if(t)return e(t);r.collect(n),f(),e()})}function a(){if(r.pools[0].messageLength>=32)return f();var e=32-r.pools[0].messageLength<<5;r.collect(r.seedFileSync(e)),f()}function f(){var t=e.md.sha1.create();t.update(r.pools[0].digest().getBytes()),r.pools[0].start();var n=1;for(var i=1;i<32;++i)n=n===31?2147483648:n<<2,n%r.reseeds===0&&(t.update(r.pools[i].digest().getBytes()),r.pools[i].start());var s=t.digest().getBytes();t.start(),t.update(s);var o=t.digest().getBytes();r.key=r.plugin.formatKey(s),r.seed=r.plugin.formatSeed(o),++r.reseeds,r.generated=0,r.time=+(new Date)}function l(t){var n=e.util.createBuffer();if(typeof window!="undefined"&&window.crypto&&window.crypto.getRandomValues){var r=new Uint32Array(t/4);try{window.crypto.getRandomValues(r);for(var i=0;i<r.length;++i)n.putInt32(r[i])}catch(s){}}if(n.length()<t){var o,u,a,f=Math.floor(Math.random()*65535);while(n.length()<t){u=16807*(f&65535),o=16807*(f>>16),u+=(o&32767)<<16,u+=o>>15,u=(u&2147483647)+(u>>31),f=u&4294967295;for(var i=0;i<3;++i)a=f>>>(i<<3),a^=Math.floor(Math.random()*255),n.putByte(String.fromCharCode(a&255))}}return n.getBytes()}var r={plugin:t,key:null,seed:null,time:null,reseeds:0,generated:0},i=t.md,s=new Array(32);for(var o=0;o<32;++o)s[o]=i.create();return r.pools=s,r.pool=0,r.generate=function(t,n){function l(c){if(c)return n(c);if(f.length()>=t)return n(null,f.getBytes(t));if(r.generated>=1048576){var h=+(new Date);if(r.time===null||h-r.time>100)r.key=null}if(r.key===null)return u(l);var p=i(r.key,r.seed);r.generated+=p.length,f.putBytes(p),r.key=o(i(r.key,s(r.seed))),r.seed=a(i(r.key,r.seed)),e.util.setImmediate(l)}if(!n)return r.generateSync(t);var i=r.plugin.cipher,s=r.plugin.increment,o=r.plugin.formatKey,a=r.plugin.formatSeed,f=e.util.createBuffer();l()},r.generateSync=function(t){var n=r.plugin.cipher,i=r.plugin.increment,s=r.plugin.formatKey,o=r.plugin.formatSeed,u=e.util.createBuffer();while(u.length()<t){if(r.generated>=1048576){var f=+(new Date);if(r.time===null||f-r.time>100)r.key=null}r.key===null&&a();var l=n(r.key,r.seed);r.generated+=l.length,u.putBytes(l),r.key=s(n(r.key,i(r.seed))),r.seed=o(n(r.key,r.seed))}return u.getBytes(t)},n?(r.seedFile=function(e,t){n.randomBytes(e,function(e,n){if(e)return t(e);t(null,n.toString())})},r.seedFileSync=function(e){return n.randomBytes(e).toString()}):(r.seedFile=function(e,t){try{t(null,l(e))}catch(n){t(n)}},r.seedFileSync=l),r.collect=function(e){var t=e.length;for(var n=0;n<t;++n)r.pools[r.pool].update(e.substr(n,1)),r.pool=r.pool===31?0:r.pool+1},r.collectInt=function(e,t){var n="";for(var i=0;i<t;i+=8)n+=String.fromCharCode(e>>i&255);r.collect(n)},r.registerWorker=function(e){if(e===self)r.seedFile=function(e,t){function n(e){var r=e.data;r.forge&&r.forge.prng&&(self.removeEventListener("message",n),t(r.forge.prng.err,r.forge.prng.bytes))}self.addEventListener("message",n),self.postMessage({forge:{prng:{needed:e}}})};else{function t(t){var n=t.data;n.forge&&n.forge.prng&&r.seedFile(n.forge.prng.needed,function(t,n){e.postMessage({forge:{prng:{err:t,bytes:n}}})})}e.addEventListener("message",t)}},r}}var t="prng";if(typeof define!="function"){if(typeof module!="object"||!module.exports)return typeof forge=="undefined"&&(forge={}),e(forge);var n=!0;define=function(e,t){t(require,module)}}var r,i=function(n,i){i.exports=function(i){var s=r.map(function(e){return n(e)}).concat(e);i=i||{},i.defined=i.defined||{};if(i.defined[t])return i[t];i.defined[t]=!0;for(var o=0;o<s.length;++o)s[o](i);return i[t]}},s=define;define=function(e,t){return r=typeof e=="string"?t.slice(2):e.slice(2),n?(delete define,s.apply(null,Array.prototype.slice.call(arguments,0))):(define=s,define.apply(null,Array.prototype.slice.call(arguments,0)))},define("forge/prng",["require","module","./md","./util"],function(){i.apply(null,Array.prototype.slice.call(arguments,0))})}(),function(){function e(e){if(e.random&&e.random.getBytes)return;(function(t){var n={},r=new Array(4),i=e.util.createBuffer();n.formatKey=function(t){var n=e.util.createBuffer(t);return t=new Array(4),t[0]=n.getInt32(),t[1]=n.getInt32(),t[2]=n.getInt32(),t[3]=n.getInt32(),e.aes._expandKey(t,!1)},n.formatSeed=function(t){var n=e.util.createBuffer(t);return t=new Array(4),t[0]=n.getInt32(),t[1]=n.getInt32(),t[2]=n.getInt32(),t[3]=n.getInt32(),t},n.cipher=function(t,n){return e.aes._updateBlock(t,n,r,!1),i.putInt32(r[0]),i.putInt32(r[1]),i.putInt32(r[2]),i.putInt32(r[3]),i.getBytes()},n.increment=function(e){return++e[3],e},n.md=e.md.sha1;var s=e.prng.create(n),o=typeof process!="undefined"&&process.versions&&process.versions.node;if(e.disableNativeCode||!o&&(typeof window=="undefined"||!window.crypto||!window.crypto.getRandomValues)){typeof window=="undefined"||window.document===undefined,s.collectInt(+(new Date),32);if(typeof navigator!="undefined"){var u="";for(var a in navigator)try{typeof navigator[a]=="string"&&(u+=navigator[a])}catch(f){}s.collect(u),u=null}t&&(t().mousemove(function(e){s.collectInt(e.clientX,16),s.collectInt(e.clientY,16)}),t().keypress(function(e){s.collectInt(e.charCode,8)}))}if(!e.random)e.random=s;else for(var a in s)e.random[a]=s[a];e.random.getBytes=function(t,n){return e.random.generate(t,n)},e.random.getBytesSync=function(t){return e.random.generate(t)}})(typeof jQuery!="undefined"?jQuery:null)}var t="random";if(typeof define!="function"){if(typeof module!="object"||!module.exports)return typeof forge=="undefined"&&(forge={}),e(forge);var n=!0;define=function(e,t){t(require,module)}}var r,i=function(n,i){i.exports=function(i){var s=r.map(function(e){return n(e)}).concat(e);i=i||{},i.defined=i.defined||{};if(i.defined[t])return i[t];i.defined[t]=!0;for(var o=0;o<s.length;++o)s[o](i);return i[t]}},s=define;define=function(e,t){return r=typeof e=="string"?t.slice(2):e.slice(2),n?(delete define,s.apply(null,Array.prototype.slice.call(arguments,0))):(define=s,define.apply(null,Array.prototype.slice.call(arguments,0)))},define("forge/random",["require","module","./aes","./md","./prng","./util"],function(){i.apply(null,Array.prototype.slice.call(arguments,0))})}(),function(){function e(e,t,n){var r=t();describe("random",function(){it("should generate 10 random bytes",function(){r.getBytes(16),r.getBytes(24),r.getBytes(32);var t=r.getBytes(10);e.equal(t.length,10)}),it("should use a synchronous seed file",function(){var r=t();r.seedFileSync=function(e){return n.fillString("a",e)};var i=r.getBytes(10);e.equal(n.bytesToHex(i),"a44857544b3df0fcac84")}),it("should use an asynchronous seed file",function(r){var i=t();i.seedFile=function(e,t){t(null,n.fillString("a",e))},i.getBytes(10,function(t,i){e.equal(t,null),e.equal(n.bytesToHex(i),"a44857544b3df0fcac84"),r()})}),it("should collect some random bytes",function(){var r=t();r.seedFileSync=function(e){return n.fillString("a",e)},r.collect("bbb");var i=r.getBytes(10);e.equal(n.bytesToHex(i),"8274fa6e0a192d670ddb")})})}typeof define=="function"?define("test/random",["forge/random","forge/util"],function(t,n){e(ASSERT,t,n())}):typeof module=="object"&&module.exports&&e(require("assert"),require("../../js/random"),require("../../js/util")())}(),function(){function e(e){e.pki=e.pki||{};var t=e.pki.oids=e.oids=e.oids||{};t["1.2.840.113549.1.1.1"]="rsaEncryption",t.rsaEncryption="1.2.840.113549.1.1.1",t["1.2.840.113549.1.1.4"]="md5WithRSAEncryption",t.md5WithRSAEncryption="1.2.840.113549.1.1.4",t["1.2.840.113549.1.1.5"]="sha1WithRSAEncryption",t.sha1WithRSAEncryption="1.2.840.113549.1.1.5",t["1.2.840.113549.1.1.7"]="RSAES-OAEP",t["RSAES-OAEP"]="1.2.840.113549.1.1.7",t["1.2.840.113549.1.1.8"]="mgf1",t.mgf1="1.2.840.113549.1.1.8",t["1.2.840.113549.1.1.9"]="pSpecified",t.pSpecified="1.2.840.113549.1.1.9",t["1.2.840.113549.1.1.10"]="RSASSA-PSS",t["RSASSA-PSS"]="1.2.840.113549.1.1.10",t["1.2.840.113549.1.1.11"]="sha256WithRSAEncryption",t.sha256WithRSAEncryption="1.2.840.113549.1.1.11",t["1.2.840.113549.1.1.12"]="sha384WithRSAEncryption",t.sha384WithRSAEncryption="1.2.840.113549.1.1.12",t["1.2.840.113549.1.1.13"]="sha512WithRSAEncryption",t.sha512WithRSAEncryption="1.2.840.113549.1.1.13",t["1.3.14.3.2.26"]="sha1",t.sha1="1.3.14.3.2.26",t["2.16.840.1.101.3.4.2.1"]="sha256",t.sha256="2.16.840.1.101.3.4.2.1",t["2.16.840.1.101.3.4.2.2"]="sha384",t.sha384="2.16.840.1.101.3.4.2.2",t["2.16.840.1.101.3.4.2.3"]="sha512",t.sha512="2.16.840.1.101.3.4.2.3",t["1.2.840.113549.2.5"]="md5",t.md5="1.2.840.113549.2.5",t["1.2.840.113549.1.7.1"]="data",t.data="1.2.840.113549.1.7.1",t["1.2.840.113549.1.7.2"]="signedData",t.signedData="1.2.840.113549.1.7.2",t["1.2.840.113549.1.7.3"]="envelopedData",t.envelopedData="1.2.840.113549.1.7.3",t["1.2.840.113549.1.7.4"]="signedAndEnvelopedData",t.signedAndEnvelopedData="1.2.840.113549.1.7.4",t["1.2.840.113549.1.7.5"]="digestedData",t.digestedData="1.2.840.113549.1.7.5",t["1.2.840.113549.1.7.6"]="encryptedData",t.encryptedData="1.2.840.113549.1.7.6",t["1.2.840.113549.1.9.1"]="emailAddress",t.emailAddress="1.2.840.113549.1.9.1",t["1.2.840.113549.1.9.2"]="unstructuredName",t.unstructuredName="1.2.840.113549.1.9.2",t["1.2.840.113549.1.9.3"]="contentType",t.contentType="1.2.840.113549.1.9.3",t["1.2.840.113549.1.9.4"]="messageDigest",t.messageDigest="1.2.840.113549.1.9.4",t["1.2.840.113549.1.9.5"]="signingTime",t.signingTime="1.2.840.113549.1.9.5",t["1.2.840.113549.1.9.6"]="counterSignature",t.counterSignature="1.2.840.113549.1.9.6",t["1.2.840.113549.1.9.7"]="challengePassword",t.challengePassword="1.2.840.113549.1.9.7",t["1.2.840.113549.1.9.8"]="unstructuredAddress",t.unstructuredAddress="1.2.840.113549.1.9.8",t["1.2.840.113549.1.9.20"]="friendlyName",t.friendlyName="1.2.840.113549.1.9.20",t["1.2.840.113549.1.9.21"]="localKeyId",t.localKeyId="1.2.840.113549.1.9.21",t["1.2.840.113549.1.9.22.1"]="x509Certificate",t.x509Certificate="1.2.840.113549.1.9.22.1",t["1.2.840.113549.1.12.10.1.1"]="keyBag",t.keyBag="1.2.840.113549.1.12.10.1.1",t["1.2.840.113549.1.12.10.1.2"]="pkcs8ShroudedKeyBag",t.pkcs8ShroudedKeyBag="1.2.840.113549.1.12.10.1.2",t["1.2.840.113549.1.12.10.1.3"]="certBag",t.certBag="1.2.840.113549.1.12.10.1.3",t["1.2.840.113549.1.12.10.1.4"]="crlBag",t.crlBag="1.2.840.113549.1.12.10.1.4",t["1.2.840.113549.1.12.10.1.5"]="secretBag",t.secretBag="1.2.840.113549.1.12.10.1.5",t["1.2.840.113549.1.12.10.1.6"]="safeContentsBag",t.safeContentsBag="1.2.840.113549.1.12.10.1.6",t["1.2.840.113549.1.5.13"]="pkcs5PBES2",t.pkcs5PBES2="1.2.840.113549.1.5.13",t["1.2.840.113549.1.5.12"]="pkcs5PBKDF2",t.pkcs5PBKDF2="1.2.840.113549.1.5.12",t["1.2.840.113549.1.12.1.1"]="pbeWithSHAAnd128BitRC4",t.pbeWithSHAAnd128BitRC4="1.2.840.113549.1.12.1.1",t["1.2.840.113549.1.12.1.2"]="pbeWithSHAAnd40BitRC4",t.pbeWithSHAAnd40BitRC4="1.2.840.113549.1.12.1.2",t["1.2.840.113549.1.12.1.3"]="pbeWithSHAAnd3-KeyTripleDES-CBC",t["pbeWithSHAAnd3-KeyTripleDES-CBC"]="1.2.840.113549.1.12.1.3",t["1.2.840.113549.1.12.1.4"]="pbeWithSHAAnd2-KeyTripleDES-CBC",t["pbeWithSHAAnd2-KeyTripleDES-CBC"]="1.2.840.113549.1.12.1.4",t["1.2.840.113549.1.12.1.5"]="pbeWithSHAAnd128BitRC2-CBC",t["pbeWithSHAAnd128BitRC2-CBC"]="1.2.840.113549.1.12.1.5",t["1.2.840.113549.1.12.1.6"]="pbewithSHAAnd40BitRC2-CBC",t["pbewithSHAAnd40BitRC2-CBC"]="1.2.840.113549.1.12.1.6",t["1.2.840.113549.3.7"]="des-EDE3-CBC",t["des-EDE3-CBC"]="1.2.840.113549.3.7",t["2.16.840.1.101.3.4.1.2"]="aes128-CBC",t["aes128-CBC"]="2.16.840.1.101.3.4.1.2",t["2.16.840.1.101.3.4.1.22"]="aes192-CBC",t["aes192-CBC"]="2.16.840.1.101.3.4.1.22",t["2.16.840.1.101.3.4.1.42"]="aes256-CBC",t["aes256-CBC"]="2.16.840.1.101.3.4.1.42",t["2.5.4.3"]="commonName",t.commonName="2.5.4.3",t["2.5.4.5"]="serialName",t.serialName="2.5.4.5",t["2.5.4.6"]="countryName",t.countryName="2.5.4.6",t["2.5.4.7"]="localityName",t.localityName="2.5.4.7",t["2.5.4.8"]="stateOrProvinceName",t.stateOrProvinceName="2.5.4.8",t["2.5.4.10"]="organizationName",t.organizationName="2.5.4.10",t["2.5.4.11"]="organizationalUnitName",t.organizationalUnitName="2.5.4.11",t["2.16.840.1.113730.1.1"]="nsCertType",t.nsCertType="2.16.840.1.113730.1.1",t["2.5.29.1"]="authorityKeyIdentifier",t["2.5.29.2"]="keyAttributes",t["2.5.29.3"]="certificatePolicies",t["2.5.29.4"]="keyUsageRestriction",t["2.5.29.5"]="policyMapping",t["2.5.29.6"]="subtreesConstraint",t["2.5.29.7"]="subjectAltName",t["2.5.29.8"]="issuerAltName",t["2.5.29.9"]="subjectDirectoryAttributes",t["2.5.29.10"]="basicConstraints",t["2.5.29.11"]="nameConstraints",t["2.5.29.12"]="policyConstraints",t["2.5.29.13"]="basicConstraints",t["2.5.29.14"]="subjectKeyIdentifier",t.subjectKeyIdentifier="2.5.29.14",t["2.5.29.15"]="keyUsage",t.keyUsage="2.5.29.15",t["2.5.29.16"]="privateKeyUsagePeriod",t["2.5.29.17"]="subjectAltName",t.subjectAltName="2.5.29.17",t["2.5.29.18"]="issuerAltName",t.issuerAltName="2.5.29.18",t["2.5.29.19"]="basicConstraints",t.basicConstraints="2.5.29.19",t["2.5.29.20"]="cRLNumber",t["2.5.29.21"]="cRLReason",t["2.5.29.22"]="expirationDate",t["2.5.29.23"]="instructionCode",t["2.5.29.24"]="invalidityDate",t["2.5.29.25"]="cRLDistributionPoints",t["2.5.29.26"]="issuingDistributionPoint",t["2.5.29.27"]="deltaCRLIndicator",t["2.5.29.28"]="issuingDistributionPoint",t["2.5.29.29"]="certificateIssuer",t["2.5.29.30"]="nameConstraints",t["2.5.29.31"]="cRLDistributionPoints",t["2.5.29.32"]="certificatePolicies",t["2.5.29.33"]="policyMappings",t["2.5.29.34"]="policyConstraints",t["2.5.29.35"]="authorityKeyIdentifier",t["2.5.29.36"]="policyConstraints",t["2.5.29.37"]="extKeyUsage",t.extKeyUsage="2.5.29.37",t["2.5.29.46"]="freshestCRL",t["2.5.29.54"]="inhibitAnyPolicy",t["1.3.6.1.5.5.7.3.1"]="serverAuth",t.serverAuth="1.3.6.1.5.5.7.3.1",t["1.3.6.1.5.5.7.3.2"]="clientAuth",t.clientAuth="1.3.6.1.5.5.7.3.2",t["1.3.6.1.5.5.7.3.3"]="codeSigning",t.codeSigning="1.3.6.1.5.5.7.3.3",t["1.3.6.1.5.5.7.3.4"]="emailProtection",t.emailProtection="1.3.6.1.5.5.7.3.4",t["1.3.6.1.5.5.7.3.8"]="timeStamping",t.timeStamping="1.3.6.1.5.5.7.3.8"}var t="oids";if(typeof define!="function"){if(typeof module!="object"||!module.exports)return typeof forge=="undefined"&&(forge={}),e(forge);var n=!0;define=function(e,t){t(require,module)}}var r,i=function(n,i){i.exports=function(i){var s=r.map(function(e){return n(e)}).concat(e);i=i||{},i.defined=i.defined||{};if(i.defined[t])return i[t];i.defined[t]=!0;for(var o=0;o<s.length;++o)s[o](i);return i[t]}},s=define;define=function(e,t){return r=typeof e=="string"?t.slice(2):e.slice(2),n?(delete define,s.apply(null,Array.prototype.slice.call(arguments,0))):(define=s,define.apply(null,Array.prototype.slice.call(arguments,0)))},define("forge/oids",["require","module"],function(){i.apply(null,Array.prototype.slice.call(arguments,0))})}(),function(){function e(e){var t=e.asn1=e.asn1||{};t.Class={UNIVERSAL:0,APPLICATION:64,CONTEXT_SPECIFIC:128,PRIVATE:192},t.Type={NONE:0,BOOLEAN:1,INTEGER:2,BITSTRING:3,OCTETSTRING:4,NULL:5,OID:6,ODESC:7,EXTERNAL:8,REAL:9,ENUMERATED:10,EMBEDDED:11,UTF8:12,ROID:13,SEQUENCE:16,SET:17,PRINTABLESTRING:19,IA5STRING:22,UTCTIME:23,GENERALIZEDTIME:24,BMPSTRING:30},t.create=function(t,n,r,i){if(e.util.isArray(i)){var s=[];for(var o=0;o<i.length;++o)i[o]!==undefined&&s.push(i[o]);i=s}return{tagClass:t,type:n,constructed:r,composed:r||e.util.isArray(i),value:i}};var n=function(e){var t=e.getByte();if(t===128)return undefined;var n,r=t&128;return r?n=e.getInt((t&127)<<3):n=t,n};t.fromDer=function(r,i){i===undefined&&(i=!0),typeof r=="string"&&(r=e.util.createBuffer(r));if(r.length()<2)throw{message:"Too few bytes to parse DER.",bytes:r.length()};var s=r.getByte(),o=s&192,u=s&31,a=n(r);if(r.length()<a){if(i)throw{message:"Too few bytes to read ASN.1 value.",detail:r.length()+" < "+a};a=r.length()}var f,l=(s&32)===32,c=l;if(!c&&o===t.Class.UNIVERSAL&&u===t.Type.BITSTRING&&a>1){var h=r.read,p=r.getByte();if(p===0){s=r.getByte();var d=s&192;if(d===t.Class.UNIVERSAL||d===t.Class.CONTEXT_SPECIFIC)try{var v=n(r);c=v===a-(r.read-h),c&&(++h,--a)}catch(m){}}r.read=h}if(c){f=[];if(a===undefined)for(;;){if(r.bytes(2)===String.fromCharCode(0,0)){r.getBytes(2);break}f.push(t.fromDer(r,i))}else{var g=r.length();while(a>0)f.push(t.fromDer(r,i)),a-=g-r.length(),g=r.length()}}else{if(a===undefined)throw{message:"Non-constructed ASN.1 object of indefinite length."};if(u===t.Type.BMPSTRING){f="";for(var y=0;y<a;y+=2)f+=String.fromCharCode(r.getInt16())}else f=r.getBytes(a)}return t.create(o,u,l,f)},t.toDer=function(n){var r=e.util.createBuffer(),i=n.tagClass|n.type,s=e.util.createBuffer();if(n.composed){n.constructed?i|=32:s.putByte(0);for(var o=0;o<n.value.length;++o)n.value[o]!==undefined&&s.putBuffer(t.toDer(n.value[o]))}else if(n.type===t.Type.BMPSTRING)for(var o=0;o<n.value.length;++o)s.putInt16(n.value.charCodeAt(o));else s.putBytes(n.value);r.putByte(i);if(s.length()<=127)r.putByte(s.length()&127);else{var u=s.length(),a="";do a+=String.fromCharCode(u&255),u>>>=8;while(u>0);r.putByte(a.length|128);for(var o=a.length-1;o>=0;--o)r.putByte(a.charCodeAt(o))}return r.putBuffer(s),r},t.oidToDer=function(t){var n=t.split("."),r=e.util.createBuffer();r.putByte(40*parseInt(n[0],10)+parseInt(n[1],10));var i,s,o,u;for(var a=2;a<n.length;++a){i=!0,s=[],o=parseInt(n[a],10);do u=o&127,o>>>=7,i||(u|=128),s.push(u),i=!1;while(o>0);for(var f=s.length-1;f>=0;--f)r.putByte(s[f])}return r},t.derToOid=function(t){var n;typeof t=="string"&&(t=e.util.createBuffer(t));var r=t.getByte();n=Math.floor(r/40)+"."+r%40;var i=0;while(t.length()>0)r=t.getByte(),i<<=7,r&128?i+=r&127:(n+="."+(i+r),i=0);return n},t.utcTimeToDate=function(e){var t=new Date,n=parseInt(e.substr(0,2),10);n=n>=50?1900+n:2e3+n;var r=parseInt(e.substr(2,2),10)-1,i=parseInt(e.substr(4,2),10),s=parseInt(e.substr(6,2),10),o=parseInt(e.substr(8,2),10),u=0;if(e.length>11){var a=e.charAt(10),f=10;a!=="+"&&a!=="-"&&(u=parseInt(e.substr(10,2),10),f+=2)}t.setUTCFullYear(n,r,i),t.setUTCHours(s,o,u,0);if(f){a=e.charAt(f);if(a==="+"||a==="-"){var l=parseInt(e.substr(f+1,2),10),c=parseInt(e.substr(f+4,2),10),h=l*60+c;h*=6e4,a==="+"?t.setTime(+t-h):t.setTime(+t+h)}}return t},t.generalizedTimeToDate=function(e){var t=new Date,n=parseInt(e.substr(0,4),10),r=parseInt(e.substr(4,2),10)-1,i=parseInt(e.substr(6,2),10),s=parseInt(e.substr(8,2),10),o=parseInt(e.substr(10,2),10),u=parseInt(e.substr(12,2),10),a=0,f=0,l=!1;e.charAt(e.length-1)==="Z"&&(l=!0);var c=e.length-5,h=e.charAt(c);if(h==="+"||h==="-"){var p=parseInt(e.substr(c+1,2),10),d=parseInt(e.substr(c+4,2),10);f=p*60+d,f*=6e4,h==="+"&&(f*=-1),l=!0}return e.charAt(14)==="."&&(a=parseFloat(e.substr(14),10)*1e3),l?(t.setUTCFullYear(n,r,i),t.setUTCHours(s,o,u,a),t.setTime(+t+f)):(t.setFullYear(n,r,i),t.setHours(s,o,u,a)),t},t.dateToUtcTime=function(e){var t="",n=[];n.push((""+e.getUTCFullYear()).substr(2)),n.push(""+(e.getUTCMonth()+1)),n.push(""+e.getUTCDate()),n.push(""+e.getUTCHours()),n.push(""+e.getUTCMinutes()),n.push(""+e.getUTCSeconds());for(var r=0;r<n.length;++r)n[r].length<2&&(t+="0"),t+=n[r];return t+="Z",t},t.validate=function(n,r,i,s){var o=!1;if(n.tagClass!==r.tagClass&&typeof r.tagClass!="undefined"||n.type!==r.type&&typeof r.type!="undefined")s&&(n.tagClass!==r.tagClass&&s.push("["+r.name+"] "+'Expected tag class "'+r.tagClass+'", got "'+n.tagClass+'"'),n.type!==r.type&&s.push("["+r.name+"] "+'Expected type "'+r.type+'", got "'+n.type+'"'));else if(n.constructed===r.constructed||typeof r.constructed=="undefined"){o=!0;if(r.value&&e.util.isArray(r.value)){var u=0;for(var a=0;o&&a<r.value.length;++a)o=r.value[a].optional||!1,n.value[u]&&(o=t.validate(n.value[u],r.value[a],i,s),o?++u:r.value[a].optional&&(o=!0)),!o&&s&&s.push("["+r.name+"] "+'Tag class "'+r.tagClass+'", type "'+r.type+'" expected value length "'+r.value.length+'", got "'+n.value.length+'"')}o&&i&&(r.capture&&(i[r.capture]=n.value),r.captureAsn1&&(i[r.captureAsn1]=n))}else s&&s.push("["+r.name+"] "+'Expected constructed "'+r.constructed+'", got "'+n.constructed+'"');return o};var r=/[^\\u0000-\\u00ff]/;t.prettyPrint=function(n,i,s){var o="";i=i||0,s=s||2,i>0&&(o+="\n");var u="";for(var a=0;a<i*s;++a)u+=" ";o+=u+"Tag: ";switch(n.tagClass){case t.Class.UNIVERSAL:o+="Universal:";break;case t.Class.APPLICATION:o+="Application:";break;case t.Class.CONTEXT_SPECIFIC:o+="Context-Specific:";break;case t.Class.PRIVATE:o+="Private:"}if(n.tagClass===t.Class.UNIVERSAL){o+=n.type;switch(n.type){case t.Type.NONE:o+=" (None)";break;case t.Type.BOOLEAN:o+=" (Boolean)";break;case t.Type.BITSTRING:o+=" (Bit string)";break;case t.Type.INTEGER:o+=" (Integer)";break;case t.Type.OCTETSTRING:o+=" (Octet string)";break;case t.Type.NULL:o+=" (Null)";break;case t.Type.OID:o+=" (Object Identifier)";break;case t.Type.ODESC:o+=" (Object Descriptor)";break;case t.Type.EXTERNAL:o+=" (External or Instance of)";break;case t.Type.REAL:o+=" (Real)";break;case t.Type.ENUMERATED:o+=" (Enumerated)";break;case t.Type.EMBEDDED:o+=" (Embedded PDV)";break;case t.Type.UTF8:o+=" (UTF8)";break;case t.Type.ROID:o+=" (Relative Object Identifier)";break;case t.Type.SEQUENCE:o+=" (Sequence)";break;case t.Type.SET:o+=" (Set)";break;case t.Type.PRINTABLESTRING:o+=" (Printable String)";break;case t.Type.IA5String:o+=" (IA5String (ASCII))";break;case t.Type.UTCTIME:o+=" (UTC time)";break;case t.Type.GENERALIZEDTIME:o+=" (Generalized time)";break;case t.Type.BMPSTRING:o+=" (BMP String)"}}else o+=n.type;o+="\n",o+=u+"Constructed: "+n.constructed+"\n";if(n.composed){var f=0,l="";for(var a=0;a<n.value.length;++a)n.value[a]!==undefined&&(f+=1,l+=t.prettyPrint(n.value[a],i+1,s),a+1<n.value.length&&(l+=","));o+=u+"Sub values: "+f+l}else{o+=u+"Value: ";if(n.type===t.Type.OID){var c=t.derToOid(n.value);o+=c,e.pki&&e.pki.oids&&c in e.pki.oids&&(o+=" ("+e.pki.oids[c]+")")}else r.test(n.value)?o+="0x"+e.util.createBuffer(n.value,"utf8").toHex():n.value.length===0?o+="[null]":o+=n.value}return o}}var t="asn1";if(typeof define!="function"){if(typeof module!="object"||!module.exports)return typeof forge=="undefined"&&(forge={}),e(forge);var n=!0;define=function(e,t){t(require,module)}}var r,i=function(n,i){i.exports=function(i){var s=r.map(function(e){return n(e)}).concat(e);i=i||{},i.defined=i.defined||{};if(i.defined[t])return i[t];i.defined[t]=!0;for(var o=0;o<s.length;++o)s[o](i);return i[t]}},s=define;define=function(e,t){return r=typeof e=="string"?t.slice(2):e.slice(2),n?(delete define,s.apply(null,Array.prototype.slice.call(arguments,0))):(define=s,define.apply(null,Array.prototype.slice.call(arguments,0)))},define("forge/asn1",["require","module","./util","./oids"],function(){i.apply(null,Array.prototype.slice.call(arguments,0))})}(),function(){function e(e,t,n){describe("asn1",function(){it("should convert an OID to DER",function(){e.equal(t.oidToDer("1.2.840.113549").toHex(),"2a864886f70d")}),it("should convert an OID from DER",function(){var r=n.hexToBytes("2a864886f70d");e.equal(t.derToOid(r),"1.2.840.113549")}),function(){var n=[{"in":"20110223123400",out:129846444e4},{"in":"20110223123400.1",out:1298464440100},{"in":"20110223123400.123",out:1298464440123}];for(var r=0;r<n.length;++r){var i=n[r];it('should convert local generalized time "'+i.in+'" to a Date',function(){var n=t.generalizedTimeToDate(i.in),r=n.getTimezoneOffset()*6e4;e.equal(n.getTime(),i.out+r)})}}(),function(){var n=[{"in":"20110223123400Z",out:129846444e4},{"in":"20110223123400.1Z",out:1298464440100},{"in":"20110223123400.123Z",out:1298464440123},{"in":"20110223123400+0200",out:129845724e4},{"in":"20110223123400.1+0200",out:1298457240100},{"in":"20110223123400.123+0200",out:1298457240123},{"in":"20110223123400-0200",out:129847164e4},{"in":"20110223123400.1-0200",out:1298471640100},{"in":"20110223123400.123-0200",out:1298471640123}];for(var r=0;r<n.length;++r){var i=n[r];it('should convert utc generalized time "'+i.in+'" to a Date',function(){var n=t.generalizedTimeToDate(i.in);e.equal(n.getTime(),i.out)})}}(),function(){var n=[{"in":"1102231234Z",out:129846444e4},{"in":"1102231234+0200",out:129845724e4},{"in":"1102231234-0200",out:129847164e4},{"in":"110223123456Z",out:1298464496e3},{"in":"110223123456+0200",out:1298457296e3},{"in":"110223123456-0200",out:1298471696e3}];for(var r=0;r<n.length;++r){var i=n[r];it('should convert utc time "'+i.in+'" to a Date',function(){var n=t.utcTimeToDate(i.in);e.equal(n.getTime(),i.out)})}}()})}typeof define=="function"?define("test/asn1",["forge/asn1","forge/util"],function(t,n){e(ASSERT,t(),n())}):typeof module=="object"&&module.exports&&e(require("assert"),require("../../js/asn1")(),require("../../js/util")())}(),function(){function e(e){function n(e){var t=e.name+": ",n=[];for(var r=0;r<e.values.length;++r)n.push(e.values[r].replace(/^(\S+\r\n)/,function(e,t){return" "+t}));t+=n.join(",")+"\r\n";var i=0,s=-1;for(var r=0;r<t.length;++r,++i)if(i>65&&s!==-1){var o=t[s];o===","?(++s,t=t.substr(0,s)+"\r\n "+t.substr(s)):t=t.substr(0,s)+"\r\n"+o+t.substr(s+1),i=r-s-1,s=-1,++r}else if(t[r]===" "||t[r]===" "||t[r]===",")s=r;return t}function r(e){return e.replace(/^\s+/,"")}var t=e.pem=e.pem||{};t.encode=function(t,r){r=r||{};var i="-----BEGIN "+t.type+"-----\r\n",s;t.procType&&(s={name:"Proc-Type",values:[String(t.procType.version),t.procType.type]},i+=n(s)),t.contentDomain&&(s={name:"Content-Domain",values:[t.contentDomain]},i+=n(s)),t.dekInfo&&(s={name:"DEK-Info",values:[t.dekInfo.algorithm]},t.dekInfo.parameters&&s.values.push(t.dekInfo.parameters),i+=n(s));if(t.headers)for(var o=0;o<t.headers.length;++o)i+=n(t.headers[o]);return t.procType&&(i+="\r\n"),i+=e.util.encode64(t.body,r.maxline||64)+"\r\n",i+="-----END "+t.type+"-----\r\n",i},t.decode=function(t){var n=[],i=/\s*-----BEGIN ([A-Z0-9- ]+)-----\r?\n([\x21-\x7e\s]+?(?:\r?\n\r?\n))?([:A-Za-z0-9+\/=\s]+?)-----END \1-----/g,s=/([\x21-\x7e]+):\s*([\x21-\x7e\s^:]+)/,o=/\r?\n/,u;for(;;){u=i.exec(t);if(!u)break;var a={type:u[1],procType:null,contentDomain:null,dekInfo:null,headers:[],body:e.util.decode64(u[3])};n.push(a);if(!u[2])continue;var f=u[2].split(o),l=0;while(u&&l<f.length){var c=f[l].replace(/\s+$/,"");for(var h=l+1;h<f.length;++h){var p=f[h];if(!/\s/.test(p[0]))break;c+=p,l=h}u=c.match(s);if(u){var d={name:u[1],values:[]},v=u[2].split(",");for(var m=0;m<v.length;++m)d.values.push(r(v[m]));if(!a.procType){if(d.name!=="Proc-Type")throw{message:'Invalid PEM formatted message. The first encapsulated header must be "Proc-Type".'};if(d.values.length!==2)throw{message:'Invalid PEM formatted message. The "Proc-Type" header must have two subfields.'};a.procType={version:v[0],type:v[1]}}else if(!a.contentDomain&&d.name==="Content-Domain")a.contentDomain=v[0]||"";else if(!a.dekInfo&&d.name==="DEK-Info"){if(d.values.length===0)throw{message:'Invalid PEM formatted message. The "DEK-Info" header must have at least one subfield.'};a.dekInfo={algorithm:v[0],parameters:v[1]||null}}else a.headers.push(d)}++l}if(a.procType==="ENCRYPTED"&&!a.dekInfo)throw{message:'Invalid PEM formatted message. The "DEK-Info" header must be present if "Proc-Type" is "ENCRYPTED".'}}if(n.length===0)throw{message:"Invalid PEM formatted message."};return n}}var t="pem";if(typeof define!="function"){if(typeof module!="object"||!module.exports)return typeof forge=="undefined"&&(forge={}),e(forge);var n=!0;define=function(e,t){t(require,module)}}var r,i=function(n,i){i.exports=function(i){var s=r.map(function(e){return n(e)}).concat(e);i=i||{},i.defined=i.defined||{};if(i.defined[t])return i[t];i.defined[t]=!0;for(var o=0;o<s.length;++o)s[o](i);return i[t]}},s=define;define=function(e,t){return r=typeof e=="string"?t.slice(2):e.slice(2),n?(delete define,s.apply(null,Array.prototype.slice.call(arguments,0))):(define=s,define.apply(null,Array.prototype.slice.call(arguments,0)))},define("forge/pem",["require","module","./util"],function(){i.apply(null,Array.prototype.slice.call(arguments,0))})}(),function(){function e(e,t){var n="-----BEGIN PRIVACY-ENHANCED MESSAGE-----\r\nProc-Type: 4,ENCRYPTED\r\nContent-Domain: RFC822\r\nDEK-Info: DES-CBC,F8143EDE5960C597\r\nOriginator-ID-Symmetric: linn@zendia.enet.dec.com,,\r\nRecipient-ID-Symmetric: linn@zendia.enet.dec.com,ptf-kmc,3\r\nKey-Info: DES-ECB,RSA-MD2,9FD3AAD2F2691B9A,\r\n B70665BB9BF7CBCDA60195DB94F727D3\r\nRecipient-ID-Symmetric: pem-dev@tis.com,ptf-kmc,4\r\nKey-Info: DES-ECB,RSA-MD2,161A3F75DC82EF26,\r\n E2EF532C65CBCFF79F83A2658132DB47\r\n\r\nLLrHB0eJzyhP+/fSStdW8okeEnv47jxe7SJ/iN72ohNcUk2jHEUSoH1nvNSIWL9M\r\n8tEjmF/zxB+bATMtPjCUWbz8Lr9wloXIkjHUlBLpvXR0UrUzYbkNpk0agV2IzUpk\r\nJ6UiRRGcDSvzrsoK+oNvqu6z7Xs5Xfz5rDqUcMlK1Z6720dcBWGGsDLpTpSCnpot\r\ndXd/H5LMDWnonNvPCwQUHg==\r\n-----END PRIVACY-ENHANCED MESSAGE-----\r\n-----BEGIN PRIVACY-ENHANCED MESSAGE-----\r\nProc-Type: 4,ENCRYPTED\r\nContent-Domain: RFC822\r\nDEK-Info: DES-CBC,BFF968AA74691AC1\r\nOriginator-Certificate:\r\n MIIBlTCCAScCAWUwDQYJKoZIhvcNAQECBQAwUTELMAkGA1UEBhMCVVMxIDAeBgNV\r\n BAoTF1JTQSBEYXRhIFNlY3VyaXR5LCBJbmMuMQ8wDQYDVQQLEwZCZXRhIDExDzAN\r\n BgNVBAsTBk5PVEFSWTAeFw05MTA5MDQxODM4MTdaFw05MzA5MDMxODM4MTZaMEUx\r\n CzAJBgNVBAYTAlVTMSAwHgYDVQQKExdSU0EgRGF0YSBTZWN1cml0eSwgSW5jLjEU\r\n MBIGA1UEAxMLVGVzdCBVc2VyIDEwWTAKBgRVCAEBAgICAANLADBIAkEAwHZHl7i+\r\n yJcqDtjJCowzTdBJrdAiLAnSC+CnnjOJELyuQiBgkGrgIh3j8/x0fM+YrsyF1u3F\r\n LZPVtzlndhYFJQIDAQABMA0GCSqGSIb3DQEBAgUAA1kACKr0PqphJYw1j+YPtcIq\r\n iWlFPuN5jJ79Khfg7ASFxskYkEMjRNZV/HZDZQEhtVaU7Jxfzs2wfX5byMp2X3U/\r\n 5XUXGx7qusDgHQGs7Jk9W8CW1fuSWUgN4w==\r\nKey-Info: RSA,\r\n I3rRIGXUGWAF8js5wCzRTkdhO34PTHdRZY9Tuvm03M+NM7fx6qc5udixps2Lng0+\r\n wGrtiUm/ovtKdinz6ZQ/aQ==\r\nIssuer-Certificate:\r\n MIIB3DCCAUgCAQowDQYJKoZIhvcNAQECBQAwTzELMAkGA1UEBhMCVVMxIDAeBgNV\r\n BAoTF1JTQSBEYXRhIFNlY3VyaXR5LCBJbmMuMQ8wDQYDVQQLEwZCZXRhIDExDTAL\r\n BgNVBAsTBFRMQ0EwHhcNOTEwOTAxMDgwMDAwWhcNOTIwOTAxMDc1OTU5WjBRMQsw\r\n CQYDVQQGEwJVUzEgMB4GA1UEChMXUlNBIERhdGEgU2VjdXJpdHksIEluYy4xDzAN\r\n BgNVBAsTBkJldGEgMTEPMA0GA1UECxMGTk9UQVJZMHAwCgYEVQgBAQICArwDYgAw\r\n XwJYCsnp6lQCxYykNlODwutF/jMJ3kL+3PjYyHOwk+/9rLg6X65B/LD4bJHtO5XW\r\n cqAz/7R7XhjYCm0PcqbdzoACZtIlETrKrcJiDYoP+DkZ8k1gCk7hQHpbIwIDAQAB\r\n MA0GCSqGSIb3DQEBAgUAA38AAICPv4f9Gx/tY4+p+4DB7MV+tKZnvBoy8zgoMGOx\r\n dD2jMZ/3HsyWKWgSF0eH/AJB3qr9zosG47pyMnTf3aSy2nBO7CMxpUWRBcXUpE+x\r\n EREZd9++32ofGBIXaialnOgVUn0OzSYgugiQ077nJLDUj0hQehCizEs5wUJ35a5h\r\nMIC-Info: RSA-MD5,RSA,\r\n UdFJR8u/TIGhfH65ieewe2lOW4tooa3vZCvVNGBZirf/7nrgzWDABz8w9NsXSexv\r\n AjRFbHoNPzBuxwmOAFeA0HJszL4yBvhG\r\nRecipient-ID-Asymmetric:\r\n MFExCzAJBgNVBAYTAlVTMSAwHgYDVQQKExdSU0EgRGF0YSBTZWN1cml0eSwgSW5j\r\n LjEPMA0GA1UECxMGQmV0YSAxMQ8wDQYDVQQLEwZOT1RBUlk=,66\r\nKey-Info: RSA,\r\n O6BS1ww9CTyHPtS3bMLD+L0hejdvX6Qv1HK2ds2sQPEaXhX8EhvVphHYTjwekdWv\r\n 7x0Z3Jx2vTAhOYHMcqqCjA==\r\n\r\nqeWlj/YJ2Uf5ng9yznPbtD0mYloSwIuV9FRYx+gzY+8iXd/NQrXHfi6/MhPfPF3d\r\njIqCJAxvld2xgqQimUzoS1a4r7kQQ5c/Iua4LqKeq3ciFzEv/MbZhA==\r\n-----END PRIVACY-ENHANCED MESSAGE-----\r\n-----BEGIN RSA PRIVATE KEY-----\r\nMIIBPAIBAAJBALjXU+IdHkSkdBscgXf+EBoa55ruAIsU50uDFjFBkp+rWFt5AOGF\r\n9xL1/HNIby5M64BCw021nJTZKEOmXKdmzYsCAwEAAQJBAApyYRNOgf9vLAC8Q7T8\r\nbvyKuLxQ50b1D319EywFgLv1Yn0s/F9F+Rew6c04Q0pIqmuOGUM7z94ul/y5OlNJ\r\n2cECIQDveEW1ib2+787l7Y0tMeDzf/HQl4MAWdcxXWOeUFK+7QIhAMWZsukutEn9\r\n9/yqFMt8bL/dclfNn1IAgUL4+dMJ7zdXAiEAhaxGhVKxN28XuCOFhe/s2R/XdQ/O\r\nUZjU1bqCzDGcLvUCIGYmxu71Tg7SVFkyM/3eHPozKOFrU2m5CRnuTHhlMl2RAiEA\r\n0vhM5TEmmNWz0anPVabqDj9TA0z5MsDJQcn5NmO9xnw=\r\n-----END RSA PRIVATE KEY-----\r\n";describe("pem",function(){it("should decode and re-encode PEM messages",function(){var r=t.decode(n),i="";for(var s=0;s<r.length;++s)i+=t.encode(r[s]);e.equal(i,n)})})}typeof define=="function"?define("test/pem",["forge/pem"],function(t){e(ASSERT,t())}):typeof module=="object"&&module.exports&&e(require("assert"),require("../../js/pem")())}(),function(){function e(e){function f(e){var t=[0,4,536870912,536870916,65536,65540,536936448,536936452,512,516,536871424,536871428,66048,66052,536936960,536936964],n=[0,1,1048576,1048577,67108864,67108865,68157440,68157441,256,257,1048832,1048833,67109120,67109121,68157696,68157697],r=[0,8,2048,2056,16777216,16777224,16779264,16779272,0,8,2048,2056,16777216,16777224,16779264,16779272],i=[0,2097152,134217728,136314880,8192,2105344,134225920,136323072,131072,2228224,134348800,136445952,139264,2236416,134356992,136454144],s=[0,262144,16,262160,0,262144,16,262160,4096,266240,4112,266256,4096,266240,4112,266256],o=[0,1024,32,1056,0,1024,32,1056,33554432,33555456,33554464,33555488,33554432,33555456,33554464,33555488],u=[0,268435456,524288,268959744,2,268435458,524290,268959746,0,268435456,524288,268959744,2,268435458,524290,268959746],a=[0,65536,2048,67584,536870912,536936448,536872960,536938496,131072,196608,133120,198656,537001984,537067520,537004032,537069568],f=[0,262144,0,262144,2,262146,2,262146,33554432,33816576,33554432,33816576,33554434,33816578,33554434,33816578],l=[0,268435456,8,268435464,0,268435456,8,268435464,1024,268436480,1032,268436488,1024,268436480,1032,268436488],c=[0,32,0,32,1048576,1048608,1048576,1048608,8192,8224,8192,8224,1056768,1056800,1056768,1056800],h=[0,16777216,512,16777728,2097152,18874368,2097664,18874880,67108864,83886080,67109376,83886592,69206016,85983232,69206528,85983744],p=[0,4096,134217728,134221824,524288,528384,134742016,134746112,16,4112,134217744,134221840,524304,528400,134742032,134746128],d=[0,4,256,260,0,4,256,260,1,5,257,261,1,5,257,261],v=e.length()>8?3:1,m=[],g=[0,0,1,1,1,1,1,1,0,1,1,1,1,1,1,0],y=0,b;for(var w=0;w<v;w++){var E=e.getInt32(),S=e.getInt32();b=(E>>>4^S)&252645135,S^=b,E^=b<<4,b=(S>>>-16^E)&65535,E^=b,S^=b<<-16,b=(E>>>2^S)&858993459,S^=b,E^=b<<2,b=(S>>>-16^E)&65535,E^=b,S^=b<<-16,b=(E>>>1^S)&1431655765,S^=b,E^=b<<1,b=(S>>>8^E)&16711935,E^=b,S^=b<<8,b=(E>>>1^S)&1431655765,S^=b,E^=b<<1,b=E<<8|S>>>20&240,E=S<<24|S<<8&16711680|S>>>8&65280|S>>>24&240,S=b;for(var x=0;x<g.length;x++){g[x]?(E=E<<2|E>>>26,S=S<<2|S>>>26):(E=E<<1|E>>>27,S=S<<1|S>>>27),E&=-15,S&=-15;var T=t[E>>>28]|n[E>>>24&15]|r[E>>>20&15]|i[E>>>16&15]|s[E>>>12&15]|o[E>>>8&15]|u[E>>>4&15],N=a[S>>>28]|f[S>>>24&15]|l[S>>>20&15]|c[S>>>16&15]|h[S>>>12&15]|p[S>>>8&15]|d[S>>>4&15];b=(N>>>16^T)&65535,m[y++]=T^b,m[y++]=N^b<<16}}return m}var t=[16843776,0,65536,16843780,16842756,66564,4,65536,1024,16843776,16843780,1024,16778244,16842756,16777216,4,1028,16778240,16778240,66560,66560,16842752,16842752,16778244,65540,16777220,16777220,65540,0,1028,66564,16777216,65536,16843780,4,16842752,16843776,16777216,16777216,1024,16842756,65536,66560,16777220,1024,4,16778244,66564,16843780,65540,16842752,16778244,16777220,1028,66564,16843776,1028,16778240,16778240,0,65540,66560,0,16842756],n=[-2146402272,-2147450880,32768,1081376,1048576,32,-2146435040,-2147450848,-2147483616,-2146402272,-2146402304,-2147483648,-2147450880,1048576,32,-2146435040,1081344,1048608,-2147450848,0,-2147483648,32768,1081376,-2146435072,1048608,-2147483616,0,1081344,32800,-2146402304,-2146435072,32800,0,1081376,-2146435040,1048576,-2147450848,-2146435072,-2146402304,32768,-2146435072,-2147450880,32,-2146402272,1081376,32,32768,-2147483648,32800,-2146402304,1048576,-2147483616,1048608,-2147450848,-2147483616,1048608,1081344,0,-2147450880,32800,-2147483648,-2146435040,-2146402272,1081344],r=[520,134349312,0,134348808,134218240,0,131592,134218240,131080,134217736,134217736,131072,134349320,131080,134348800,520,134217728,8,134349312,512,131584,134348800,134348808,131592,134218248,131584,131072,134218248,8,134349320,512,134217728,134349312,134217728,131080,520,131072,134349312,134218240,0,512,131080,134349320,134218240,134217736,512,0,134348808,134218248,131072,134217728,134349320,8,131592,131584,134217736,134348800,134218248,520,134348800,131592,8,134348808,131584],i=[8396801,8321,8321,128,8396928,8388737,8388609,8193,0,8396800,8396800,8396929,129,0,8388736,8388609,1,8192,8388608,8396801,128,8388608,8193,8320,8388737,1,8320,8388736,8192,8396928,8396929,129,8388736,8388609,8396800,8396929,129,0,0,8396800,8320,8388736,8388737,1,8396801,8321,8321,128,8396929,129,1,8192,8388609,8193,8396928,8388737,8193,8320,8388608,8396801,128,8388608,8192,8396928],s=[256,34078976,34078720,1107296512,524288,256,1073741824,34078720,1074266368,524288,33554688,1074266368,1107296512,1107820544,524544,1073741824,33554432,1074266112,1074266112,0,1073742080,1107820800,1107820800,33554688,1107820544,1073742080,0,1107296256,34078976,33554432,1107296256,524544,524288,1107296512,256,33554432,1073741824,34078720,1107296512,1074266368,33554688,1073741824,1107820544,34078976,1074266368,256,33554432,1107820544,1107820800,524544,1107296256,1107820800,34078720,0,1074266112,1107296256,524544,33554688,1073742080,524288,0,1074266112,34078976,1073742080],o=[536870928,541065216,16384,541081616,541065216,16,541081616,4194304,536887296,4210704,4194304,536870928,4194320,536887296,536870912,16400,0,4194320,536887312,16384,4210688,536887312,16,541065232,541065232,0,4210704,541081600,16400,4210688,541081600,536870912,536887296,16,541065232,4210688,541081616,4194304,16400,536870928,4194304,536887296,536870912,16400,536870928,541081616,4210688,541065216,4210704,541081600,0,541065232,16,16384,541065216,4210704,16384,4194320,536887312,0,541081600,536870912,4194320,536887312],u=[2097152,69206018,67110914,0,2048,67110914,2099202,69208064,69208066,2097152,0,67108866,2,67108864,69206018,2050,67110912,2099202,2097154,67110912,67108866,69206016,69208064,2097154,69206016,2048,2050,69208066,2099200,2,67108864,2099200,67108864,2099200,2097152,67110914,67110914,69206018,69206018,2,2097154,67108864,67110912,2097152,69208064,2050,2099202,69208064,2050,67108866,69208066,69206016,2099200,0,2,69208066,0,2099202,69206016,2048,67108866,67110912,2048,2097154],a=[268439616,4096,262144,268701760,268435456,268439616,64,268435456,262208,268697600,268701760,266240,268701696,266304,4096,64,268697600,268435520,268439552,4160,266240,262208,268697664,268701696,4160,0,0,268697664,268435520,268439552,266304,262144,266304,262144,268701696,4096,64,268697664,4096,266304,268439552,64,268435520,268697600,268697664,268435456,262144,268439616,0,268701760,262208,268435520,268697600,268439552,268439616,0,268701760,266240,266240,4160,4160,262208,268435456,268701696],l=function(l,c){typeof l=="string"&&(l.length===8||l.length===24)&&(l=e.util.createBuffer(l));var h=f(l),p=1,d=0,v=0,m=0,g=0,y=!1,b=null,w=null,E=h.length===32?3:9,S;E===3?S=c?[0,32,2]:[30,-2,-2]:S=c?[0,32,2,62,30,-2,64,96,2]:[94,62,-2,32,64,2,30,-2,-2];var x=null;return x={start:function(t,n){t?(typeof t=="string"&&t.length===8&&(t=e.util.createBuffer(t)),p=1,d=t.getInt32(),m=t.getInt32()):p=0,y=!1,b=e.util.createBuffer(),w=n||e.util.createBuffer(),x.output=w},update:function(e){y||b.putBuffer(e);while(b.length()>=8){var f,l=b.getInt32(),x=b.getInt32();p===1&&(c?(l^=d,x^=m):(v=d,g=m,d=l,m=x)),f=(l>>>4^x)&252645135,x^=f,l^=f<<4,f=(l>>>16^x)&65535,x^=f,l^=f<<16,f=(x>>>2^l)&858993459,l^=f,x^=f<<2,f=(x>>>8^l)&16711935,l^=f,x^=f<<8,f=(l>>>1^x)&1431655765,x^=f,l^=f<<1,l=l<<1|l>>>31,x=x<<1|x>>>31;for(var T=0;T<E;T+=3){var N=S[T+1],C=S[T+2];for(var k=S[T];k!=N;k+=C){var L=x^h[k],A=(x>>>4|x<<28)^h[k+1];f=l,l=x,x=f^(n[L>>>24&63]|i[L>>>16&63]|o[L>>>8&63]|a[L&63]|t[A>>>24&63]|r[A>>>16&63]|s[A>>>8&63]|u[A&63])}f=l,l=x,x=f}l=l>>>1|l<<31,x=x>>>1|x<<31,f=(l>>>1^x)&1431655765,x^=f,l^=f<<1,f=(x>>>8^l)&16711935,l^=f,x^=f<<8,f=(x>>>2^l)&858993459,l^=f,x^=f<<2,f=(l>>>16^x)&65535,x^=f,l^=f<<16,f=(l>>>4^x)&252645135,x^=f,l^=f<<4,p===1&&(c?(d=l,m=x):(l^=v,x^=g)),w.putInt32(l),w.putInt32(x)}},finish:function(e){var t=!0;if(c)if(e)t=e(8,b,!c);else{var n=b.length()===8?8:8-b.length();b.fillWithByte(n,n)}t&&(y=!0,x.update());if(!c){t=b.length()===0;if(t)if(e)t=e(8,w,!c);else{var r=w.length(),i=w.at(r-1);i>r?t=!1:w.truncate(i)}}return t}},x};e.des=e.des||{},e.des.startEncrypting=function(e,t,n){var r=l(e,!0);return r.start(t,n),r},e.des.createEncryptionCipher=function(e){return l(e,!0)},e.des.startDecrypting=function(e,t,n){var r=l(e,!1);return r.start(t,n),r},e.des.createDecryptionCipher=function(e){return l(e,!1)}}var t="des";if(typeof define!="function"){if(typeof module!="object"||!module.exports)return typeof forge=="undefined"&&(forge={}),e(forge);var n=!0;define=function(e,t){t(require,module)}}var r,i=function(n,i){i.exports=function(i){var s=r.map(function(e){return n(e)}).concat(e);i=i||{},i.defined=i.defined||{};if(i.defined[t])return i[t];i.defined[t]=!0;for(var o=0;o<s.length;++o)s[o](i);return i[t]}},s=define;define=function(e,t){return r=typeof e=="string"?t.slice(2):e.slice(2),n?(delete define,s.apply(null,Array.prototype.slice.call(arguments,0))):(define=s,define.apply(null,Array.prototype.slice.call(arguments,0)))},define("forge/des",["require","module","./util"],function(){i.apply(null,Array.prototype.slice.call(arguments,0))})}(),function(){function e(e){function i(e,t,n){this.data=[],e!=null&&("number"==typeof e?this.fromNumber(e,t,n):t==null&&"string"!=typeof e?this.fromString(e,256):this.fromString(e,t))}function s(){return new i(null)}function o(e,t,n,r,i,s){while(--s>=0){var o=t*this.data[e++]+n.data[r]+i;i=Math.floor(o/67108864),n.data[r++]=o&67108863}return i}function u(e,t,n,r,i,s){var o=t&32767,u=t>>15;while(--s>=0){var a=this.data[e]&32767,f=this.data[e++]>>15,l=u*a+f*o;a=o*a+((l&32767)<<15)+n.data[r]+(i&1073741823),i=(a>>>30)+(l>>>15)+u*f+(i>>>30),n.data[r++]=a&1073741823}return i}function a(e,t,n,r,i,s){var o=t&16383,u=t>>14;while(--s>=0){var a=this.data[e]&16383,f=this.data[e++]>>14,l=u*a+f*o;a=o*a+((l&16383)<<14)+n.data[r]+i,i=(a>>28)+(l>>14)+u*f,n.data[r++]=a&268435455}return i}function d(e){return l.charAt(e)}function v(e,t){var n=c[e.charCodeAt(t)];return n==null?-1:n}function m(e){for(var t=this.t-1;t>=0;--t)e.data[t]=this.data[t];e.t=this.t,e.s=this.s}function g(e){this.t=1,this.s=e<0?-1:0,e>0?this.data[0]=e:e<-1?this.data[0]=e+DV:this.t=0}function y(e){var t=s();return t.fromInt(e),t}function b(e,t){var n;if(t==16)n=4;else if(t==8)n=3;else if(t==256)n=8;else if(t==2)n=1;else if(t==32)n=5;else{if(t!=4){this.fromRadix(e,t);return}n=2}this.t=0,this.s=0;var r=e.length,s=!1,o=0;while(--r>=0){var u=n==8?e[r]&255:v(e,r);if(u<0){e.charAt(r)=="-"&&(s=!0);continue}s=!1,o==0?this.data[this.t++]=u:o+n>this.DB?(this.data[this.t-1]|=(u&(1<<this.DB-o)-1)<<o,this.data[this.t++]=u>>this.DB-o):this.data[this.t-1]|=u<<o,o+=n,o>=this.DB&&(o-=this.DB)}n==8&&(e[0]&128)!=0&&(this.s=-1,o>0&&(this.data[this.t-1]|=(1<<this.DB-o)-1<<o)),this.clamp(),s&&i.ZERO.subTo(this,this)}function w(){var e=this.s&this.DM;while(this.t>0&&this.data[this.t-1]==e)--this.t}function E(e){if(this.s<0)return"-"+this.negate().toString(e);var t;if(e==16)t=4;else if(e==8)t=3;else if(e==2)t=1;else if(e==32)t=5;else{if(e!=4)return this.toRadix(e);t=2}var n=(1<<t)-1,r,i=!1,s="",o=this.t,u=this.DB-o*this.DB%t;if(o-->0){u<this.DB&&(r=this.data[o]>>u)>0&&(i=!0,s=d(r));while(o>=0)u<t?(r=(this.data[o]&(1<<u)-1)<<t-u,r|=this.data[--o]>>(u+=this.DB-t)):(r=this.data[o]>>(u-=t)&n,u<=0&&(u+=this.DB,--o)),r>0&&(i=!0),i&&(s+=d(r))}return i?s:"0"}function S(){var e=s();return i.ZERO.subTo(this,e),e}function x(){return this.s<0?this.negate():this}function T(e){var t=this.s-e.s;if(t!=0)return t;var n=this.t;t=n-e.t;if(t!=0)return this.s<0?-t:t;while(--n>=0)if((t=this.data[n]-e.data[n])!=0)return t;return 0}function N(e){var t=1,n;return(n=e>>>16)!=0&&(e=n,t+=16),(n=e>>8)!=0&&(e=n,t+=8),(n=e>>4)!=0&&(e=n,t+=4),(n=e>>2)!=0&&(e=n,t+=2),(n=e>>1)!=0&&(e=n,t+=1),t}function C(){return this.t<=0?0:this.DB*(this.t-1)+N(this.data[this.t-1]^this.s&this.DM)}function k(e,t){var n;for(n=this.t-1;n>=0;--n)t.data[n+e]=this.data[n];for(n=e-1;n>=0;--n)t.data[n]=0;t.t=this.t+e,t.s=this.s}function L(e,t){for(var n=e;n<this.t;++n)t.data[n-e]=this.data[n];t.t=Math.max(this.t-e,0),t.s=this.s}function A(e,t){var n=e%this.DB,r=this.DB-n,i=(1<<r)-1,s=Math.floor(e/this.DB),o=this.s<<n&this.DM,u;for(u=this.t-1;u>=0;--u)t.data[u+s+1]=this.data[u]>>r|o,o=(this.data[u]&i)<<n;for(u=s-1;u>=0;--u)t.data[u]=0;t.data[s]=o,t.t=this.t+s+1,t.s=this.s,t.clamp()}function O(e,t){t.s=this.s;var n=Math.floor(e/this.DB);if(n>=this.t){t.t=0;return}var r=e%this.DB,i=this.DB-r,s=(1<<r)-1;t.data[0]=this.data[n]>>r;for(var o=n+1;o<this.t;++o)t.data[o-n-1]|=(this.data[o]&s)<<i,t.data[o-n]=this.data[o]>>r;r>0&&(t.data[this.t-n-1]|=(this.s&s)<<i),t.t=this.t-n,t.clamp()}function M(e,t){var n=0,r=0,i=Math.min(e.t,this.t);while(n<i)r+=this.data[n]-e.data[n],t.data[n++]=r&this.DM,r>>=this.DB;if(e.t<this.t){r-=e.s;while(n<this.t)r+=this.data[n],t.data[n++]=r&this.DM,r>>=this.DB;r+=this.s}else{r+=this.s;while(n<e.t)r-=e.data[n],t.data[n++]=r&this.DM,r>>=this.DB;r-=e.s}t.s=r<0?-1:0,r<-1?t.data[n++]=this.DV+r:r>0&&(t.data[n++]=r),t.t=n,t.clamp()}function _(e,t){var n=this.abs(),r=e.abs(),s=n.t;t.t=s+r.t;while(--s>=0)t.data[s]=0;for(s=0;s<r.t;++s)t.data[s+n.t]=n.am(0,r.data[s],t,s,0,n.t);t.s=0,t.clamp(),this.s!=e.s&&i.ZERO.subTo(t,t)}function D(e){var t=this.abs(),n=e.t=2*t.t;while(--n>=0)e.data[n]=0;for(n=0;n<t.t-1;++n){var r=t.am(n,t.data[n],e,2*n,0,1);(e.data[n+t.t]+=t.am(n+1,2*t.data[n],e,2*n+1,r,t.t-n-1))>=t.DV&&(e.data[n+t.t]-=t.DV,e.data[n+t.t+1]=1)}e.t>0&&(e.data[e.t-1]+=t.am(n,t.data[n],e,2*n,0,1)),e.s=0,e.clamp()}function P(e,t,n){var r=e.abs();if(r.t<=0)return;var o=this.abs();if(o.t<r.t){t!=null&&t.fromInt(0),n!=null&&this.copyTo(n);return}n==null&&(n=s());var u=s(),a=this.s,f=e.s,l=this.DB-N(r.data[r.t-1]);l>0?(r.lShiftTo(l,u),o.lShiftTo(l,n)):(r.copyTo(u),o.copyTo(n));var c=u.t,h=u.data[c-1];if(h==0)return;var p=h*(1<<this.F1)+(c>1?u.data[c-2]>>this.F2:0),d=this.FV/p,v=(1<<this.F1)/p,m=1<<this.F2,g=n.t,y=g-c,b=t==null?s():t;u.dlShiftTo(y,b),n.compareTo(b)>=0&&(n.data[n.t++]=1,n.subTo(b,n)),i.ONE.dlShiftTo(c,b),b.subTo(u,u);while(u.t<c)u.data[u.t++]=0;while(--y>=0){var w=n.data[--g]==h?this.DM:Math.floor(n.data[g]*d+(n.data[g-1]+m)*v);if((n.data[g]+=u.am(0,w,n,y,0,c))<w){u.dlShiftTo(y,b),n.subTo(b,n);while(n.data[g]<--w)n.subTo(b,n)}}t!=null&&(n.drShiftTo(c,t),a!=f&&i.ZERO.subTo(t,t)),n.t=c,n.clamp(),l>0&&n.rShiftTo(l,n),a<0&&i.ZERO.subTo(n,n)}function H(e){var t=s();return this.abs().divRemTo(e,null,t),this.s<0&&t.compareTo(i.ZERO)>0&&e.subTo(t,t),t}function B(e){this.m=e}function j(e){return e.s<0||e.compareTo(this.m)>=0?e.mod(this.m):e}function F(e){return e}function I(e){e.divRemTo(this.m,null,e)}function q(e,t,n){e.multiplyTo(t,n),this.reduce(n)}function R(e,t){e.squareTo(t),this.reduce(t)}function U(){if(this.t<1)return 0;var e=this.data[0];if((e&1)==0)return 0;var t=e&3;return t=t*(2-(e&15)*t)&15,t=t*(2-(e&255)*t)&255,t=t*(2-((e&65535)*t&65535))&65535,t=t*(2-e*t%this.DV)%this.DV,t>0?this.DV-t:-t}function z(e){this.m=e,this.mp=e.invDigit(),this.mpl=this.mp&32767,this.mph=this.mp>>15,this.um=(1<<e.DB-15)-1,this.mt2=2*e.t}function W(e){var t=s();return e.abs().dlShiftTo(this.m.t,t),t.divRemTo(this.m,null,t),e.s<0&&t.compareTo(i.ZERO)>0&&this.m.subTo(t,t),t}function X(e){var t=s();return e.copyTo(t),this.reduce(t),t}function V(e){while(e.t<=this.mt2)e.data[e.t++]=0;for(var t=0;t<this.m.t;++t){var n=e.data[t]&32767,r=n*this.mpl+((n*this.mph+(e.data[t]>>15)*this.mpl&this.um)<<15)&e.DM;n=t+this.m.t,e.data[n]+=this.m.am(0,r,e,t,0,this.m.t);while(e.data[n]>=e.DV)e.data[n]-=e.DV,e.data[++n]++}e.clamp(),e.drShiftTo(this.m.t,e),e.compareTo(this.m)>=0&&e.subTo(this.m,e)}function $(e,t){e.squareTo(t),this.reduce(t)}function J(e,t,n){e.multiplyTo(t,n),this.reduce(n)}function K(){return(this.t>0?this.data[0]&1:this.s)==0}function Q(e,t){if(e>4294967295||e<1)return i.ONE;var n=s(),r=s(),o=t.convert(this),u=N(e)-1;o.copyTo(n);while(--u>=0){t.sqrTo(n,r);if((e&1<<u)>0)t.mulTo(r,o,n);else{var a=n;n=r,r=a}}return t.revert(n)}function G(e,t){var n;return e<256||t.isEven()?n=new B(t):n=new z(t),this.exp(e,n)}function Y(){var e=s();return this.copyTo(e),e}function Z(){if(this.s<0){if(this.t==1)return this.data[0]-this.DV;if(this.t==0)return-1}else{if(this.t==1)return this.data[0];if(this.t==0)return 0}return(this.data[1]&(1<<32-this.DB)-1)<<this.DB|this.data[0]}function et(){return this.t==0?this.s:this.data[0]<<24>>24}function tt(){return this.t==0?this.s:this.data[0]<<16>>16}function nt(e){return Math.floor(Math.LN2*this.DB/Math.log(e))}function rt(){return this.s<0?-1:this.t<=0||this.t==1&&this.data[0]<=0?0:1}function it(e){e==null&&(e=10);if(this.signum()==0||e<2||e>36)return"0";var t=this.chunkSize(e),n=Math.pow(e,t),r=y(n),i=s(),o=s(),u="";this.divRemTo(r,i,o);while(i.signum()>0)u=(n+o.intValue()).toString(e).substr(1)+u,i.divRemTo(r,i,o);return o.intValue().toString(e)+u}function st(e,t){this.fromInt(0),t==null&&(t=10);var n=this.chunkSize(t),r=Math.pow(t,n),s=!1,o=0,u=0;for(var a=0;a<e.length;++a){var f=v(e,a);if(f<0){e.charAt(a)=="-"&&this.signum()==0&&(s=!0);continue}u=t*u+f,++o>=n&&(this.dMultiply(r),this.dAddOffset(u,0),o=0,u=0)}o>0&&(this.dMultiply(Math.pow(t,o)),this.dAddOffset(u,0)),s&&i.ZERO.subTo(this,this)}function ot(e,t,n){if("number"==typeof t)if(e<2)this.fromInt(1);else{this.fromNumber(e,n),this.testBit(e-1)||this.bitwiseTo(i.ONE.shiftLeft(e-1),dt,this),this.isEven()&&this.dAddOffset(1,0);while(!this.isProbablePrime(t))this.dAddOffset(2,0),this.bitLength()>e&&this.subTo(i.ONE.shiftLeft(e-1),this)}else{var r=new Array,s=e&7;r.length=(e>>3)+1,t.nextBytes(r),s>0?r[0]&=(1<<s)-1:r[0]=0,this.fromString(r,256)}}function ut(){var e=this.t,t=new Array;t[0]=this.s;var n=this.DB-e*this.DB%8,r,i=0;if(e-->0){n<this.DB&&(r=this.data[e]>>n)!=(this.s&this.DM)>>n&&(t[i++]=r|this.s<<this.DB-n);while(e>=0){n<8?(r=(this.data[e]&(1<<n)-1)<<8-n,r|=this.data[--e]>>(n+=this.DB-8)):(r=this.data[e]>>(n-=8)&255,n<=0&&(n+=this.DB,--e)),(r&128)!=0&&(r|=-256),i==0&&(this.s&128)!=(r&128)&&++i;if(i>0||r!=this.s)t[i++]=r}}return t}function at(e){return this.compareTo(e)==0}function ft(e){return this.compareTo(e)<0?this:e}function lt(e){return this.compareTo(e)>0?this:e}function ct(e,t,n){var r,i,s=Math.min(e.t,this.t);for(r=0;r<s;++r)n.data[r]=t(this.data[r],e.data[r]);if(e.t<this.t){i=e.s&this.DM;for(r=s;r<this.t;++r)n.data[r]=t(this.data[r],i);n.t=this.t}else{i=this.s&this.DM;for(r=s;r<e.t;++r)n.data[r]=t(i,e.data[r]);n.t=e.t}n.s=t(this.s,e.s),n.clamp()}function ht(e,t){return e&t}function pt(e){var t=s();return this.bitwiseTo(e,ht,t),t}function dt(e,t){return e|t}function vt(e){var t=s();return this.bitwiseTo(e,dt,t),t}function mt(e,t){return e^t}function gt(e){var t=s();return this.bitwiseTo(e,mt,t),t}function yt(e,t){return e&~t}function bt(e){var t=s();return this.bitwiseTo(e,yt,t),t}function wt(){var e=s();for(var t=0;t<this.t;++t)e.data[t]=this.DM&~this.data[t];return e.t=this.t,e.s=~this.s,e}function Et(e){var t=s();return e<0?this.rShiftTo(-e,t):this.lShiftTo(e,t),t}function St(e){var t=s();return e<0?this.lShiftTo(-e,t):this.rShiftTo(e,t),t}function xt(e){if(e==0)return-1;var t=0;return(e&65535)==0&&(e>>=16,t+=16),(e&255)==0&&(e>>=8,t+=8),(e&15)==0&&(e>>=4,t+=4),(e&3)==0&&(e>>=2,t+=2),(e&1)==0&&++t,t}function Tt(){for(var e=0;e<this.t;++e)if(this.data[e]!=0)return e*this.DB+xt(this.data[e]);return this.s<0?this.t*this.DB:-1}function Nt(e){var t=0;while(e!=0)e&=e-1,++t;return t}function Ct(){var e=0,t=this.s&this.DM;for(var n=0;n<this.t;++n)e+=Nt(this.data[n]^t);return e}function kt(e){var t=Math.floor(e/this.DB);return t>=this.t?this.s!=0:(this.data[t]&1<<e%this.DB)!=0}function Lt(e,t){var n=i.ONE.shiftLeft(e);return this.bitwiseTo(n,t,n),n}function At(e){return this.changeBit(e,dt)}function Ot(e){return this.changeBit(e,yt)}function Mt(e){return this.changeBit(e,mt)}function _t(e,t){var n=0,r=0,i=Math.min(e.t,this.t);while(n<i)r+=this.data[n]+e.data[n],t.data[n++]=r&this.DM,r>>=this.DB;if(e.t<this.t){r+=e.s;while(n<this.t)r+=this.data[n],t.data[n++]=r&this.DM,r>>=this.DB;r+=this.s}else{r+=this.s;while(n<e.t)r+=e.data[n],t.data[n++]=r&this.DM,r>>=this.DB;r+=e.s}t.s=r<0?-1:0,r>0?t.data[n++]=r:r<-1&&(t.data[n++]=this.DV+r),t.t=n,t.clamp()}function Dt(e){var t=s();return this.addTo(e,t),t}function Pt(e){var t=s();return this.subTo(e,t),t}function Ht(e){var t=s();return this.multiplyTo(e,t),t}function Bt(e){var t=s();return this.divRemTo(e,t,null),t}function jt(e){var t=s();return this.divRemTo(e,null,t),t}function Ft(e){var t=s(),n=s();return this.divRemTo(e,t,n),new Array(t,n)}function It(e){this.data[this.t]=this.am(0,e-1,this,0,0,this.t),++this.t,this.clamp()}function qt(e,t){if(e==0)return;while(this.t<=t)this.data[this.t++]=0;this.data[t]+=e;while(this.data[t]>=this.DV)this.data[t]-=this.DV,++t>=this.t&&(this.data[this.t++]=0),++this.data[t]}function Rt(){}function Ut(e){return e}function zt(e,t,n){e.multiplyTo(t,n)}function Wt(e,t){e.squareTo(t)}function Xt(e){return this.exp(e,new Rt)}function Vt(e,t,n){var r=Math.min(this.t+e.t,t);n.s=0,n.t=r;while(r>0)n.data[--r]=0;var i;for(i=n.t-this.t;r<i;++r)n.data[r+this.t]=this.am(0,e.data[r],n,r,0,this.t);for(i=Math.min(e.t,t);r<i;++r)this.am(0,e.data[r],n,r,0,t-r);n.clamp()}function $t(e,t,n){--t;var r=n.t=this.t+e.t-t;n.s=0;while(--r>=0)n.data[r]=0;for(r=Math.max(t-this.t,0);r<e.t;++r)n.data[this.t+r-t]=this.am(t-r,e.data[r],n,0,0,this.t+r-t);n.clamp(),n.drShiftTo(1,n)}function Jt(e){this.r2=s(),this.q3=s(),i.ONE.dlShiftTo(2*e.t,this.r2),this.mu=this.r2.divide(e),this.m=e}function Kt(e){if(e.s<0||e.t>2*this.m.t)return e.mod(this.m);if(e.compareTo(this.m)<0)return e;var t=s();return e.copyTo(t),this.reduce(t),t}function Qt(e){return e}function Gt(e){e.drShiftTo(this.m.t-1,this.r2),e.t>this.m.t+1&&(e.t=this.m.t+1,e.clamp()),this.mu.multiplyUpperTo(this.r2,this.m.t+1,this.q3),this.m.multiplyLowerTo(this.q3,this.m.t+1,this.r2);while(e.compareTo(this.r2)<0)e.dAddOffset(1,this.m.t+1);e.subTo(this.r2,e);while(e.compareTo(this.m)>=0)e.subTo(this.m,e)}function Yt(e,t){e.squareTo(t),this.reduce(t)}function Zt(e,t,n){e.multiplyTo(t,n),this.reduce(n)}function en(e,t){var n=e.bitLength(),r,i=y(1),o;if(n<=0)return i;n<18?r=1:n<48?r=3:n<144?r=4:n<768?r=5:r=6,n<8?o=new B(t):t.isEven()?o=new Jt(t):o=new z(t);var u=new Array,a=3,f=r-1,l=(1<<r)-1;u[1]=o.convert(this);if(r>1){var c=s();o.sqrTo(u[1],c);while(a<=l)u[a]=s(),o.mulTo(c,u[a-2],u[a]),a+=2}var h=e.t-1,p,d=!0,v=s(),m;n=N(e.data[h])-1;while(h>=0){n>=f?p=e.data[h]>>n-f&l:(p=(e.data[h]&(1<<n+1)-1)<<f-n,h>0&&(p|=e.data[h-1]>>this.DB+n-f)),a=r;while((p&1)==0)p>>=1,--a;(n-=a)<0&&(n+=this.DB,--h);if(d)u[p].copyTo(i),d=!1;else{while(a>1)o.sqrTo(i,v),o.sqrTo(v,i),a-=2;a>0?o.sqrTo(i,v):(m=i,i=v,v=m),o.mulTo(v,u[p],i)}while(h>=0&&(e.data[h]&1<<n)==0)o.sqrTo(i,v),m=i,i=v,v=m,--n<0&&(n=this.DB-1,--h)}return o.revert(i)}function tn(e){var t=this.s<0?this.negate():this.clone(),n=e.s<0?e.negate():e.clone();if(t.compareTo(n)<0){var r=t;t=n,n=r}var i=t.getLowestSetBit(),s=n.getLowestSetBit();if(s<0)return t;i<s&&(s=i),s>0&&(t.rShiftTo(s,t),n.rShiftTo(s,n));while(t.signum()>0)(i=t.getLowestSetBit())>0&&t.rShiftTo(i,t),(i=n.getLowestSetBit())>0&&n.rShiftTo(i,n),t.compareTo(n)>=0?(t.subTo(n,t),t.rShiftTo(1,t)):(n.subTo(t,n),n.rShiftTo(1,n));return s>0&&n.lShiftTo(s,n),n}function nn(e){if(e<=0)return 0;var t=this.DV%e,n=this.s<0?e-1:0;if(this.t>0)if(t==0)n=this.data[0]%e;else for(var r=this.t-1;r>=0;--r)n=(t*n+this.data[r])%e;return n}function rn(e){var t=e.isEven();if(this.isEven()&&t||e.signum()==0)return i.ZERO;var n=e.clone(),r=this.clone(),s=y(1),o=y(0),u=y(0),a=y(1);while(n.signum()!=0){while(n.isEven()){n.rShiftTo(1,n);if(t){if(!s.isEven()||!o.isEven())s.addTo(this,s),o.subTo(e,o);s.rShiftTo(1,s)}else o.isEven()||o.subTo(e,o);o.rShiftTo(1,o)}while(r.isEven()){r.rShiftTo(1,r);if(t){if(!u.isEven()||!a.isEven())u.addTo(this,u),a.subTo(e,a);u.rShiftTo(1,u)}else a.isEven()||a.subTo(e,a);a.rShiftTo(1,a)}n.compareTo(r)>=0?(n.subTo(r,n),t&&s.subTo(u,s),o.subTo(a,o)):(r.subTo(n,r),t&&u.subTo(s,u),a.subTo(o,a))}return r.compareTo(i.ONE)!=0?i.ZERO:a.compareTo(e)>=0?a.subtract(e):a.signum()<0?(a.addTo(e,a),a.signum()<0?a.add(e):a):a}function un(e){var t,n=this.abs();if(n.t==1&&n.data[0]<=sn[sn.length-1]){for(t=0;t<sn.length;++t)if(n.data[0]==sn[t])return!0;return!1}if(n.isEven())return!1;t=1;while(t<sn.length){var r=sn[t],i=t+1;while(i<sn.length&&r<on)r*=sn[i++];r=n.modInt(r);while(t<i)if(r%sn[t++]==0)return!1}return n.millerRabin(e)}function an(e){var t=this.subtract(i.ONE),n=t.getLowestSetBit();if(n<=0)return!1;var r=t.shiftRight(n);e=e+1>>1,e>sn.length&&(e=sn.length);var o=s();for(var u=0;u<e;++u){o.fromInt(sn[u]);var a=o.modPow(r,this);if(a.compareTo(i.ONE)!=0&&a.compareTo(t)!=0){var f=1;while(f++<n&&a.compareTo(t)!=0){a=a.modPowInt(2,this);if(a.compareTo(i.ONE)==0)return!1}if(a.compareTo(t)!=0)return!1}}return!0}var t,n=0xdeadbeefcafe,r=(n&16777215)==15715070;typeof navigator=="undefined"?(i.prototype.am=a,t=28):r&&navigator.appName=="Microsoft Internet Explorer"?(i.prototype.am=u,t=30):r&&navigator.appName!="Netscape"?(i.prototype.am=o,t=26):(i.prototype.am=a,t=28),i.prototype.DB=t,i.prototype.DM=(1<<t)-1,i.prototype.DV=1<<t;var f=52;i.prototype.FV=Math.pow(2,f),i.prototype.F1=f-t,i.prototype.F2=2*t-f;var l="0123456789abcdefghijklmnopqrstuvwxyz",c=new Array,h,p;h="0".charCodeAt(0);for(p=0;p<=9;++p)c[h++]=p;h="a".charCodeAt(0);for(p=10;p<36;++p)c[h++]=p;h="A".charCodeAt(0);for(p=10;p<36;++p)c[h++]=p;B.prototype.convert=j,B.prototype.revert=F,B.prototype.reduce=I,B.prototype.mulTo=q,B.prototype.sqrTo=R,z.prototype.convert=W,z.prototype.revert=X,z.prototype.reduce=V,z.prototype.mulTo=J,z.prototype.sqrTo=$,i.prototype.copyTo=m,i.prototype.fromInt=g,i.prototype.fromString=b,i.prototype.clamp=w,i.prototype.dlShiftTo=k,i.prototype.drShiftTo=L,i.prototype.lShiftTo=A,i.prototype.rShiftTo=O,i.prototype.subTo=M,i.prototype.multiplyTo=_,i.prototype.squareTo=D,i.prototype.divRemTo=P,i.prototype.invDigit=U,i.prototype.isEven=K,i.prototype.exp=Q,i.prototype.toString=E,i.prototype.negate=S,i.prototype.abs=x,i.prototype.compareTo=T,i.prototype.bitLength=C,i.prototype.mod=H,i.prototype.modPowInt=G,i.ZERO=y(0),i.ONE=y(1),Rt.prototype.convert=Ut,Rt.prototype.revert=Ut,Rt.prototype.mulTo=zt,Rt.prototype.sqrTo=Wt,Jt.prototype.convert=Kt,Jt.prototype.revert=Qt,Jt.prototype.reduce=Gt,Jt.prototype.mulTo=Zt,Jt.prototype.sqrTo=Yt;var sn=[2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293,307,311,313,317,331,337,347,349,353,359,367,373,379,383,389,397,401,409,419,421,431,433,439,443,449,457,461,463,467,479,487,491,499,503,509],on=(1<<26)/sn[sn.length-1];i.prototype.chunkSize=nt,i.prototype.toRadix=it,i.prototype.fromRadix=st,i.prototype.fromNumber=ot,i.prototype.bitwiseTo=ct,i.prototype.changeBit=Lt,i.prototype.addTo=_t,i.prototype.dMultiply=It,i.prototype.dAddOffset=qt,i.prototype.multiplyLowerTo=Vt,i.prototype.multiplyUpperTo=$t,i.prototype.modInt=nn,i.prototype.millerRabin=an,i.prototype.clone=Y,i.prototype.intValue=Z,i.prototype.byteValue=et,i.prototype.shortValue=tt,i.prototype.signum=rt,i.prototype.toByteArray=ut,i.prototype.equals=at,i.prototype.min=ft,i.prototype.max=lt,i.prototype.and=pt,i.prototype.or=vt,i.prototype.xor=gt,i.prototype.andNot=bt,i.prototype.not=wt,i.prototype.shiftLeft=Et,i.prototype.shiftRight=St,i.prototype.getLowestSetBit=Tt,i.prototype.bitCount=Ct,i.prototype.testBit=kt,i.prototype.setBit=At,i.prototype.clearBit=Ot,i.prototype.flipBit=Mt,i.prototype.add=Dt,i.prototype.subtract=Pt,i.prototype.multiply=Ht,i.prototype.divide=Bt,i.prototype.remainder=jt,i.prototype.divideAndRemainder=Ft,i.prototype.modPow=en,i.prototype.modInverse=rn,i.prototype.pow=Xt,i.prototype.gcd=tn,i.prototype.isProbablePrime=un,e.jsbn=e.jsbn||{},e.jsbn.BigInteger=i}var t="jsbn";if(typeof define!="function"){if(typeof module!="object"||!module.exports)return typeof forge=="undefined"&&(forge={}),e(forge);var n=!0;define=function(e,t){t(require,module)}}var r,i=function(n,i){i.exports=function(i){var s=r.map(function(e){return n(e)}).concat(e);i=i||{},i.defined=i.defined||{};if(i.defined[t])return i[t];i.defined[t]=!0;for(var o=0;o<s.length;++o)s[o](i);return i[t]}},s=define;define=function(e,t){return r=typeof e=="string"?t.slice(2):e.slice(2),n?(delete define,s.apply(null,Array.prototype.slice.call(arguments,0))):(define=s,define.apply(null,Array.prototype.slice.call(arguments,0)))},define("forge/jsbn",["require","module"],function(){i.apply(null,Array.prototype.slice.call(arguments,0))})}(),function(){function e(e){var t=e.asn1,n=e.pkcs7asn1=e.pkcs7asn1||{};e.pkcs7=e.pkcs7||{},e.pkcs7.asn1=n;var r={name:"ContentInfo",tagClass:t.Class.UNIVERSAL,type:t.Type.SEQUENCE,constructed:!0,value:[{name:"ContentInfo.ContentType",tagClass:t.Class.UNIVERSAL,type:t.Type.OID,constructed:!1,capture:"contentType"},{name:"ContentInfo.content",tagClass:t.Class.CONTEXT_SPECIFIC,type:0,constructed:!0,optional:!0,captureAsn1:"content"}]};n.contentInfoValidator=r;var i={name:"EncryptedContentInfo",tagClass:t.Class.UNIVERSAL,type:t.Type.SEQUENCE,constructed:!0,value:[{name:"EncryptedContentInfo.contentType",tagClass:t.Class.UNIVERSAL,type:t.Type.OID,constructed:!1,capture:"contentType"},{name:"EncryptedContentInfo.contentEncryptionAlgorithm",tagClass:t.Class.UNIVERSAL,type:t.Type.SEQUENCE,constructed:!0,value:[{name:"EncryptedContentInfo.contentEncryptionAlgorithm.algorithm",tagClass:t.Class.UNIVERSAL,type:t.Type.OID,constructed:!1,capture:"encAlgorithm"},{name:"EncryptedContentInfo.contentEncryptionAlgorithm.parameter",tagClass:t.Class.UNIVERSAL,captureAsn1:"encParameter"}]},{name:"EncryptedContentInfo.encryptedContent",tagClass:t.Class.CONTEXT_SPECIFIC,type:0,capture:"encContent"}]};n.envelopedDataValidator={name:"EnvelopedData",tagClass:t.Class.UNIVERSAL,type:t.Type.SEQUENCE,constructed:!0,value:[{name:"EnvelopedData.Version",tagClass:t.Class.UNIVERSAL,type:t.Type.INTEGER,constructed:!1,capture:"version"},{name:"EnvelopedData.RecipientInfos",tagClass:t.Class.UNIVERSAL,type:t.Type.SET,constructed:!0,captureAsn1:"recipientInfos"}].concat(i)},n.encryptedDataValidator={name:"EncryptedData",tagClass:t.Class.UNIVERSAL,type:t.Type.SEQUENCE,constructed:!0,value:[{name:"EncryptedData.Version",tagClass:t.Class.UNIVERSAL,type:t.Type.INTEGER,constructed:!1,capture:"version"}].concat(i)};var s={name:"SignerInfo",tagClass:t.Class.UNIVERSAL,type:t.Type.SEQUENCE,constructed:!0,value:[{name:"SignerInfo.Version",tagClass:t.Class.UNIVERSAL,type:t.Type.INTEGER,constructed:!1},{name:"SignerInfo.IssuerAndSerialNumber",tagClass:t.Class.UNIVERSAL,type:t.Type.SEQUENCE,constructed:!0},{name:"SignerInfo.DigestAlgorithm",tagClass:t.Class.UNIVERSAL,type:t.Type.SEQUENCE,constructed:!0},{name:"SignerInfo.AuthenticatedAttributes",tagClass:t.Class.CONTEXT_SPECIFIC,type:0,constructed:!0,optional:!0,capture:"authenticatedAttributes"},{name:"SignerInfo.DigestEncryptionAlgorithm",tagClass:t.Class.UNIVERSAL,type:t.Type.SEQUENCE,constructed:!0},{name:"SignerInfo.EncryptedDigest",tagClass:t.Class.UNIVERSAL,type:t.Type.OCTETSTRING,constructed:!1,capture:"signature"},{name:"SignerInfo.UnauthenticatedAttributes",tagClass:t.Class.CONTEXT_SPECIFIC,type:1,constructed:!0,optional:!0}]};n.signedDataValidator={name:"SignedData",tagClass:t.Class.UNIVERSAL,type:t.Type.SEQUENCE,constructed:!0,value:[{name:"SignedData.Version",tagClass:t.Class.UNIVERSAL,type:t.Type.INTEGER,constructed:!1,capture:"version"},{name:"SignedData.DigestAlgorithms",tagClass:t.Class.UNIVERSAL,type:t.Type.SET,constructed:!0,captureAsn1:"digestAlgorithms"},r,{name:"SignedData.Certificates",tagClass:t.Class.CONTEXT_SPECIFIC,type:0,optional:!0,captureAsn1:"certificates"},{name:"SignedData.CertificateRevocationLists",tagClass:t.Class.CONTEXT_SPECIFIC,type:1,optional:!0,captureAsn1:"crls"},{name:"SignedData.SignerInfos",tagClass:t.Class.UNIVERSAL,type:t.Type.SET,capture:"signerInfos",value:[s]}]},n.recipientInfoValidator={name:"RecipientInfo",tagClass:t.Class.UNIVERSAL,type:t.Type.SEQUENCE,constructed:!0,value:[{name:"RecipientInfo.version",tagClass:t.Class.UNIVERSAL,type:t.Type.INTEGER,constructed:!1,capture:"version"},{name:"RecipientInfo.issuerAndSerial",tagClass:t.Class.UNIVERSAL,type:t.Type.SEQUENCE,constructed:!0,value:[{name:"RecipientInfo.issuerAndSerial.issuer",tagClass:t.Class.UNIVERSAL,type:t.Type.SEQUENCE,constructed:!0,captureAsn1:"issuer"},{name:"RecipientInfo.issuerAndSerial.serialNumber",tagClass:t.Class.UNIVERSAL,type:t.Type.INTEGER,constructed:!1,capture:"serial"}]},{name:"RecipientInfo.keyEncryptionAlgorithm",tagClass:t.Class.UNIVERSAL,type:t.Type.SEQUENCE,constructed:!0,value:[{name:"RecipientInfo.keyEncryptionAlgorithm.algorithm",tagClass:t.Class.UNIVERSAL,type:t.Type.OID,constructed:!1,capture:"encAlgorithm"},{name:"RecipientInfo.keyEncryptionAlgorithm.parameter",tagClass:t.Class.UNIVERSAL,constructed:!1,captureAsn1:"encParameter"}]},{name:"RecipientInfo.encryptedKey",tagClass:t.Class.UNIVERSAL,type:t.Type.OCTETSTRING,constructed:!1,capture:"encKey"}]}}var t="pkcs7asn1";if(typeof define!="function"){if(typeof module!="object"||!module.exports)return typeof forge=="undefined"&&(forge={}),e(forge);var n=!0;define=function(e,t){t(require,module)}}var r,i=function(n,i){i.exports=function(i){var s=r.map(function(e){return n(e)}).concat(e);i=i||{},i.defined=i.defined||{};if(i.defined[t])return i[t];i.defined[t]=!0;for(var o=0;o<s.length;++o)s[o](i);return i[t]}},s=define;define=function(e,t){return r=typeof e=="string"?t.slice(2):e.slice(2),n?(delete define,s.apply(null,Array.prototype.slice.call(arguments,0))):(define=s,define.apply(null,Array.prototype.slice.call(arguments,0)))},define("forge/pkcs7asn1",["require","module","./asn1","./util"],function(){i.apply(null,Array.prototype.slice.call(arguments,0))})}(),function(){function e(e){function f(e,t,n,r){var i=[];for(var s=0;s<e.length;s++)for(var o=0;o<e[s].safeBags.length;o++){var u=e[s].safeBags[o];if(r!==undefined&&u.type!==r)continue;u.attributes[t]!==undefined&&u.attributes[t].indexOf(n)>=0&&i.push(u)}return i}function l(e,r,s,o){r=t.fromDer(r,s);if(r.tagClass!==t.Class.UNIVERSAL||r.type!==t.Type.SEQUENCE||r.constructed!==!0)throw{message:"PKCS#12 AuthenticatedSafe expected to be a SEQUENCE OF ContentInfo"};for(var u=0;u<r.value.length;u++){var a=r.value[u],f={},l=[];if(!t.validate(a,i,f,l))throw{message:"Cannot read ContentInfo.",errors:l};var p={encrypted:!1},d=null,v=f.content.value[0];switch(t.derToOid(f.contentType)){case n.oids.data:if(v.tagClass!==t.Class.UNIVERSAL||v.type!==t.Type.OCTETSTRING)throw{message:"PKCS#12 SafeContents Data is not an OCTET STRING."};d=v.value;break;case n.oids.encryptedData:if(o===undefined)throw{message:"Found PKCS#12 Encrypted SafeContents Data but no password available."};d=c(v,o),p.encrypted=!0;break;default:throw{message:"Unsupported PKCS#12 contentType.",contentType:t.derToOid(f.contentType)}}p.safeBags=h(d,s,o),e.safeContents.push(p)}}function c(r,i){var s={},o=[];if(!t.validate(r,e.pkcs7.asn1.encryptedDataValidator,s,o))throw{message:"Cannot read EncryptedContentInfo. ",errors:o};var u=t.derToOid(s.contentType);if(u!==n.oids.data)throw{message:"PKCS#12 EncryptedContentInfo ContentType is not Data.",oid:u};u=t.derToOid(s.encAlgorithm);var a=n.pbe.getCipher(u,s.encParameter,i),f=e.util.createBuffer(s.encContent);a.update(f);if(!a.finish())throw{message:"Failed to decrypt PKCS#12 SafeContents."};return a.output.getBytes()}function h(e,r,i){e=t.fromDer(e,r);if(e.tagClass!==t.Class.UNIVERSAL||e.type!==t.Type.SEQUENCE||e.constructed!==!0)throw{message:"PKCS#12 SafeContents expected to be a SEQUENCE OF SafeBag"};var s=[];for(var u=0;u<e.value.length;u++){var f=e.value[u],l={},c=[];if(!t.validate(f,o,l,c))throw{message:"Cannot read SafeBag.",errors:c};var h={type:t.derToOid(l.bagId),attributes:p(l.bagAttributes)};s.push(h);var d,v,m=l.bagValue.value[0];switch(h.type){case n.oids.pkcs8ShroudedKeyBag:if(i===undefined)throw{message:"Found PKCS#8 ShroudedKeyBag but no password available."};m=n.decryptPrivateKeyInfo(m,i);if(m===null)throw{message:"Unable to decrypt PKCS#8 ShroudedKeyBag, wrong password?"};case n.oids.keyBag:h.key=n.privateKeyFromAsn1(m);continue;case n.oids.certBag:d=a,v=function(){if(t.derToOid(l.certId)!==n.oids.x509Certificate)throw{message:"Unsupported certificate type, only X.509 supported.",oid:t.derToOid(l.certId)};h.cert=n.certificateFromAsn1(t.fromDer(l.cert,r),!0)};break;default:throw{message:"Unsupported PKCS#12 SafeBag type.",oid:h.type}}if(d!==undefined&&!t.validate(m,d,l,c))throw{message:"Cannot read PKCS#12 "+d.name,errors:c};v()}return s}function p(e){var r={};if(e!==undefined)for(var i=0;i<e.length;++i){var s={},o=[];if(!t.validate(e[i],u,s,o))throw{message:"Cannot read PKCS#12 BagAttribute.",errors:o};var a=t.derToOid(s.oid);if(n.oids[a]===undefined)continue;r[n.oids[a]]=[];for(var f=0;f<s.values.length;++f)r[n.oids[a]].push(s.values[f].value)}return r}var t=e.asn1,n=e.pki,r=e.pkcs12=e.pkcs12||{},i={name:"ContentInfo",tagClass:t.Class.UNIVERSAL,type:t.Type.SEQUENCE,constructed:!0,value:[{name:"ContentInfo.contentType",tagClass:t.Class.UNIVERSAL,type:t.Type.OID,constructed:!1,capture:"contentType"},{name:"ContentInfo.content",tagClass:t.Class.CONTEXT_SPECIFIC,constructed:!0,captureAsn1:"content"}]},s={name:"PFX",tagClass:t.Class.UNIVERSAL,type:t.Type.SEQUENCE,constructed:!0,value:[{name:"PFX.version",tagClass:t.Class.UNIVERSAL,type:t.Type.INTEGER,constructed:!1,capture:"version"},i,{name:"PFX.macData",tagClass:t.Class.UNIVERSAL,type:t.Type.SEQUENCE,constructed:!0,optional:!0,captureAsn1:"mac",value:[{name:"PFX.macData.mac",tagClass:t.Class.UNIVERSAL,type:t.Type.SEQUENCE,constructed:!0,value:[{name:"PFX.macData.mac.digestAlgorithm",tagClass:t.Class.UNIVERSAL,type:t.Type.SEQUENCE,constructed:!0,value:[{name:"PFX.macData.mac.digestAlgorithm.algorithm",tagClass:t.Class.UNIVERSAL,type:t.Type.OID,constructed:!1,capture:"macAlgorithm"},{name:"PFX.macData.mac.digestAlgorithm.parameters",tagClass:t.Class.UNIVERSAL,captureAsn1:"macAlgorithmParameters"}]},{name:"PFX.macData.mac.digest",tagClass:t.Class.UNIVERSAL,type:t.Type.OCTETSTRING,constructed:!1,capture:"macDigest"}]},{name:"PFX.macData.macSalt",tagClass:t.Class.UNIVERSAL,type:t.Type.OCTETSTRING,constructed:!1,capture:"macSalt"},{name:"PFX.macData.iterations",tagClass:t.Class.UNIVERSAL,type:t.Type.INTEGER,constructed:!1,optional:!0,capture:"macIterations"}]}]},o={name:"SafeBag",tagClass:t.Class.UNIVERSAL,type:t.Type.SEQUENCE,constructed:!0,value:[{name:"SafeBag.bagId",tagClass:t.Class.UNIVERSAL,type:t.Type.OID,constructed:!1,capture:"bagId"},{name:"SafeBag.bagValue",tagClass:t.Class.CONTEXT_SPECIFIC,constructed:!0,captureAsn1:"bagValue"},{name:"SafeBag.bagAttributes",tagClass:t.Class.UNIVERSAL,type:t.Type.SET,constructed:!0,optional:!0,capture:"bagAttributes"}]},u={name:"Attribute",tagClass:t.Class.UNIVERSAL,type:t.Type.SEQUENCE,constructed:!0,value:[{name:"Attribute.attrId",tagClass:t.Class.UNIVERSAL,type:t.Type.OID,constructed:!1,capture:"oid"},{name:"Attribute.attrValues",tagClass:t.Class.UNIVERSAL,type:t.Type.SET,constructed:!0,capture:"values"}]},a={name:"CertBag",tagClass:t.Class.UNIVERSAL,type:t.Type.SEQUENCE,constructed:!0,value:[{name:"CertBag.certId",tagClass:t.Class.UNIVERSAL,type:t.Type.OID,constructed:!1,capture:"certId"},{name:"CertBag.certValue",tagClass:t.Class.CONTEXT_SPECIFIC,constructed:!0,value:[{name:"CertBag.certValue[0]",tagClass:t.Class.UNIVERSAL,type:t.Class.OCTETSTRING,constructed:!1,capture:"cert"}]}]};r.pkcs12FromAsn1=function(i,o,u){typeof o=="string"?(u=o,o=!0):o===undefined&&(o=!0);var a={},c=[];if(!t.validate(i,s,a,c))throw{message:"Cannot read PKCS#12 PFX. ASN.1 object is not an PKCS#12 PFX.",errors:c};var h={version:a.version.charCodeAt(0),safeContents:[],getBags:function(t){var n={},r;return"localKeyId"in t?r=t.localKeyId:"localKeyIdHex"in t&&(r=e.util.hexToBytes(t.localKeyIdHex)),r!==undefined&&(n.localKeyId=f(h.safeContents,"localKeyId",r,t.bagType)),"friendlyName"in t&&(n.friendlyName=f(h.safeContents,"friendlyName",t.friendlyName,t.bagType)),n},getBagsByFriendlyName:function(e,t){return f(h.safeContents,"friendlyName",e,t)},getBagsByLocalKeyId:function(e,t){return f(h.safeContents,"localKeyId",e,t)}};if(a.version.charCodeAt(0)!==3)throw{message:"PKCS#12 PFX of version other than 3 not supported.",version:a.version.charCodeAt(0)};if(t.derToOid(a.contentType)!==n.oids.data)throw{message:"Only PKCS#12 PFX in password integrity mode supported.",oid:t.derToOid(a.contentType)};var p=a.content.value[0];if(p.tagClass!==t.Class.UNIVERSAL||p.type!==t.Type.OCTETSTRING)throw{message:"PKCS#12 authSafe content data is not an OCTET STRING."};if(a.mac){var d=null,v=0,m=t.derToOid(a.macAlgorithm);switch(m){case n.oids.sha1:d=e.md.sha1.create(),v=20;break;case n.oids.sha256:d=e.md.sha256.create(),v=32;break;case n.oids.sha384:d=e.md.sha384.create(),v=48;break;case n.oids.sha512:d=e.md.sha512.create(),v=64;break;case n.oids.md5:d=e.md.md5.create(),v=16}if(d===null)throw{message:"PKCS#12 uses unsupported MAC algorithm: "+m};var g=new e.util.ByteBuffer(a.macSalt),y="macIterations"in a?parseInt(e.util.bytesToHex(a.macIterations),16):1,b=r.generateKey(u||"",g,3,y,v,d),w=e.hmac.create();w.start(d,b),w.update(p.value);var E=w.getMac();if(E.getBytes()!==a.macDigest)throw{message:"PKCS#12 MAC could not be verified. Invalid password?"}}return l(h,p.value,o,u),h},r.toPkcs12Asn1=function(i,s,o,u){u=u||{},u.saltSize=u.saltSize||8,u.count=u.count||2048,u.algorithm=u.algorithm||u.encAlgorithm||"aes128","useMac"in u||(u.useMac=!0),"localKeyId"in u||(u.localKeyId=null),"generateLocalKeyId"in u||(u.generateLocalKeyId=!0);var a=u.localKeyId,f=undefined;if(a!==null)a=e.util.hexToBytes(a);else if(u.generateLocalKeyId)if(s){var l=e.util.isArray(s)?s[0]:s;typeof l=="string"&&(l=n.certificateFromPem(l));var c=e.md.sha1.create();c.update(t.toDer(n.certificateToAsn1(l)).getBytes()),a=c.digest().getBytes()}else a=e.random.getBytes(20);var h=[];a!==null&&h.push(t.create(t.Class.UNIVERSAL,t.Type.SEQUENCE,!0,[t.create(t.Class.UNIVERSAL,t.Type.OID,!1,t.oidToDer(n.oids.localKeyId).getBytes()),t.create(t.Class.UNIVERSAL,t.Type.SET,!0,[t.create(t.Class.UNIVERSAL,t.Type.OCTETSTRING,!1,a)])])),"friendlyName"in u&&h.push(t.create(t.Class.UNIVERSAL,t.Type.SEQUENCE,!0,[t.create(t.Class.UNIVERSAL,t.Type.OID,!1,t.oidToDer(n.oids.friendlyName).getBytes()),t.create(t.Class.UNIVERSAL,t.Type.SET,!0,[t.create(t.Class.UNIVERSAL,t.Type.BMPSTRING,!1,u.friendlyName)])])),h.length>0&&(f=t.create(t.Class.UNIVERSAL,t.Type.SET,!0,h));var p=[],d=[];s!==null&&(e.util.isArray(s)?d=s:d=[s]);var v=[];for(var m=0;m<d.length;++m){s=d[m],typeof s=="string"&&(s=n.certificateFromPem(s));var g=m===0?f:undefined,y=n.certificateToAsn1(s),b=t.create(t.Class.UNIVERSAL,t.Type.SEQUENCE,!0,[t.create(t.Class.UNIVERSAL,t.Type.OID,!1,t.oidToDer(n.oids.certBag).getBytes()),t.create(t.Class.CONTEXT_SPECIFIC,0,!0,[t.create(t.Class.UNIVERSAL,t.Type.SEQUENCE,!0,[t.create(t.Class.UNIVERSAL,t.Type.OID,!1,t.oidToDer(n.oids.x509Certificate).getBytes()),t.create(t.Class.CONTEXT_SPECIFIC,0,!0,[t.create(t.Class.UNIVERSAL,t.Type.OCTETSTRING,!1,t.toDer(y).getBytes())])])]),g]);v.push(b)}if(v.length>0){var w=t.create(t.Class.UNIVERSAL,t.Type.SEQUENCE,!0,v),E=t.create(t.Class.UNIVERSAL,t.Type.SEQUENCE,!0,[t.create(t.Class.UNIVERSAL,t.Type.OID,!1,t.oidToDer(n.oids.data).getBytes()),t.create(t.Class.CONTEXT_SPECIFIC,0,!0,[t.create(t.Class.UNIVERSAL,t.Type.OCTETSTRING,!1,t.toDer(w).getBytes())])]);p.push(E)}var S=null;if(i!==null){var x=n.wrapRsaPrivateKey(n.privateKeyToAsn1(i));o===null?S=t.create(t.Class.UNIVERSAL,t.Type.SEQUENCE,!0,[t.create(t.Class.UNIVERSAL,t.Type.OID,!1,t.oidToDer(n.oids.keyBag).getBytes()),t.create(t.Class.CONTEXT_SPECIFIC,0,!0,[x]),f]):S=t.create(t.Class.UNIVERSAL,t.Type.SEQUENCE,!0,[t.create(t.Class.UNIVERSAL,t.Type.OID,!1,t.oidToDer(n.oids.pkcs8ShroudedKeyBag).getBytes()),t.create(t.Class.CONTEXT_SPECIFIC,0,!0,[n.encryptPrivateKeyInfo(x,o,u)]),f]);var T=t.create(t.Class.UNIVERSAL,t.Type.SEQUENCE,!0,[S]),N=t.create(t.Class.UNIVERSAL,t.Type.SEQUENCE,!0,[t.create(t.Class.UNIVERSAL,t.Type.OID,!1,t.oidToDer(n.oids.data).getBytes()),t.create(t.Class.CONTEXT_SPECIFIC,0,!0,[t.create(t.Class.UNIVERSAL,t.Type.OCTETSTRING,!1,t.toDer(T).getBytes())])]);p.push(N)}var C=t.create(t.Class.UNIVERSAL,t.Type.SEQUENCE,!0,p),k=undefined;if(u.useMac){var c=e.md.sha1.create(),L=new e.util.ByteBuffer(e.random.getBytes(u.saltSize)),A=u.count,i=r.generateKey(o||"",L,3,A,20),O=e.hmac.create();O.start(c,i),O.update(t.toDer(C).getBytes());var M=O.getMac();k=t.create(t.Class.UNIVERSAL,t.Type.SEQUENCE,!0,[t.create(t.Class.UNIVERSAL,t.Type.SEQUENCE,!0,[t.create(t.Class.UNIVERSAL,t.Type.SEQUENCE,!0,[t.create(t.Class.UNIVERSAL,t.Type.OID,!1,t.oidToDer(n.oids.sha1).getBytes()),t.create(t.Class.UNIVERSAL,t.Type.NULL,!1,"")]),t.create(t.Class.UNIVERSAL,t.Type.OCTETSTRING,!1,M.getBytes())]),t.create(t.Class.UNIVERSAL,t.Type.OCTETSTRING,!1,L.getBytes()),t.create(t.Class.UNIVERSAL,t.Type.INTEGER,!1,e.util.hexToBytes(A.toString(16)))])}return t.create(t.Class.UNIVERSAL,t.Type.SEQUENCE,!0,[t.create(t.Class.UNIVERSAL,t.Type.INTEGER,!1,String.fromCharCode(3)),t.create(t.Class.UNIVERSAL,t.Type.SEQUENCE,!0,[t.create(t.Class.UNIVERSAL,t.Type.OID,!1,t.oidToDer(n.oids.data).getBytes()),t.create(t.Class.CONTEXT_SPECIFIC,0,!0,[t.create(t.Class.UNIVERSAL,t.Type.OCTETSTRING,!1,t.toDer(C).getBytes())])]),k])},r.generateKey=function(t,n,r,i,s,o){var u,a;if(typeof o=="undefined"||o===null)o=e.md.sha1.create();var f=o.digestLength,l=o.blockLength,c=new e.util.ByteBuffer,h=new e.util.ByteBuffer;for(a=0;a<t.length;a++)h.putInt16(t.charCodeAt(a));h.putInt16(0);var p=h.length(),d=n.length(),v=new e.util.ByteBuffer;v.fillWithByte(r,l);var m=l*Math.ceil(d/l),g=new e.util.ByteBuffer;for(a=0;a<m;a++)g.putByte(n.at(a%d));var y=l*Math.ceil(p/l),b=new e.util.ByteBuffer;for(a=0;a<y;a++)b.putByte(h.at(a%p));var w=g;w.putBuffer(b);var E=Math.ceil(s/f);for(var S=1;S<=E;S++){var x=new e.util.ByteBuffer;x.putBytes(v.bytes()),x.putBytes(w.bytes());for(var T=0;T<i;T++)o.start(),o.update(x.getBytes()),x=o.digest();var N=new e.util.ByteBuffer;for(a=0;a<l;a++)N.putByte(x.at(a%f));var C=Math.ceil(d/l)+Math.ceil(p/l),k=new e.util.ByteBuffer;for(u=0;u<C;u++){var L=new e.util.ByteBuffer(w.getBytes(l)),A=511;for(a=N.length()-1;a>=0;a--)A>>=8,A+=N.at(a)+L.at(a),L.setAt(a,A&255);k.putBuffer(L)}w=k,c.putBuffer(x)}return c.truncate(c.length()-s),c}}var t="pkcs12";if(typeof define!="function"){if(typeof module!="object"||!module.exports)return typeof forge=="undefined"&&(forge={}),e(forge);var n=!0;define=function(e,t){t(require,module)}}var r,i=function(n,i){i.exports=function(i){var s=r.map(function(e){return n(e)}).concat(e);i=i||{},i.defined=i.defined||{};if(i.defined[t])return i[t];i.defined[t]=!0;for(var o=0;o<s.length;++o)s[o](i);return i[t]}},s=define;define=function(e,t){return r=typeof e=="string"?t.slice(2):e.slice(2),n?(delete define,s.apply(null,Array.prototype.slice.call(arguments,0))):(define=s,define.apply(null,Array.prototype.slice.call(arguments,0)))},define("forge/pkcs12",["require","module","./asn1","./sha1","./pkcs7asn1","./pki","./util","./random","./hmac"],function(){i.apply(null,Array.prototype.slice.call(arguments,0))})}(),function(){function e(e){var t=e.pss=e.pss||{};t.create=function(t,n,r){var i=t.digestLength,s={};return s.verify=function(s,o,u){var a,f=u-1,l=Math.ceil(f/8);o=o.substr(-l);if(l<i+r+2)throw{message:"Inconsistent parameters to PSS signature verification."};if(o.charCodeAt(l-1)!==188)throw{message:"Encoded message does not end in 0xBC."};var c=l-i-1,h=o.substr(0,c),p=o.substr(c,i),d=65280>>8*l-f&255;if((h.charCodeAt(0)&d)!==0)throw{message:"Bits beyond keysize not zero as expected."};var v=n.generate(p,c),m="";for(a=0;a<c;a++)m+=String.fromCharCode(h.charCodeAt(a)^v.charCodeAt(a));m=String.fromCharCode(m.charCodeAt(0)&~d)+m.substr(1);var g=l-i-r-2;for(a=0;a<g;a++)if(m.charCodeAt(a)!==0)throw{message:"Leftmost octets not zero as expected"};if(m.charCodeAt(g)!==1)throw{message:"Inconsistent PSS signature, 0x01 marker not found"};var y=m.substr(-r),b=new e.util.ByteBuffer;b.fillWithByte(0,8),b.putBytes(s),b.putBytes(y),t.start(),t.update(b.getBytes());var w=t.digest().getBytes();return p===w},s.encode=function(s,o){var u,a=o-1,f=Math.ceil(a/8),l=s.digest().getBytes();if(f<i+r+2)throw{message:"Message is too long to encrypt"};var c=e.random.getBytes(r),h=new e.util.ByteBuffer;h.fillWithByte(0,8),h.putBytes(l),h.putBytes(c),t.start(),t.update(h.getBytes());var p=t.digest().getBytes(),d=new e.util.ByteBuffer;d.fillWithByte(0,f-r-i-2),d.putByte(1),d.putBytes(c);var v=d.getBytes(),m=f-i-1,g=n.generate(p,m),y="";for(u=0;u<m;u++)y+=String.fromCharCode(v.charCodeAt(u)^g.charCodeAt(u));var b=65280>>8*f-a&255;return y=String.fromCharCode(y.charCodeAt(0)&~b)+y.substr(1),y+p+String.fromCharCode(188)},s}}var t="pss";if(typeof define!="function"){if(typeof module!="object"||!module.exports)return typeof forge=="undefined"&&(forge={}),e(forge);var n=!0;define=function(e,t){t(require,module)}}var r,i=function(n,i){i.exports=function(i){var s=r.map(function(e){return n(e)}).concat(e);i=i||{},i.defined=i.defined||{};if(i.defined[t])return i[t];i.defined[t]=!0;for(var o=0;o<s.length;++o)s[o](i);return i[t]}},s=define;define=function(e,t){return r=typeof e=="string"?t.slice(2):e.slice(2),n?(delete define,s.apply(null,Array.prototype.slice.call(arguments,0))):(define=s,define.apply(null,Array.prototype.slice.call(arguments,0)))},define("forge/pss",["require","module","./random","./util"],function(){i.apply(null,Array.prototype.slice.call(arguments,0))})}(),function(){function e(e){var t=[217,120,249,196,25,221,181,237,40,233,253,121,74,160,216,157,198,126,55,131,43,118,83,142,98,76,100,136,68,139,251,162,23,154,89,245,135,179,79,19,97,69,109,141,9,129,125,50,189,143,64,235,134,183,123,11,240,149,33,34,92,107,78,130,84,214,101,147,206,96,178,28,115,86,192,20,167,140,241,220,18,117,202,31,59,190,228,209,66,61,212,48,163,60,182,38,111,191,14,218,70,105,7,87,39,242,29,155,188,148,67,3,248,17,199,246,144,239,62,231,6,195,213,47,200,102,30,215,8,232,234,222,128,82,238,247,132,170,114,172,53,77,106,42,150,26,210,113,90,21,73,116,75,159,208,94,4,24,164,236,194,224,65,110,15,81,203,204,36,145,175,80,161,244,112,57,153,124,58,133,35,184,180,122,252,2,54,91,37,85,151,49,45,93,250,152,227,138,146,174,5,223,41,16,103,108,186,201,211,0,230,207,225,158,168,44,99,22,1,63,88,226,137,169,13,56,52,27,171,51,255,176,187,72,12,95,185,177,205,46,197,243,219,71,229,165,156,119,10,166,32,104,254,127,193,173],n=[1,2,3,5],r=function(e,t){return e<<t&65535|(e&65535)>>16-t},i=function(e,t){return(e&65535)>>t|e<<16-t&65535};e.rc2=e.rc2||{},e.rc2.expandKey=function(n,r){typeof n=="string"&&(n=e.util.createBuffer(n)),r=r||128;var i=n,s=n.length(),o=r,u=Math.ceil(o/8),a=255>>(o&7),f;for(f=s;f<128;f++)i.putByte(t[i.at(f-1)+i.at(f-s)&255]);i.setAt(128-u,t[i.at(128-u)&a]);for(f=127-u;f>=0;f--)i.setAt(f,t[i.at(f+1)^i.at(f+u)]);return i};var s=function(t,s,o){var u=!1,a=null,f=null,l=null,c,h,p,d,v=[];t=e.rc2.expandKey(t,s);for(p=0;p<64;p++)v.push(t.getInt16Le());o?(c=function(e){for(p=0;p<4;p++)e[p]+=v[d]+(e[(p+3)%4]&e[(p+2)%4])+(~e[(p+3)%4]&e[(p+1)%4]),e[p]=r(e[p],n[p]),d++},h=function(e){for(p=0;p<4;p++)e[p]+=v[e[(p+3)%4]&63]}):(c=function(e){for(p=3;p>=0;p--)e[p]=i(e[p],n[p]),e[p]-=v[d]+(e[(p+3)%4]&e[(p+2)%4])+(~e[(p+3)%4]&e[(p+1)%4]),d--},h=function(e){for(p=3;p>=0;p--)e[p]-=v[e[(p+3)%4]&63]});var m=function(e){var t=[];for(p=0;p<4;p++){var n=a.getInt16Le();l!==null&&(o?n^=l.getInt16Le():l.putInt16Le(n)),t.push(n&65535)}d=o?0:63;for(var r=0;r<e.length;r++)for(var i=0;i<e[r][0];i++)e[r][1](t);for(p=0;p<4;p++)l!==null&&(o?l.putInt16Le(t[p]):t[p]^=l.getInt16Le()),f.putInt16Le(t[p])},g=null;return g={start:function(n,r){n&&typeof t=="string"&&n.length===8&&(n=e.util.createBuffer(n)),u=!1,a=e.util.createBuffer(),f=r||new e.util.createBuffer,l=n,g.output=f},update:function(e){u||a.putBuffer(e);while(a.length()>=8)m([[5,c],[1,h],[6,c],[1,h],[5,c]])},finish:function(e){var t=!0;if(o)if(e)t=e(8,a,!o);else{var n=a.length()===8?8:8-a.length();a.fillWithByte(n,n)}t&&(u=!0,g.update());if(!o){t=a.length()===0;if(t)if(e)t=e(8,f,!o);else{var r=f.length(),i=f.at(r-1);i>r?t=!1:f.truncate(i)}}return t}},g};e.rc2.startEncrypting=function(t,n,r){var i=e.rc2.createEncryptionCipher(t,128);return i.start(n,r),i},e.rc2.createEncryptionCipher=function(e,t){return s(e,t,!0)},e.rc2.startDecrypting=function(t,n,r){var i=e.rc2.createDecryptionCipher(t,128);return i.start(n,r),i},e.rc2.createDecryptionCipher=function(e,t){return s(e,t,!1)}}var t="rc2";if(typeof define!="function"){if(typeof module!="object"||!module.exports)return typeof forge=="undefined"&&(forge={}),e(forge);var n=!0;define=function(e,t){t(require,module)}}var r,i=function(n,i){i.exports=function(i){var s=r.map(function(e){return n(e)}).concat(e);i=i||{},i.defined=i.defined||{};if(i.defined[t])return i[t];i.defined[t]=!0;for(var o=0;o<s.length;++o)s[o](i);return i[t]}},s=define;define=function(e,t){return r=typeof e=="string"?t.slice(2):e.slice(2),n?(delete define,s.apply(null,Array.prototype.slice.call(arguments,0))):(define=s,define.apply(null,Array.prototype.slice.call(arguments,0)))},define("forge/rc2",["require","module","./util"],function(){i.apply(null,Array.prototype.slice.call(arguments,0))})}(),function(){function e(e){function n(e,t,n){var r="",i=Math.ceil(t/n.digestLength);for(var s=0;s<i;++s){var o=String.fromCharCode(s>>24&255,s>>16&255,s>>8&255,s&255);n.start(),n.update(e+o),r+=n.digest().getBytes()}return r.substring(0,t)}var t=e.pkcs1=e.pkcs1||{};t.encode_rsa_oaep=function(t,r,i){var s=undefined,o=undefined,u=undefined;typeof i=="string"?(s=i,o=arguments[3]||undefined,u=arguments[4]||undefined):i&&(s=i.label||undefined,o=i.seed||undefined,u=i.md||undefined),u?u.start():u=e.md.sha1.create();var a=Math.ceil(t.n.bitLength()/8),f=a-2*u.digestLength-2;if(r.length>f)throw{message:"RSAES-OAEP input message length is too long.",length:r.length,maxLength:f};s||(s=""),u.update(s,"raw");var l=u.digest(),c="",h=f-r.length;for(var p=0;p<h;p++)c+="\0";var d=l.getBytes()+c+""+r;if(!o)o=e.random.getBytes(u.digestLength);else if(o.length!==u.digestLength)throw{message:"Invalid RSAES-OAEP seed. The seed length must match the digest length.",seedLength:o.length,digestLength:u.digestLength};var v=n(o,a-u.digestLength-1,u),m=e.util.xorBytes(d,v,d.length),g=n(m,u.digestLength,u),y=e.util.xorBytes(o,g,o.length);return"\0"+y+m},t.decode_rsa_oaep=function(t,r,i){var s=undefined,o=undefined;typeof i=="string"?(s=i,o=arguments[3]||undefined):i&&(s=i.label||undefined,o=i.md||undefined);var u=Math.ceil(t.n.bitLength()/8);if(r.length!==u)throw{message:"RSAES-OAEP encoded message length is invalid.",length:r.length,expectedLength:u};o===undefined?o=e.md.sha1.create():o.start();if(u<2*o.digestLength+2)throw{message:"RSAES-OAEP key is too short for the hash function."};s||(s=""),o.update(s,"raw");var a=o.digest().getBytes(),f=r.charAt(0),l=r.substring(1,o.digestLength+1),c=r.substring(1+o.digestLength),h=n(c,o.digestLength,o),p=e.util.xorBytes(l,h,l.length),d=n(p,u-o.digestLength-1,o),v=e.util.xorBytes(c,d,c.length),m=v.substring(0,o.digestLength),g=f!=="\0";for(var y=0;y<o.digestLength;++y)g|=a.charAt(y)!==m.charAt(y);var b=1,w=o.digestLength;for(var E=o.digestLength;E<v.length;E++){var S=v.charCodeAt(E),x=S&1^1,T=b?65534:0;g|=S&T,b&=x,w+=b}if(g||v.charCodeAt(w)!==1)throw{message:"Invalid RSAES-OAEP padding."};return v.substring(w+1)}}var t="pkcs1";if(typeof define!="function"){if(typeof module!="object"||!module.exports)return typeof forge=="undefined"&&(forge={}),e(forge);var n=!0;define=function(e,t){t(require,module)}}var r,i=function(n,i){i.exports=function(i){var s=r.map(function(e){return n(e)}).concat(e);i=i||{},i.defined=i.defined||{};if(i.defined[t])return i[t];i.defined[t]=!0;for(var o=0;o<s.length;++o)s[o](i);return i[t]}},s=define;define=function(e,t){return r=typeof e=="string"?t.slice(2):e.slice(2),n?(delete define,s.apply(null,Array.prototype.slice.call(arguments,0))):(define=s,define.apply(null,Array.prototype.slice.call(arguments,0)))},define("forge/pkcs1",["require","module","./util","./random","./sha1"],function(){i.apply(null,Array.prototype.slice.call(arguments,0))})}(),function(){function e(e){function o(t,n,r){var i=e.util.createBuffer(),s=Math.ceil(n.n.bitLength()/8);if(t.length>s-11)throw{message:"Message is too long for PKCS#1 v1.5 padding.",length:t.length,max:s-11};i.putByte(0),i.putByte(r);var o=s-3-t.length,u;if(r===0||r===1){u=r===0?0:255;for(var a=0;a<o;++a)i.putByte(u)}else for(var a=0;a<o;++a)u=Math.floor(Math.random()*255)+1,i.putByte(u);return i.putByte(0),i.putBytes(t),i}function u(t,n,r,i){var s=Math.ceil(n.n.bitLength()/8),o=e.util.createBuffer(t),u=o.getByte(),a=o.getByte();if(u!==0||r&&a!==0&&a!==1||!r&&a!=2||r&&a===0&&typeof i=="undefined")throw{message:"Encryption block is invalid."};var f=0;if(a===0){f=s-3-i;for(var l=0;l<f;++l)if(o.getByte()!==0)throw{message:"Encryption block is invalid."}}else if(a===1){f=0;while(o.length()>1){if(o.getByte()!==255){--o.read;break}++f}}else if(a===2){f=0;while(o.length()>1){if(o.getByte()===0){--o.read;break}++f}}var c=o.getByte();if(c!==0||f!==s-3-o.length())throw{message:"Encryption block is invalid."};return o.getBytes()}function a(t,n,r){function c(){h(t.pBits,function(e,n){if(e)return r(e);t.p=n,h(t.qBits,p)})}function h(e,n){function p(){var n=e-1,r=new BigInteger(e,t.rng);return r.testBit(n)||r.bitwiseTo(BigInteger.ONE.shiftLeft(n),l,r),r.dAddOffset(31-r.mod(f).byteValue(),0),r}function v(i){if(d)return;--c;var s=i.data;if(s.found){for(var a=0;a<r.length;++a)r[a].terminate();return d=!0,n(null,new BigInteger(s.prime,16))}h.bitLength()>e&&(h=p());var f=h.toString(16);i.target.postMessage({e:t.eInt,hex:f,workLoad:o}),h.dAddOffset(u,0)}var r=[];for(var i=0;i<s;++i)r[i]=new Worker(a);var c=s,h=p();for(var i=0;i<s;++i)r[i].addEventListener("message",v);var d=!1}function p(n,i){t.q=i;if(t.p.compareTo(t.q)<0){var s=t.p;t.p=t.q,t.q=s}t.p1=t.p.subtract(BigInteger.ONE),t.q1=t.q.subtract(BigInteger.ONE),t.phi=t.p1.multiply(t.q1);if(t.phi.gcd(t.e).compareTo(BigInteger.ONE)!==0){t.p=t.q=null,c();return}t.n=t.p.multiply(t.q);if(t.n.bitLength()!==t.bits){t.q=null,h(t.qBits,p);return}var o=t.e.modInverse(t.phi);t.keys={privateKey:e.pki.rsa.setPrivateKey(t.n,t.e,o,t.p,t.q,o.mod(t.p1),o.mod(t.q1),t.q.modInverse(t.p)),publicKey:e.pki.rsa.setPublicKey(t.n,t.e)},r(null,t.keys)}typeof n=="function"&&(r=n,n={});if(typeof Worker=="undefined"){function i(){if(e.pki.rsa.stepKeyPairGenerationState(t,10))return r(null,t.keys);e.util.setImmediate(i)}return i()}var s=n.workers||2,o=n.workLoad||100,u=o*30/8,a=n.workerScript||"forge/prime.worker.js",f=new BigInteger(null);f.fromInt(30);var l=function(e,t){return e|t};c()}typeof BigInteger=="undefined"&&(BigInteger=e.jsbn.BigInteger);var t=e.asn1;e.pki=e.pki||{},e.pki.rsa=e.rsa=e.rsa||{};var n=e.pki,r=[6,4,2,4,2,4,6,2],i=function(n){var r;if(n.algorithm in e.pki.oids){r=e.pki.oids[n.algorithm];var i=t.oidToDer(r).getBytes(),s=t.create(t.Class.UNIVERSAL,t.Type.SEQUENCE,!0,[]),o=t.create(t.Class.UNIVERSAL,t.Type.SEQUENCE,!0,[]);o.value.push(t.create(t.Class.UNIVERSAL,t.Type.OID,!1,i)),o.value.push(t.create(t.Class.UNIVERSAL,t.Type.NULL,!1,""));var u=t.create(t.Class.UNIVERSAL,t.Type.OCTETSTRING,!1,n.digest().getBytes());return s.value.push(o),s.value.push(u),t.toDer(s).getBytes()}throw{message:"Unknown message digest algorithm.",algorithm:n.algorithm}},s=function(e,t,n){var r;if(n)r=e.modPow(t.e,t.n);else{t.dP||(t.dP=t.d.mod(t.p.subtract(BigInteger.ONE))),t.dQ||(t.dQ=t.d.mod(t.q.subtract(BigInteger.ONE))),t.qInv||(t.qInv=t.q.modInverse(t.p));var i=e.mod(t.p).modPow(t.dP,t.p),s=e.mod(t.q).modPow(t.dQ,t.q);while(i.compareTo(s)<0)i=i.add(t.p);r=i.subtract(s).multiply(t.qInv).mod(t.p).multiply(t.q).add(s)}return r};n.rsa.encrypt=function(t,n,r){var i=r,u,a=Math.ceil(n.n.bitLength()/8);r!==!1&&r!==!0?(i=r===2,u=o(t,n,r)):(u=e.util.createBuffer(),u.putBytes(t));var f=new BigInteger(u.toHex(),16),l=s(f,n,i),c=l.toString(16),h=e.util.createBuffer(),p=a-Math.ceil(c.length/2);while(p>0)h.putByte(0),--p;return h.putBytes(e.util.hexToBytes(c)),h.getBytes()},n.rsa.decrypt=function(t,n,r,i){var o=Math.ceil(n.n.bitLength()/8);if(t.length!==o)throw{message:"Encrypted message length is invalid.",length:t.length,expected:o};var a=new BigInteger(e.util.createBuffer(t).toHex(),16);if(a.compareTo(n.n)>=0)throw{message:"Encrypted message is invalid."};var f=s(a,n,r),l=f.toString(16),c=e.util.createBuffer(),h=o-Math.ceil(l.length/2);while(h>0)c.putByte(0),--h;return c.putBytes(e.util.hexToBytes(l)),i!==!1?u(c.getBytes(),n,r):c.getBytes()},n.rsa.createKeyPairGenerationState=function(t,n){typeof t=="string"&&(t=parseInt(t,10)),t=t||1024;var r={nextBytes:function(t){var n=e.random.getBytes(t.length);for(var r=0;r<t.length;++r)t[r]=n.charCodeAt(r)}},i={state:0,bits:t,rng:r,eInt:n||65537,e:new BigInteger(null),p:null,q:null,qBits:t>>1,pBits:t-(t>>1),pqState:0,num:null,keys:null};return i.e.fromInt(i.eInt),i},n.rsa.stepKeyPairGenerationState=function(t,n){var i=new BigInteger(null);i.fromInt(30);var s=0,o=function(e,t){return e|t},u=+(new Date),a,f=0;while(t.keys===null&&(n<=0||f<n)){if(t.state===0){var l=t.p===null?t.pBits:t.qBits,c=l-1;t.pqState===0?(t.num=new BigInteger(l,t.rng),t.num.testBit(c)||t.num.bitwiseTo(BigInteger.ONE.shiftLeft(c),o,t.num),t.num.dAddOffset(31-t.num.mod(i).byteValue(),0),s=0,++t.pqState):t.pqState===1?t.num.bitLength()>l?t.pqState=0:t.num.isProbablePrime(1)?++t.pqState:t.num.dAddOffset(r[s++%8],0):t.pqState===2?t.pqState=t.num.subtract(BigInteger.ONE).gcd(t.e).compareTo(BigInteger.ONE)===0?3:0:t.pqState===3&&(t.pqState=0,t.num.isProbablePrime(10)&&(t.p===null?t.p=t.num:t.q=t.num,t.p!==null&&t.q!==null&&++t.state),t.num=null)}else if(t.state===1)t.p.compareTo(t.q)<0&&(t.num=t.p,t.p=t.q,t.q=t.num),++t.state;else if(t.state===2)t.p1=t.p.subtract(BigInteger.ONE),t.q1=t.q.subtract(BigInteger.ONE),t.phi=t.p1.multiply(t.q1),++t.state;else if(t.state===3)t.phi.gcd(t.e).compareTo(BigInteger.ONE)===0?++t.state:(t.p=null,t.q=null,t.state=0);else if(t.state===4)t.n=t.p.multiply(t.q),t.n.bitLength()===t.bits?++t.state:(t.q=null,t.state=0);else if(t.state===5){var h=t.e.modInverse(t.phi);t.keys={privateKey:e.pki.rsa.setPrivateKey(t.n,t.e,h,t.p,t.q,h.mod(t.p1),h.mod(t.q1),t.q.modInverse(t.p)),publicKey:e.pki.rsa.setPublicKey(t.n,t.e)}}a=+(new Date),f+=a-u,u=a}return t.keys!==null},n.rsa.generateKeyPair=function(e,t,r,i){arguments.length===1?typeof e=="object"?(r=e,e=undefined):typeof e=="function"&&(i=e,e=undefined):arguments.length===2?(typeof e=="number"?typeof t=="function"?i=t:r=t:(r=e,i=t,e=undefined),t=undefined):arguments.length===3&&(typeof t=="number"?typeof r=="function"&&(i=r,r=undefined):(i=r,r=t,t=undefined)),r=r||{},e===undefined&&(e=r.bits||1024),t===undefined&&(t=r.e||65537);var s=n.rsa.createKeyPairGenerationState(e,t);if(!i)return n.rsa.stepKeyPairGenerationState(s,0),s.keys;a(s,r,i)},n.rsa.setPublicKey=function(r,i){var s={n:r,e:i};return s.encrypt=function(t,r,i){typeof r=="string"?r=r.toUpperCase():r===undefined&&(r="RSAES-PKCS1-V1_5");if(r==="RSAES-PKCS1-V1_5")r={encode:function(e,t,n){return o(e,t,2).getBytes()}};else if(r==="RSA-OAEP"||r==="RSAES-OAEP")r={encode:function(t,n){return e.pkcs1.encode_rsa_oaep(n,t,i)}};else{if(["RAW","NONE","NULL",null].indexOf(r)===-1)throw{message:'Unsupported encryption scheme: "'+r+'".'};r={encode:function(e){return e}}}var u=r.encode(t,s,!0);return n.rsa.encrypt(u,s,!0)},s.verify=function(e,r,i){typeof i=="string"?i=i.toUpperCase():i===undefined&&(i="RSASSA-PKCS1-V1_5");if(i==="RSASSA-PKCS1-V1_5")i={verify:function(e,n){n=u(n,s,!0);var r=t.fromDer(n);return e===r.value[1].value}};else if(i==="NONE"||i==="NULL"||i===null)i={verify:function(e,t){return t=u(t,s,!0),e===t}};var o=n.rsa.decrypt(r,s,!0,!1);return i.verify(e,o,s.n.bitLength())},s},n.rsa.setPrivateKey=function(t,r,s,o,a,f,l,c){var h={n:t,e:r,d:s,p:o,q:a,dP:f,dQ:l,qInv:c};return h.decrypt=function(t,r,i){typeof r=="string"?r=r.toUpperCase():r===undefined&&(r="RSAES-PKCS1-V1_5");var s=n.rsa.decrypt(t,h,!1,!1);if(r==="RSAES-PKCS1-V1_5")r={decode:u};else if(r==="RSA-OAEP"||r==="RSAES-OAEP")r={decode:function(t,n){return e.pkcs1.decode_rsa_oaep(n,t,i)}};else{if(["RAW","NONE","NULL",null].indexOf(r)===-1)throw{message:'Unsupported encryption scheme: "'+r+'".'};r={decode:function(e){return e}}}return r.decode(s,h,!1)},h.sign=function(e,t){var r=!1;typeof t=="string"&&(t=t.toUpperCase());if(t===undefined||t==="RSASSA-PKCS1-V1_5")t={encode:i},r=1;else if(t==="NONE"||t==="NULL"||t===null)t={encode:function(){return e}},r=1;var s=t.encode(e,h.n.bitLength());return n.rsa.encrypt(s,h,r)},h}}var t="rsa";if(typeof define!="function"){if(typeof module!="object"||!module.exports)return typeof forge=="undefined"&&(forge={}),e(forge);var n=!0;define=function(e,t){t(require,module)}}var r,i=function(n,i){i.exports=function(i){var s=r.map(function(e){return n(e)}).concat(e);i=i||{},i.defined=i.defined||{};if(i.defined[t])return i[t];i.defined[t]=!0;for(var o=0;o<s.length;++o)s[o](i);return i[t]}},s=define;define=function(e,t){return r=typeof e=="string"?t.slice(2):e.slice(2),n?(delete define,s.apply(null,Array.prototype.slice.call(arguments,0))):(define=s,define.apply(null,Array.prototype.slice.call(arguments,0)))},define("forge/rsa",["require","module","./asn1","./oids","./random","./util","./jsbn","./pkcs1"],function(){i.apply(null,Array.prototype.slice.call(arguments,0))})}(),function(){function e(e){function w(n){var r=t.create(t.Class.UNIVERSAL,t.Type.SEQUENCE,!0,[]),i,s,o=n.attributes;for(var u=0;u<o.length;++u){i=o[u];var a=i.value,f=t.Type.PRINTABLESTRING;"valueTagClass"in i&&(f=i.valueTagClass,f===t.Type.UTF8&&(a=e.util.encodeUtf8(a))),s=t.create(t.Class.UNIVERSAL,t.Type.SET,!0,[t.create(t.Class.UNIVERSAL,t.Type.SEQUENCE,!0,[t.create(t.Class.UNIVERSAL,t.Type.OID,!1,t.oidToDer(i.type).getBytes()),t.create(t.Class.UNIVERSAL,f,!1,a)])]),r.value.push(s)}return r}function E(e){var n=t.create(t.Class.CONTEXT_SPECIFIC,3,!0,[]),r=t.create(t.Class.UNIVERSAL,t.Type.SEQUENCE,!0,[]);n.value.push(r);var i,s;for(var o=0;o<e.length;++o){i=e[o],s=t.create(t.Class.UNIVERSAL,t.Type.SEQUENCE,!0,[]),r.value.push(s),s.value.push(t.create(t.Class.UNIVERSAL,t.Type.OID,!1,t.oidToDer(i.id).getBytes())),i.critical&&s.value.push(t.create(t.Class.UNIVERSAL,t.Type.BOOLEAN,!1,String.fromCharCode(255)));var u=i.value;typeof i.value!="string"&&(u=t.toDer(u).getBytes()),s.value.push(t.create(t.Class.UNIVERSAL,t.Type.OCTETSTRING,!1,u))}return n}function S(e,n){switch(e){case r["RSASSA-PSS"]:var i=[];return n.hash.algorithmOid!==undefined&&i.push(t.create(t.Class.CONTEXT_SPECIFIC,0,!0,[t.create(t.Class.UNIVERSAL,t.Type.SEQUENCE,!0,[t.create(t.Class.UNIVERSAL,t.Type.OID,!1,t.oidToDer(n.hash.algorithmOid).getBytes()),t.create(t.Class.UNIVERSAL,t.Type.NULL,!1,"")])])),n.mgf.algorithmOid!==undefined&&i.push(t.create(t.Class.CONTEXT_SPECIFIC,1,!0,[t.create(t.Class.UNIVERSAL,t.Type.SEQUENCE,!0,[t.create(t.Class.UNIVERSAL,t.Type.OID,!1,t.oidToDer(n.mgf.algorithmOid).getBytes()),t.create(t.Class.UNIVERSAL,t.Type.SEQUENCE,!0,[t.create(t.Class.UNIVERSAL,t.Type.OID,!1,t.oidToDer(n.mgf.hash.algorithmOid).getBytes()),t.create(t.Class.UNIVERSAL,t.Type.NULL,!1,"")])])])),n.saltLength!==undefined&&i.push(t.create(t.Class.CONTEXT_SPECIFIC,2,!0,[t.create(t.Class.UNIVERSAL,t.Type.INTEGER,!1,String.fromCharCode(n.saltLength))])),t.create(t.Class.UNIVERSAL,t.Type.SEQUENCE,!0,i);default:return t.create(t.Class.UNIVERSAL,t.Type.NULL,!1,"")}}function x(n){var r=t.create(t.Class.CONTEXT_SPECIFIC,0,!0,[]);if(n.attributes.length===0)return r;var i=n.attributes;for(var s=0;s<i.length;++s){var o=i[s],u=o.value,a=t.Type.UTF8;"valueTagClass"in o&&(a=o.valueTagClass),a===t.Type.UTF8&&(u=e.util.encodeUtf8(u));var f=t.create(t.Class.UNIVERSAL,t.Type.SEQUENCE,!0,[t.create(t.Class.UNIVERSAL,t.Type.OID,!1,t.oidToDer(o.type).getBytes()),t.create(t.Class.UNIVERSAL,t.Type.SET,!0,[t.create(t.Class.UNIVERSAL,a,!1,u)])]);r.value.push(f)}return r}function T(e,t,n){var r=[N(e+t)];for(var i=16,s=1;i<n;++s,i+=16)r.push(N(r[s-1]+e+t));return r.join("").substr(0,n)}function N(t){return e.md.md5.create().update(t).digest().getBytes()}typeof BigInteger=="undefined"&&(BigInteger=e.jsbn.BigInteger);var t=e.asn1,n=e.pki=e.pki||{},r=n.oids;n.pbe={};var i={};i.CN=r.commonName,i.commonName="CN",i.C=r.countryName,i.countryName="C",i.L=r.localityName,i.localityName="L",i.ST=r.stateOrProvinceName,i.stateOrProvinceName="ST",i.O=r.organizationName,i.organizationName="O",i.OU=r.organizationalUnitName,i.organizationalUnitName="OU",i.E=r.emailAddress,i.emailAddress="E";var s={name:"SubjectPublicKeyInfo",tagClass:t.Class.UNIVERSAL,type:t.Type.SEQUENCE,constructed:!0,captureAsn1:"subjectPublicKeyInfo",value:[{name:"SubjectPublicKeyInfo.AlgorithmIdentifier",tagClass:t.Class.UNIVERSAL,type:t.Type.SEQUENCE,constructed:!0,value:[{name:"AlgorithmIdentifier.algorithm",tagClass:t.Class.UNIVERSAL,type:t.Type.OID,constructed:!1,capture:"publicKeyOid"}]},{name:"SubjectPublicKeyInfo.subjectPublicKey",tagClass:t.Class.UNIVERSAL,type:t.Type.BITSTRING,constructed:!1,value:[{name:"SubjectPublicKeyInfo.subjectPublicKey.RSAPublicKey",tagClass:t.Class.UNIVERSAL,type:t.Type.SEQUENCE,constructed:!0,optional:!0,captureAsn1:"rsaPublicKey"}]}]},o={name:"RSAPublicKey",tagClass:t.Class.UNIVERSAL,type:t.Type.SEQUENCE,constructed:!0,value:[{name:"RSAPublicKey.modulus",tagClass:t.Class.UNIVERSAL,type:t.Type.INTEGER,constructed:!1,capture:"publicKeyModulus"},{name:"RSAPublicKey.exponent",tagClass:t.Class.UNIVERSAL,type:t.Type.INTEGER,constructed:!1,capture:"publicKeyExponent"}]},u={name:"Certificate",tagClass:t.Class.UNIVERSAL,type:t.Type.SEQUENCE,constructed:!0,value:[{name:"Certificate.TBSCertificate",tagClass:t.Class.UNIVERSAL,type:t.Type.SEQUENCE,constructed:!0,captureAsn1:"tbsCertificate",value:[{name:"Certificate.TBSCertificate.version",tagClass:t.Class.CONTEXT_SPECIFIC,type:0,constructed:!0,optional:!0,value:[{name:"Certificate.TBSCertificate.version.integer",tagClass:t.Class.UNIVERSAL,type:t.Type.INTEGER,constructed:!1,capture:"certVersion"}]},{name:"Certificate.TBSCertificate.serialNumber",tagClass:t.Class.UNIVERSAL,type:t.Type.INTEGER,constructed:!1,capture:"certSerialNumber"},{name:"Certificate.TBSCertificate.signature",tagClass:t.Class.UNIVERSAL,type:t.Type.SEQUENCE,constructed:!0,value:[{name:"Certificate.TBSCertificate.signature.algorithm",tagClass:t.Class.UNIVERSAL,type:t.Type.OID,constructed:!1,capture:"certinfoSignatureOid"},{name:"Certificate.TBSCertificate.signature.parameters",tagClass:t.Class.UNIVERSAL,optional:!0,captureAsn1:"certinfoSignatureParams"}]},{name:"Certificate.TBSCertificate.issuer",tagClass:t.Class.UNIVERSAL,type:t.Type.SEQUENCE,constructed:!0,captureAsn1:"certIssuer"},{name:"Certificate.TBSCertificate.validity",tagClass:t.Class.UNIVERSAL,type:t.Type.SEQUENCE,constructed:!0,value:[{name:"Certificate.TBSCertificate.validity.notBefore (utc)",tagClass:t.Class.UNIVERSAL,type:t.Type.UTCTIME,constructed:!1,optional:!0,capture:"certValidity1UTCTime"},{name:"Certificate.TBSCertificate.validity.notBefore (generalized)",tagClass:t.Class.UNIVERSAL,type:t.Type.GENERALIZEDTIME,constructed:!1,optional:!0,capture:"certValidity2GeneralizedTime"},{name:"Certificate.TBSCertificate.validity.notAfter (utc)",tagClass:t.Class.UNIVERSAL,type:t.Type.UTCTIME,constructed:!1,optional:!0,capture:"certValidity3UTCTime"},{name:"Certificate.TBSCertificate.validity.notAfter (generalized)",tagClass:t.Class.UNIVERSAL,type:t.Type.GENERALIZEDTIME,constructed:!1,optional:!0,capture:"certValidity4GeneralizedTime"}]},{name:"Certificate.TBSCertificate.subject",tagClass:t.Class.UNIVERSAL,type:t.Type.SEQUENCE,constructed:!0,captureAsn1:"certSubject"},s,{name:"Certificate.TBSCertificate.issuerUniqueID",tagClass:t.Class.CONTEXT_SPECIFIC,type:1,constructed:!0,optional:!0,value:[{name:"Certificate.TBSCertificate.issuerUniqueID.id",tagClass:t.Class.UNIVERSAL,type:t.Type.BITSTRING,constructed:!1,capture:"certIssuerUniqueId"}]},{name:"Certificate.TBSCertificate.subjectUniqueID",tagClass:t.Class.CONTEXT_SPECIFIC,type:2,constructed:!0,optional:!0,value:[{name:"Certificate.TBSCertificate.subjectUniqueID.id",tagClass:t.Class.UNIVERSAL,type:t.Type.BITSTRING,constructed:!1,capture:"certSubjectUniqueId"}]},{name:"Certificate.TBSCertificate.extensions",tagClass:t.Class.CONTEXT_SPECIFIC,type:3,constructed:!0,captureAsn1:"certExtensions",optional:!0}]},{name:"Certificate.signatureAlgorithm",tagClass:t.Class.UNIVERSAL,type:t.Type.SEQUENCE,constructed:!0,value:[{name:"Certificate.signatureAlgorithm.algorithm",tagClass:t.Class.UNIVERSAL,type:t.Type.OID,constructed:!1,capture:"certSignatureOid"},{name:"Certificate.TBSCertificate.signature.parameters",tagClass:t.Class.UNIVERSAL,optional:!0,captureAsn1:"certSignatureParams"}]},{name:"Certificate.signatureValue",tagClass:t.Class.UNIVERSAL,type:t.Type.BITSTRING,constructed:!1,capture:"certSignature"}]},a={name:"PrivateKeyInfo",tagClass:t.Class.UNIVERSAL,type:t.Type.SEQUENCE,constructed:!0,value:[{name:"PrivateKeyInfo.version",tagClass:t.Class.UNIVERSAL,type:t.Type.INTEGER,constructed:!1,capture:"privateKeyVersion"},{name:"PrivateKeyInfo.privateKeyAlgorithm",tagClass:t.Class.UNIVERSAL,type:t.Type.SEQUENCE,constructed:!0,value:[{name:"AlgorithmIdentifier.algorithm",tagClass:t.Class.UNIVERSAL,type:t.Type.OID,constructed:!1,capture:"privateKeyOid"}]},{name:"PrivateKeyInfo",tagClass:t.Class.UNIVERSAL,type:t.Type.OCTETSTRING,constructed:!1,capture:"privateKey"}]},f={name:"RSAPrivateKey",tagClass:t.Class.UNIVERSAL,type:t.Type.SEQUENCE,constructed:!0,value:[{name:"RSAPrivateKey.version",tagClass:t.Class.UNIVERSAL,type:t.Type.INTEGER,constructed:!1,capture:"privateKeyVersion"},{name:"RSAPrivateKey.modulus",tagClass:t.Class.UNIVERSAL,type:t.Type.INTEGER,constructed:!1,capture:"privateKeyModulus"},{name:"RSAPrivateKey.publicExponent",tagClass:t.Class.UNIVERSAL,type:t.Type.INTEGER,constructed:!1,capture:"privateKeyPublicExponent"},{name:"RSAPrivateKey.privateExponent",tagClass:t.Class.UNIVERSAL,type:t.Type.INTEGER,constructed:!1,capture:"privateKeyPrivateExponent"},{name:"RSAPrivateKey.prime1",tagClass:t.Class.UNIVERSAL,type:t.Type.INTEGER,constructed:!1,capture:"privateKeyPrime1"},{name:"RSAPrivateKey.prime2",tagClass:t.Class.UNIVERSAL,type:t.Type.INTEGER,constructed:!1,capture:"privateKeyPrime2"},{name:"RSAPrivateKey.exponent1",tagClass:t.Class.UNIVERSAL,type:t.Type.INTEGER,constructed:!1,capture:"privateKeyExponent1"},{name:"RSAPrivateKey.exponent2",tagClass:t.Class.UNIVERSAL,type:t.Type.INTEGER,constructed:!1,capture:"privateKeyExponent2"},{name:"RSAPrivateKey.coefficient",tagClass:t.Class.UNIVERSAL,type:t.Type.INTEGER,constructed:!1,capture:"privateKeyCoefficient"}]},l={name:"EncryptedPrivateKeyInfo",tagClass:t.Class.UNIVERSAL,type:t.Type.SEQUENCE,constructed:!0,value:[{name:"EncryptedPrivateKeyInfo.encryptionAlgorithm",tagClass:t.Class.UNIVERSAL,type:t.Type.SEQUENCE,constructed:!0,value:[{name:"AlgorithmIdentifier.algorithm",tagClass:t.Class.UNIVERSAL,type:t.Type.OID,constructed:!1,capture:"encryptionOid"},{name:"AlgorithmIdentifier.parameters",tagClass:t.Class.UNIVERSAL,type:t.Type.SEQUENCE,constructed:!0,captureAsn1:"encryptionParams"}]},{name:"EncryptedPrivateKeyInfo.encryptedData",tagClass:t.Class.UNIVERSAL,type:t.Type.OCTETSTRING,constructed:!1,capture:"encryptedData"}]},c={name:"PBES2Algorithms",tagClass:t.Class.UNIVERSAL,type:t.Type.SEQUENCE,constructed:!0,value:[{name:"PBES2Algorithms.keyDerivationFunc",tagClass:t.Class.UNIVERSAL,type:t.Type.SEQUENCE,constructed:!0,value:[{name:"PBES2Algorithms.keyDerivationFunc.oid",tagClass:t.Class.UNIVERSAL,type:t.Type.OID,constructed:!1,capture:"kdfOid"},{name:"PBES2Algorithms.params",tagClass:t.Class.UNIVERSAL,type:t.Type.SEQUENCE,constructed:!0,value:[{name:"PBES2Algorithms.params.salt",tagClass:t.Class.UNIVERSAL,type:t.Type.OCTETSTRING,constructed:!1,capture:"kdfSalt"},{name:"PBES2Algorithms.params.iterationCount",tagClass:t.Class.UNIVERSAL,type:t.Type.INTEGER,onstructed:!0,capture:"kdfIterationCount"}]}]},{name:"PBES2Algorithms.encryptionScheme",tagClass:t.Class.UNIVERSAL,type:t.Type.SEQUENCE,constructed:!0,value:[{name:"PBES2Algorithms.encryptionScheme.oid",tagClass:t.Class.UNIVERSAL,type:t.Type.OID,constructed:!1,capture:"encOid"},{name:"PBES2Algorithms.encryptionScheme.iv",tagClass:t.Class.UNIVERSAL,type:t.Type.OCTETSTRING,constructed:!1,capture:"encIv"}]}]},h={name:"pkcs-12PbeParams",tagClass:t.Class.UNIVERSAL,type:t.Type.SEQUENCE,constructed:!0,value:[{name:"pkcs-12PbeParams.salt",tagClass:t.Class.UNIVERSAL,type:t.Type.OCTETSTRING,constructed:!1,capture:"salt"},{name:"pkcs-12PbeParams.iterations",tagClass:t.Class.UNIVERSAL,type:t.Type.INTEGER,constructed:!1,capture:"iterations"}]},p={name:"rsapss",tagClass:t.Class.UNIVERSAL,type:t.Type.SEQUENCE,constructed:!0,value:[{name:"rsapss.hashAlgorithm",tagClass:t.Class.CONTEXT_SPECIFIC,type:0,constructed:!0,value:[{name:"rsapss.hashAlgorithm.AlgorithmIdentifier",tagClass:t.Class.UNIVERSAL,type:t.Class.SEQUENCE,constructed:!0,optional:!0,value:[{name:"rsapss.hashAlgorithm.AlgorithmIdentifier.algorithm",tagClass:t.Class.UNIVERSAL,type:t.Type.OID,constructed:!1,capture:"hashOid"}]}]},{name:"rsapss.maskGenAlgorithm",tagClass:t.Class.CONTEXT_SPECIFIC,type:1,constructed:!0,value:[{name:"rsapss.maskGenAlgorithm.AlgorithmIdentifier",tagClass:t.Class.UNIVERSAL,type:t.Class.SEQUENCE,constructed:!0,optional:!0,value:[{name:"rsapss.maskGenAlgorithm.AlgorithmIdentifier.algorithm",tagClass:t.Class.UNIVERSAL,type:t.Type.OID,constructed:!1,capture:"maskGenOid"},{name:"rsapss.maskGenAlgorithm.AlgorithmIdentifier.params",tagClass:t.Class.UNIVERSAL,type:t.Type.SEQUENCE,constructed:!0,value:[{name:"rsapss.maskGenAlgorithm.AlgorithmIdentifier.params.algorithm",tagClass:t.Class.UNIVERSAL,type:t.Type.OID,constructed:!1,capture:"maskGenHashOid"}]}]}]},{name:"rsapss.saltLength",tagClass:t.Class.CONTEXT_SPECIFIC,type:2,optional:!0,value:[{name:"rsapss.saltLength.saltLength",tagClass:t.Class.UNIVERSAL,type:t.Class.INTEGER,constructed:!1,capture:"saltLength"}]},{name:"rsapss.trailerField",tagClass:t.Class.CONTEXT_SPECIFIC,type:3,optional:!0,value:[{name:"rsapss.trailer.trailer",tagClass:t.Class.UNIVERSAL,type:t.Class.INTEGER,constructed:!1,capture:"trailer"}]}]},d={name:"CertificationRequestInfo",tagClass:t.Class.UNIVERSAL,type:t.Type.SEQUENCE,constructed:!0,captureAsn1:"certificationRequestInfo",value:[{name:"CertificationRequestInfo.integer",tagClass:t.Class.UNIVERSAL,type:t.Type.INTEGER,constructed:!1,capture:"certificationRequestInfoVersion"},{name:"CertificationRequestInfo.subject",tagClass:t.Class.UNIVERSAL,type:t.Type.SEQUENCE,constructed:!0,captureAsn1:"certificationRequestInfoSubject"},s,{name:"CertificationRequestInfo.attributes",tagClass:t.Class.CONTEXT_SPECIFIC,type:0,constructed:!0,optional:!0,capture:"certificationRequestInfoAttributes",value:[{name:"CertificationRequestInfo.attributes",tagClass:t.Class.UNIVERSAL,type:t.Type.SEQUENCE,constructed:!0,value:[{name:"CertificationRequestInfo.attributes.type",tagClass:t.Class.UNIVERSAL,type:t.Type.OID,constructed:!1},{name:"CertificationRequestInfo.attributes.value",tagClass:t.Class.UNIVERSAL,type:t.Type.SET,constructed:!0}]}]}]},v={name:"CertificationRequest",tagClass:t.Class.UNIVERSAL,type:t.Type.SEQUENCE,constructed:!0,captureAsn1:"csr",value:[d,{name:"CertificationRequest.signatureAlgorithm",tagClass:t.Class.UNIVERSAL,type:t.Type.SEQUENCE,constructed:!0,value:[{name:"CertificationRequest.signatureAlgorithm.algorithm",tagClass:t.Class.UNIVERSAL,type:t.Type.OID,constructed:!1,capture:"csrSignatureOid"},{name:"CertificationRequest.signatureAlgorithm.parameters",tagClass:t.Class.UNIVERSAL,optional:!0,captureAsn1:"csrSignatureParams"}]},{name:"CertificationRequest.signature",tagClass:t.Class.UNIVERSAL,type:t.Type.BITSTRING,constructed:!1,capture:"csrSignature"}]};n.RDNAttributesAsArray=function(e,n){var s=[],o,u,a;for(var f=0;f<e.value.length;++f){o=e.value[f];for(var l=0;l<o.value.length;++l)a={},u=o.value[l],a.type=t.derToOid(u.value[0].value),a.value=u.value[1].value,a.valueTagClass=u.value[1].type,a.type in r&&(a.name=r[a.type],a.name in i&&(a.shortName=i[a.name])),n&&(n.update(a.type),n.update(a.value)),s.push(a)}return s},n.CRIAttributesAsArray=function(e){var n=[];for(var s=0;s<e.length;++s){var o=e[s],u=t.derToOid(o.value[0].value),a=o.value[1].value;for(var f=0;f<a.length;++f){var l={};l.type=u,l.value=a[f].value,l.valueTagClass=a[f].type,l.type in r&&(l.name=r[l.type],l.name in i&&(l.shortName=i[l.name])),n.push(l)}}return n};var m=function(e,t){typeof t=="string"&&(t={shortName:t});var n=null,r;for(var i=0;n===null&&i<e.attributes.length;++i)r=e.attributes[i],t.type&&t.type===r.type?n=r:t.name&&t.name===r.name?n=r:t.shortName&&t.shortName===r.shortName&&(n=r);return n},g=function(n){var i=[],s,o,u;for(var a=0;a<n.value.length;++a){u=n.value[a];for(var f=0;f<u.value.length;++f){o=u.value[f],s={},s.id=t.derToOid(o.value[0].value),s.critical=!1,o.value[1].type===t.Type.BOOLEAN?(s.critical=o.value[1].value.charCodeAt(0)!==0,s.value=o.value[2].value):s.value=o.value[1].value;if(s.id in r){s.name=r[s.id];if(s.name==="keyUsage"){var l=t.fromDer(s.value),c=0,h=0;l.value.length>1&&(c=l.value.charCodeAt(1),h=l.value.length>2?l.value.charCodeAt(2):0),s.digitalSignature=(c&128)===128,s.nonRepudiation=(c&64)===64,s.keyEncipherment=(c&32)===32,s.dataEncipherment=(c&16)===16,s.keyAgreement=(c&8)===8,s.keyCertSign=(c&4)===4,s.cRLSign=(c&2)===2,s.encipherOnly=(c&1)===1,s.decipherOnly=(h&128)===128}else if(s.name==="basicConstraints"){var l=t.fromDer(s.value);l.value.length>0?s.cA=l.value[0].value.charCodeAt(0)!==0:s.cA=!1;if(l.value.length>1){var p=e.util.createBuffer(l.value[1].value);s.pathLenConstraint=p.getInt(p.length()<<3)}}else if(s.name==="extKeyUsage"){var l=t.fromDer(s.value);for(var d=0;d<l.value.length;++d){var v=t.derToOid(l.value[d].value);v in r?s[r[v]]=!0:s[v]=!0}}else if(s.name==="nsCertType"){var l=t.fromDer(s.value),c=0;l.value.length>1&&(c=l.value.charCodeAt(1)),s.client=(c&128)===128,s.server=(c&64)===64,s.email=(c&32)===32,s.objsign=(c&16)===16,s.reserved=(c&8)===8,s.sslCA=(c&4)===4,s.emailCA=(c&2)===2,s.objCA=(c&1)===1}else if(s.name==="subjectAltName"||s.name==="issuerAltName"){s.altNames=[];var m,l=t.fromDer(s.value);for(var g=0;g<l.value.length;++g){m=l.value[g];var y={type:m.type,value:m.value};s.altNames.push(y);switch(m.type){case 1:case 2:case 6:break;case 7:break;case 8:y.oid=t.derToOid(m.value);break;default:}}}else if(s.name==="subjectKeyIdentifier"){var l=t.fromDer(s.value);s.subjectKeyIdentifier=e.util.bytesToHex(l.value)}}i.push(s)}}return i};n.pemToDer=function(t){var n=e.pem.decode(t)[0];if(n.procType&&n.procType.type==="ENCRYPTED")throw{message:"Could not convert PEM to DER; PEM is encrypted."};return e.util.createBuffer(n.body)};var y=function(t){var n=t.toString(16);return n[0]>="8"&&(n="00"+n),e.util.hexToBytes(n)},b=function(e,n,i){var s={};if(e!==r["RSASSA-PSS"])return s;i&&(s={hash:{algorithmOid:r.sha1},mgf:{algorithmOid:r.mgf1,hash:{algorithmOid:r.sha1}},saltLength:20});var o={},u=[];if(!t.validate(n,p,o,u))throw{message:"Cannot read RSASSA-PSS parameter block.",errors:u};return o.hashOid!==undefined&&(s.hash=s.hash||{},s.hash.algorithmOid=t.derToOid(o.hashOid)),o.maskGenOid!==undefined&&(s.mgf=s.mgf||{},s.mgf.algorithmOid=t.derToOid(o.maskGenOid),s.mgf.hash=s.mgf.hash||{},s.mgf.hash.algorithmOid=t.derToOid(o.maskGenHashOid)),o.saltLength!==undefined&&(s.saltLength=o.saltLength.charCodeAt(0)),s};n.certificateFromPem=function(r,i,s){var o=e.pem.decode(r)[0];if(o.type!=="CERTIFICATE"&&o.type!=="X509 CERTIFICATE"&&o.type!=="TRUSTED CERTIFICATE")throw{message:'Could not convert certificate from PEM; PEM header type is not "CERTIFICATE", "X509 CERTIFICATE", or "TRUSTED CERTIFICATE".',headerType:o.type};if(o.procType&&o.procType.type==="ENCRYPTED")throw{message:"Could not convert certificate from PEM; PEM is encrypted."};var u=t.fromDer(o.body,s);return n.certificateFromAsn1(u,i)},n.certificateToPem=function(r,i){var s={type:"CERTIFICATE",body:t.toDer(n.certificateToAsn1(r)).getBytes()};return e.pem.encode(s,{maxline:i})},n.publicKeyFromPem=function(r){var i=e.pem.decode(r)[0];if(i.type!=="PUBLIC KEY"&&i.type!=="RSA PUBLIC KEY")throw{message:'Could not convert public key from PEM; PEM header type is not "PUBLIC KEY" or "RSA PUBLIC KEY".',headerType:i.type};if(i.procType&&i.procType.type==="ENCRYPTED")throw{message:"Could not convert public key from PEM; PEM is encrypted."};var s=t.fromDer(i.body);return n.publicKeyFromAsn1(s)},n.publicKeyToPem=function(r,i){var s={type:"PUBLIC KEY",body:t.toDer(n.publicKeyToAsn1(r)).getBytes()};return e.pem.encode(s,{maxline:i})},n.publicKeyToRSAPublicKeyPem=function(r,i){var s={type:"RSA PUBLIC KEY",body:t.toDer(n.publicKeyToRSAPublicKey(r)).getBytes()};return e.pem.encode(s,{maxline:i})},n.privateKeyFromPem=function(r){var i=e.pem.decode(r)[0];if(i.type!=="PRIVATE KEY"&&i.type!=="RSA PRIVATE KEY")throw{message:'Could not convert private key from PEM; PEM header type is not "PRIVATE KEY" or "RSA PRIVATE KEY".',headerType:i.type};if(i.procType&&i.procType.type==="ENCRYPTED")throw{message:"Could not convert private key from PEM; PEM is encrypted."};var s=t.fromDer(i.body);return n.privateKeyFromAsn1(s)},n.privateKeyToPem=function(r,i){var s={type:"RSA PRIVATE KEY",body:t.toDer(n.privateKeyToAsn1(r)).getBytes()};return e.pem.encode(s,{maxline:i})},n.certificationRequestFromPem=function(r,i,s){var o=e.pem.decode(r)[0];if(o.type!=="CERTIFICATE REQUEST")throw{message:'Could not convert certification request from PEM; PEM header type is not "CERTIFICATE REQUEST".',headerType:o.type};if(o.procType&&o.procType.type==="ENCRYPTED")throw{message:"Could not convert certification request from PEM; PEM is encrypted."};var u=t.fromDer(o.body,s);return n.certificationRequestFromAsn1(u,i)},n.certificationRequestToPem=function(r,i){var s={type:"CERTIFICATE REQUEST",body:t.toDer(n.certificationRequestToAsn1(r)).getBytes()};return e.pem.encode(s,{maxline:i})},n.createCertificate=function(){var s={};s.version=2,s.serialNumber="00",s.signatureOid=null,s.signature=null,s.siginfo={},s.siginfo.algorithmOid=null,s.validity={},s.validity.notBefore=new Date,s.validity.notAfter=new Date,s.issuer={},s.issuer.getField=function(e){return m(s.issuer,e)},s.issuer.addField=function(e){o([e]),s.issuer.attributes.push(e)},s.issuer.attributes=[],s.issuer.hash=null,s.subject={},s.subject.getField=function(e){return m(s.subject,e)},s.subject.addField=function(e){o([e]),s.subject.attributes.push(e)},s.subject.attributes=[],s.subject.hash=null,s.extensions=[],s.publicKey=null,s.md=null;var o=function(e){var t;for(var r=0;r<e.length;++r){t=e[r],typeof t.name=="undefined"&&(t.type&&t.type in n.oids?t.name=n.oids[t.type]:t.shortName&&t.shortName in i&&(t.name=n.oids[i[t.shortName]]));if(typeof t.type=="undefined"){if(!(t.name&&t.name in n.oids))throw{message:"Attribute type not specified.",attribute:t};t.type=n.oids[t.name]}typeof t.shortName=="undefined"&&t.name&&t.name in i&&(t.shortName=i[t.name]);if(typeof t.value=="undefined")throw{message:"Attribute value not specified.",attribute:t}}};return s.setSubject=function(e,t){o(e),s.subject.attributes=e,delete s.subject.uniqueId,t&&(s.subject.uniqueId=t),s.subject.hash=null},s.setIssuer=function(e,t){o(e),s.issuer.attributes=e,delete s.issuer.uniqueId,t&&(s.issuer.uniqueId=t),s.issuer.hash=null},s.setExtensions=function(i){var o;for(var u=0;u<i.length;++u){o=i[u],typeof o.name=="undefined"&&o.id&&o.id in n.oids&&(o.name=n.oids[o.id]);if(typeof o.id=="undefined"){if(!(o.name&&o.name in n.oids))throw{message:"Extension ID not specified.",extension:o};o.id=n.oids[o.name]}if(typeof o.value=="undefined"){if(o.name==="keyUsage"){var a=0,f=0,l=0;o.digitalSignature&&(f|=128,a=7),o.nonRepudiation&&(f|=64,a=6),o.keyEncipherment&&(f|=32,a=5),o.dataEncipherment&&(f|=16,a=4),o.keyAgreement&&(f|=8,a=3),o.keyCertSign&&(f|=4,a=2),o.cRLSign&&(f|=2,a=1),o.encipherOnly&&(f|=1,a=0),o.decipherOnly&&(l|=128,a=7);var c=String.fromCharCode(a);l!==0?c+=String.fromCharCode(f)+String.fromCharCode(l):f!==0&&(c+=String.fromCharCode(f)),o.value=t.create(t.Class.UNIVERSAL,t.Type.BITSTRING,!1,c)}else if(o.name==="basicConstraints"){o.value=t.create(t.Class.UNIVERSAL,t.Type.SEQUENCE,!0,[]),o.cA&&o.value.value.push(t.create(t.Class.UNIVERSAL,t.Type.BOOLEAN,!1,String.fromCharCode(255)));if(o.pathLenConstraint){var h=o.pathLenConstraint,p=e.util.createBuffer();p.putInt(h,h.toString(2).length),o.value.value.push(t.create(t.Class.UNIVERSAL,t.Type.INTEGER,!1,p.getBytes()))}}else if(o.name==="extKeyUsage"){o.value=t.create(t.Class.UNIVERSAL,t.Type.SEQUENCE,!0,[]);var d=o.value.value;for(var v in o){if(o[v]!==!0)continue;v in r?d.push(t.create(t.Class.UNIVERSAL,t.Type.OID,!1,t.oidToDer(r[v]).getBytes())):v.indexOf(".")!==-1&&d.push(t.create(t.Class.UNIVERSAL,t.Type.OID,!1,t.oidToDer(v).getBytes()))}}else if(o.name==="nsCertType"){var a=0,f=0;o.client&&(f|=128,a=7),o.server&&(f|=64,a=6),o.email&&(f|=32,a=5),o.objsign&&(f|=16,a=4),o.reserved&&(f|=8,a=3),o.sslCA&&(f|=4,a=2),o.emailCA&&(f|=2,a=1),o.objCA&&(f|=1,a=0);var c=String.fromCharCode(a);f!==0&&(c+=String.fromCharCode(f)),o.value=t.create(t.Class.UNIVERSAL,t.Type.BITSTRING,!1,c)}else if(o.name==="subjectAltName"||o.name==="issuerAltName"){o.value=t.create(t.Class.UNIVERSAL,t.Type.SEQUENCE,!0,[]);var m;for(var g=0;g<o.altNames.length;++g){m=o.altNames[g];var c=m.value;m.type===8&&(c=t.oidToDer(c)),o.value.value.push(t.create(t.Class.CONTEXT_SPECIFIC,m.type,!1,c))}}else if(o.name==="subjectKeyIdentifier"){var y=s.generateSubjectKeyIdentifier();o.subjectKeyIdentifier=y.toHex(),o.value=t.create(t.Class.UNIVERSAL,t.Type.OCTETSTRING,!1,y.getBytes())}if(typeof o.value=="undefined")throw{message:"Extension value not specified.",extension:o}}}s.extensions=i},s.getExtension=function(e){typeof e=="string"&&(e={name:e});var t=null,n;for(var r=0;t===null&&r<s.extensions.length;++r)n=s.extensions[r],e.id&&n.id===e.id?t=n:e.name&&n.name===e.name&&(t=n);return t},s.sign=function(i,o){s.md=o||e.md.sha1.create();var u=r[s.md.algorithm+"WithRSAEncryption"];if(!u)throw{message:"Could not compute certificate digest. Unknown message digest algorithm OID.",algorithm:s.md.algorithm};s.signatureOid=s.siginfo.algorithmOid=u,s.tbsCertificate=n.getTBSCertificate(s);var a=t.toDer(s.tbsCertificate);s.md.update(a.getBytes()),s.signature=i.sign(s.md)},s.verify=function(i){var o=!1,u=i.md;if(u===null){if(i.signatureOid in r){var a=r[i.signatureOid];switch(a){case"sha1WithRSAEncryption":u=e.md.sha1.create();break;case"md5WithRSAEncryption":u=e.md.md5.create();break;case"sha256WithRSAEncryption":u=e.md.sha256.create();break;case"RSASSA-PSS":u=e.md.sha256.create()}}if(u===null)throw{message:"Could not compute certificate digest. Unknown signature OID.",signatureOid:i.signatureOid};var f=i.tbsCertificate||n.getTBSCertificate(i),l=t.toDer(f);u.update(l.getBytes())}if(u!==null){var c=undefined;switch(i.signatureOid){case r.sha1WithRSAEncryption:c=undefined;break;case r["RSASSA-PSS"]:var h,p;h=r[i.signatureParameters.mgf.hash.algorithmOid];if(h===undefined||e.md[h]===undefined)throw{message:"Unsupported MGF hash function.",oid:i.signatureParameters.mgf.hash.algorithmOid,name:h};p=r[i.signatureParameters.mgf.algorithmOid];if(p===undefined||e.mgf[p]===undefined)throw{message:"Unsupported MGF function.",oid:i.signatureParameters.mgf.algorithmOid,name:p};p=e.mgf[p].create(e.md[h].create()),h=r[i.signatureParameters.hash.algorithmOid];if(h===undefined||e.md[h]===undefined)throw{message:"Unsupported RSASSA-PSS hash function.",oid:i.signatureParameters.hash.algorithmOid,name:h};c=e.pss.create(e.md[h].create(),p,i.signatureParameters.saltLength)}o=s.publicKey.verify(u.digest().getBytes(),i.signature,c)}return o},s.isIssuer=function(e){var t=!1,n=s.issuer,r=e.subject;if(n.hash&&r.hash)t=n.hash===r.hash;else if(n.attributes.length===r.attributes.length){t=!0;var i,o;for(var u=0;t&&u<n.attributes.length;++u){i=n.attributes[u],o=r.attributes[u];if(i.type!==o.type||i.value!==o.value)t=!1}}return t},s.generateSubjectKeyIdentifier=function(){var r=t.toDer(n.publicKeyToRSAPublicKey(s.publicKey)),i=e.md.sha1.create();return i.update(r.getBytes()),i.digest()},s.verifySubjectKeyIdentifier=function(){var t=!1,n=r.subjectKeyIdentifier;for(var i=0;i<s.extensions.length;++i){var o=s.extensions[i];if(o.id===n){var u=s.generateSubjectKeyIdentifier().getBytes();return e.util.hexToBytes(o.subjectKeyIdentifier)===u}}return!1},s},n.certificateFromAsn1=function(i,s){var o={},a=[];if(!t.validate(i,u,o,a))throw{message:"Cannot read X.509 certificate. ASN.1 object is not an X509v3 Certificate.",errors:a};if(typeof o.certSignature!="string"){var f="\0";for(var l=0;l<o.certSignature.length;++l)f+=t.toDer(o.certSignature[l]).getBytes();o.certSignature=f}var c=t.derToOid(o.publicKeyOid);if(c!==n.oids.rsaEncryption)throw{message:"Cannot read public key. OID is not RSA."};var h=n.createCertificate();h.version=o.certVersion?o.certVersion.charCodeAt(0):0;var p=e.util.createBuffer(o.certSerialNumber);h.serialNumber=p.toHex(),h.signatureOid=e.asn1.derToOid(o.certSignatureOid),h.signatureParameters=b(h.signatureOid,o.certSignatureParams,!0),h.siginfo.algorithmOid=e.asn1.derToOid(o.certinfoSignatureOid),h.siginfo.parameters=b(h.siginfo.algorithmOid,o.certinfoSignatureParams,!1);var d=e.util.createBuffer(o.certSignature);++d.read,h.signature=d.getBytes();var v=[];o.certValidity1UTCTime!==undefined&&v.push(t.utcTimeToDate(o.certValidity1UTCTime)),o.certValidity2GeneralizedTime!==undefined&&v.push(t.generalizedTimeToDate(o.certValidity2GeneralizedTime)),o.certValidity3UTCTime!==undefined&&v.push(t.utcTimeToDate(o.certValidity3UTCTime)),o.certValidity4GeneralizedTime!==undefined&&v.push(t.generalizedTimeToDate(o.certValidity4GeneralizedTime));if(v.length>2)throw{message:"Cannot read notBefore/notAfter validity times; more than two times were provided in the certificate."};if(v.length<2)throw{message:"Cannot read notBefore/notAfter validity times; they were not provided as either UTCTime or GeneralizedTime."};h.validity.notBefore=v[0],h.validity.notAfter=v[1],h.tbsCertificate=o.tbsCertificate;if(s){h.md=null;if(h.signatureOid in r){var c=r[h.signatureOid];switch(c){case"sha1WithRSAEncryption":h.md=e.md.sha1.create();break;case"md5WithRSAEncryption":h.md=e.md.md5.create();break;case"sha256WithRSAEncryption":h.md=e.md.sha256.create();break;case"RSASSA-PSS":h.md=e.md.sha256.create()}}if(h.md===null)throw{message:"Could not compute certificate digest. Unknown signature OID.",signatureOid:h.signatureOid};var y=t.toDer(h.tbsCertificate);h.md.update(y.getBytes())}var w=e.md.sha1.create();h.issuer.getField=function(e){return m(h.issuer,e)},h.issuer.addField=function(e){_fillMissingFields([e]),h.issuer.attributes.push(e)},h.issuer.attributes=n.RDNAttributesAsArray(o.certIssuer,w),o.certIssuerUniqueId&&(h.issuer.uniqueId=o.certIssuerUniqueId),h.issuer.hash=w.digest().toHex();var E=e.md.sha1.create();return h.subject.getField=function(e){return m(h.subject,e)},h.subject.addField=function(e){_fillMissingFields([e]),h.subject.attributes.push(e)},h.subject.attributes=n.RDNAttributesAsArray(o.certSubject,E),o.certSubjectUniqueId&&(h.subject.uniqueId=o.certSubjectUniqueId),h.subject.hash=E.digest().toHex(),o.certExtensions?h.extensions=g(o.certExtensions):h.extensions=[],h.publicKey=n.publicKeyFromAsn1(o.subjectPublicKeyInfo),h},n.certificationRequestFromAsn1=function(i,s){var o={},u=[];if(!t.validate(i,v,o,u))throw{message:"Cannot read PKCS#10 certificate request. ASN.1 object is not a PKCS#10 CertificationRequest.",errors:u};if(typeof o.csrSignature!="string"){var a="\0";for(var f=0;f<o.csrSignature.length;++f)a+=t.toDer(o.csrSignature[f]).getBytes();o.csrSignature=a}var l=t.derToOid(o.publicKeyOid);if(l!==n.oids.rsaEncryption)throw{message:"Cannot read public key. OID is not RSA."};var c=n.createCertificationRequest();c.version=o.csrVersion?o.csrVersion.charCodeAt(0):0,c.signatureOid=e.asn1.derToOid(o.csrSignatureOid),c.signatureParameters=b(c.signatureOid,o.csrSignatureParams,!0),c.siginfo.algorithmOid=e.asn1.derToOid(o.csrSignatureOid),c.siginfo.parameters=b(c.siginfo.algorithmOid,o.csrSignatureParams,!1);var h=e.util.createBuffer(o.csrSignature);++h.read,c.signature=h.getBytes(),c.certificationRequestInfo=o.certificationRequestInfo;if(s){c.md=null;if(c.signatureOid in r){var l=r[c.signatureOid];switch(l){case"sha1WithRSAEncryption":c.md=e.md.sha1.create();break;case"md5WithRSAEncryption":c.md=e.md.md5.create();break;case"sha256WithRSAEncryption":c.md=e.md.sha256.create();break;case"RSASSA-PSS":c.md=e.md.sha256.create()}}if(c.md===null)throw{message:"Could not compute certification request digest. Unknown signature OID.",signatureOid:c.signatureOid};var p=t.toDer(c.certificationRequestInfo);c.md.update(p.getBytes())}var d=e.md.sha1.create();return c.subject.getField=function(e){return m(c.subject,e)},c.subject.addField=function(e){_fillMissingFields([e]),c.subject.attributes.push(e)},c.subject.attributes=n.RDNAttributesAsArray(o.certificationRequestInfoSubject,d),c.subject.hash=d.digest().toHex(),c.publicKey=n.publicKeyFromAsn1(o.subjectPublicKeyInfo),c.getAttribute=function(e){return m(c.attributes,e)},c.addAttribute=function(e){_fillMissingFields([e]),c.attributes.push(e)},c.attributes=n.CRIAttributesAsArray(o.certificationRequestInfoAttributes),c},n.createCertificationRequest=function(){var s={};s.version=0,s.signatureOid=null,s.signature=null,s.siginfo={},s.siginfo.algorithmOid=null,s.subject={},s.subject.getField=function(e){return m(s.subject,e)},s.subject.addField=function(e){o([e]),s.subject.attributes.push(e)},s.subject.attributes=[],s.subject.hash=null,s.publicKey=null,s.attributes=[],s.getAttribute=function(e){return m(s.attributes,e)},s.addAttribute=function(e){o([e]),s.attributes.push(e)},s.md=null;var o=function(e){var t;for(var r=0;r<e.length;++r){t=e[r],typeof t.name=="undefined"&&(t.type&&t.type in n.oids?t.name=n.oids[t.type]:t.shortName&&t.shortName in i&&(t.name=n.oids[i[t.shortName]]));if(typeof t.type=="undefined"){if(!(t.name&&t.name in n.oids))throw{message:"Attribute type not specified.",attribute:t};t.type=n.oids[t.name]}typeof t.shortName=="undefined"&&t.name&&t.name in i&&(t.shortName=i[t.name]);if(typeof t.value=="undefined")throw{message:"Attribute value not specified.",attribute:t}}};return s.setSubject=function(e){o(e),s.subject.attributes=e,s.subject.hash=null},s.setAttributes=function(e){o(e),s.attributes=e},s.sign=function(i,o){s.md=o||e.md.sha1.create();var u=r[s.md.algorithm+"WithRSAEncryption"];if(!u)throw{message:"Could not compute certification request digest. Unknown message digest algorithm OID.",algorithm:s.md.algorithm};s.signatureOid=s.siginfo.algorithmOid=u,s.certificationRequestInfo=n.getCertificationRequestInfo(s);var a=t.toDer(s.certificationRequestInfo);s.md.update(a.getBytes()),s.signature=i.sign(s.md)},s.verify=function(){var i=!1,o=s.md;if(o===null){if(s.signatureOid in r){var u=r[s.signatureOid];switch(u){case"sha1WithRSAEncryption":o=e.md.sha1.create();break;case"md5WithRSAEncryption":o=e.md.md5.create();break;case"sha256WithRSAEncryption":o=e.md.sha256.create();break;case"RSASSA-PSS":o=e.md.sha256.create()}}if(o===null)throw{message:"Could not compute certification request digest. Unknown signature OID.",signatureOid:s.signatureOid};var a=s.certificationRequestInfo||n.getCertificationRequestInfo(s),f=t.toDer(a);o.update(f.getBytes())}if(o!==null){var l=undefined;switch(s.signatureOid){case r.sha1WithRSAEncryption:l=undefined;break;case r["RSASSA-PSS"]:var c,h;c=r[s.signatureParameters.mgf.hash.algorithmOid];if(c===undefined||e.md[c]===undefined)throw{message:"Unsupported MGF hash function.",oid:s.signatureParameters.mgf.hash.algorithmOid,name:c};h=r[s.signatureParameters.mgf.algorithmOid];if(h===undefined||e.mgf[h]===undefined)throw{message:"Unsupported MGF function.",oid:s.signatureParameters.mgf.algorithmOid,name:h};h=e.mgf[h].create(e.md[c].create()),c=r[s.signatureParameters.hash.algorithmOid];if(c===undefined||e.md[c]===undefined)throw{message:"Unsupported RSASSA-PSS hash function.",oid:s.signatureParameters.hash.algorithmOid,name:c};l=e.pss.create(e.md[c].create(),h,s.signatureParameters.saltLength)}i=s.publicKey.verify(o.digest().getBytes(),s.signature,l)}return i},s},n.getTBSCertificate=function(r){var i=t.create(t.Class.UNIVERSAL,t.Type.SEQUENCE,!0,[t.create(t.Class.CONTEXT_SPECIFIC,0,!0,[t.create(t.Class.UNIVERSAL,t.Type.INTEGER,!1,String.fromCharCode(r.version))]),t.create(t.Class.UNIVERSAL,t.Type.INTEGER,!1,e.util.hexToBytes(r.serialNumber)),t.create(t.Class.UNIVERSAL,t.Type.SEQUENCE,!0,[t.create(t.Class.UNIVERSAL,t.Type.OID,!1,t.oidToDer(r.siginfo.algorithmOid).getBytes()),S(r.siginfo.algorithmOid,r.siginfo.parameters)]),w(r.issuer),t.create(t.Class.UNIVERSAL,t.Type.SEQUENCE,!0,[t.create(t.Class.UNIVERSAL,t.Type.UTCTIME,!1,t.dateToUtcTime(r.validity.notBefore)),t.create(t.Class.UNIVERSAL,t.Type.UTCTIME,!1,t.dateToUtcTime(r.validity.notAfter))]),w(r.subject),n.publicKeyToAsn1(r.publicKey)]);return r.issuer.uniqueId&&i.value.push(t.create(t.Class.CONTEXT_SPECIFIC,1,!0,[t.create(t.Class.UNIVERSAL,t.Type.BITSTRING,!1,String.fromCharCode(0)+r.issuer.uniqueId)])),r.subject.uniqueId&&i.value.push(t.create(t.Class.CONTEXT_SPECIFIC,2,!0,[t.create(t.Class.UNIVERSAL,t.Type.BITSTRING,!1,String.fromCharCode(0)+r.subject.uniqueId)])),r.extensions.length>0&&i.value.push(E(r.extensions)),i},n.getCertificationRequestInfo=function(e){var r=t.create(t.Class.UNIVERSAL,t.Type.SEQUENCE,!0,[t.create(t.Class.UNIVERSAL,t.Type.INTEGER,!1,String.fromCharCode(e.version)),w(e.subject),n.publicKeyToAsn1(e.publicKey),x(e)]);return r},n.distinguishedNameToAsn1=function(e){return w(e)},n.certificateToAsn1=function(e){var r=e.tbsCertificate||n.getTBSCertificate(e);return t.create(t.Class.UNIVERSAL,t.Type.SEQUENCE,!0,[r,t.create(t.Class.UNIVERSAL,t.Type.SEQUENCE,!0,[t.create(t.Class.UNIVERSAL,t.Type.OID,!1,t.oidToDer(e.signatureOid).getBytes()),S(e.signatureOid,e.signatureParameters)]),t.create(t.Class.UNIVERSAL,t.Type.BITSTRING,!1,String.fromCharCode(0)+e.signature)])},n.certificationRequestToAsn1=function(e){var r=e.certificationRequestInfo||n.getCertificationRequestInfo(e);return t.create(t.Class.UNIVERSAL,t.Type.SEQUENCE,!0,[r,t.create(t.Class.UNIVERSAL,t.Type.SEQUENCE,!0,[t.create(t.Class.UNIVERSAL,t.Type.OID,!1,t.oidToDer(e.signatureOid).getBytes()),S(e.signatureOid,e.signatureParameters)]),t.create(t.Class.UNIVERSAL,t.Type.BITSTRING,!1,String.fromCharCode(0)+e.signature)])},n.createCaStore=function(t){var r={certs:{}};r.getIssuer=function(t){var i=null;if(!t.issuer.hash){var s=e.md.sha1.create();t.issuer.attributes=n.RDNAttributesAsArray(w(t.issuer),s),t.issuer.hash=s.digest().toHex()}if(t.issuer.hash in r.certs){i=r.certs[t.issuer.hash];if(e.util.isArray(i))throw{message:"Resolving multiple issuer matches not implemented yet."}}return i},r.addCertificate=function(t){typeof t=="string"&&(t=e.pki.certificateFromPem(t));if(!t.subject.hash){var i=e.md.sha1.create();t.subject.attributes=n.RDNAttributesAsArray(w(t.subject),i),t.subject.hash=i.digest().toHex()}if(t.subject.hash in r.certs){var s=r.certs[t.subject.hash];e.util.isArray(s)||(s=[s]),s.push(t)}else r.certs[t.subject.hash]=t};if(t)for(var i=0;i<t.length;++i){var s=t[i];r.addCertificate(s)}return r},n.certificateError={bad_certificate:"forge.pki.BadCertificate",unsupported_certificate:"forge.pki.UnsupportedCertificate",certificate_revoked:"forge.pki.CertificateRevoked",certificate_expired:"forge.pki.CertificateExpired",certificate_unknown:"forge.pki.CertificateUnknown",unknown_ca:"forge.pki.UnknownCertificateAuthority"},n.verifyCertificateChain=function(t,r,i){r=r.slice(0);var s=r.slice(0),o=new Date,u=!0,a=null,f=0,l=null;do{var c=r.shift();if(o<c.validity.notBefore||o>c.validity.notAfter)a={message:"Certificate is not valid yet or has expired.",error:n.certificateError.certificate_expired,notBefore:c.validity.notBefore,notAfter:c.validity.notAfter,now:o};else{var h=!1;if(r.length>0){l=r[0];try{h=l.verify(c)}catch(p){}}else{var d=t.getIssuer(c);if(d===null)a={message:"Certificate is not trusted.",error:n.certificateError.unknown_ca};else{e.util.isArray(d)||(d=[d]);while(!h&&d.length>0){l=d.shift();try{h=l.verify(c)}catch(p){}}}}a===null&&!h&&(a={message:"Certificate signature is invalid.",error:n.certificateError.bad_certificate})}a===null&&!c.isIssuer(l)&&(a={message:"Certificate issuer is invalid.",error:n.certificateError.bad_certificate});if(a===null){var v={keyUsage:!0,basicConstraints:!0};for(var m=0;a===null&&m<c.extensions.length;++m){var g=c.extensions[m];g.critical&&!(g.name in v)&&(a={message:"Certificate has an unsupported critical extension.",error:n.certificateError.unsupported_certificate})}}if(!u||r.length===0&&!l){var y=c.getExtension("basicConstraints"),b=c.getExtension("keyUsage");b!==null&&(!b.keyCertSign||y===null)&&(a={message:"Certificate keyUsage or basicConstraints conflict or indicate that the certificate is not a CA. If the certificate is the only one in the chain or isn't the first then the certificate must be a valid CA.",error:n.certificateError.bad_certificate}),a===null&&y!==null&&!y.cA&&(a={message:"Certificate basicConstraints indicates the certificate is not a CA.",error:n.certificateError.bad_certificate})}var w=a===null?!0:a.error,E=i?i(w,f,s):w;if(E!==!0){w===!0&&(a={message:"The application rejected the certificate.",error:n.certificateError.bad_certificate});if(E||E===0)typeof E=="object"&&!e.util.isArray(E)?(E.message&&(a.message=E.message),E.error&&(a.error=E.error)):typeof E=="string"&&(a.error=E);throw a}a=null,u=!1,++f}while(r.length>0);return!0},n.publicKeyFromAsn1=function(r){var i={},u=[];if(t.validate(r,s,i,u)){var a=t.derToOid(i.publicKeyOid);if(a!==n.oids.rsaEncryption)throw{message:"Cannot read public key. Unknown OID.",oid:a};r=i.rsaPublicKey}u=[];if(!t.validate(r,o,i,u))throw{message:"Cannot read public key. ASN.1 object does not contain an RSAPublicKey.",errors:u};var f=e.util.createBuffer(i.publicKeyModulus).toHex(),l=e.util.createBuffer(i.publicKeyExponent).toHex();return n.setRsaPublicKey(new BigInteger(f,16),new BigInteger(l,16))},n.publicKeyToAsn1=n.publicKeyToSubjectPublicKeyInfo=function(e){return t.create(t.Class.UNIVERSAL,t.Type.SEQUENCE,!0,[t.create(t.Class.UNIVERSAL,t.Type.SEQUENCE,!0,[t.create(t.Class.UNIVERSAL,t.Type.OID,!1,t.oidToDer(n.oids.rsaEncryption).getBytes()),t.create(t.Class.UNIVERSAL,t.Type.NULL,!1,"")]),t.create(t.Class.UNIVERSAL,t.Type.BITSTRING,!1,[n.publicKeyToRSAPublicKey(e)])])},n.publicKeyToRSAPublicKey=function(e){return t.create(t.Class.UNIVERSAL,t.Type.SEQUENCE,!0,[t.create(t.Class.UNIVERSAL,t.Type.INTEGER,!1,y(e.n)),t.create(t.Class.UNIVERSAL,t.Type.INTEGER,!1,y(e.e))])},n.privateKeyFromAsn1=function(r){var i={},s=[];t.validate(r,a,i,s)&&(r=t.fromDer(e.util.createBuffer(i.privateKey))),i={},s=[];if(!t.validate(r,f,i,s))throw{message:"Cannot read private key. ASN.1 object does not contain an RSAPrivateKey.",errors:s};var o,u,l,c,h,p,d,v;return o=e.util.createBuffer(i.privateKeyModulus).toHex(),u=e.util.createBuffer(i.privateKeyPublicExponent).toHex(),l=e.util.createBuffer(i.privateKeyPrivateExponent).toHex(),c=e.util.createBuffer(i.privateKeyPrime1).toHex(),h=e.util.createBuffer(i.privateKeyPrime2).toHex(),p=e.util.createBuffer(i.privateKeyExponent1).toHex(),d=e.util.createBuffer(i.privateKeyExponent2).toHex(),v=e.util.createBuffer(i.privateKeyCoefficient).toHex(),n.setRsaPrivateKey(new BigInteger(o,16),new BigInteger(u,16),new BigInteger(l,16),new BigInteger(c,16),new BigInteger(h,16),new BigInteger(p,16),new BigInteger(d,16),new BigInteger(v,16))},n.privateKeyToAsn1=n.privateKeyToRSAPrivateKey=function(e){return t.create(t.Class.UNIVERSAL,t.Type.SEQUENCE,!0,[t.create(t.Class.UNIVERSAL,t.Type.INTEGER,!1,String.fromCharCode(0)),t.create(t.Class.UNIVERSAL,t.Type.INTEGER,!1,y(e.n)),t.create(t.Class.UNIVERSAL,t.Type.INTEGER,!1,y(e.e)),t.create(t.Class.UNIVERSAL,t.Type.INTEGER,!1,y(e.d)),t.create(t.Class.UNIVERSAL,t.Type.INTEGER,!1,y(e.p)),t.create(t.Class.UNIVERSAL,t.Type.INTEGER,!1,y(e.q)),t.create(t.Class.UNIVERSAL,t.Type.INTEGER,!1,y(e.dP)),t.create(t.Class.UNIVERSAL,t.Type.INTEGER,!1,y(e.dQ)),t.create(t.Class.UNIVERSAL,t.Type.INTEGER,!1,y(e.qInv))])},n.wrapRsaPrivateKey=function(e){return t.create(t.Class.UNIVERSAL,t.Type.SEQUENCE,!0,[t.create(t.Class.UNIVERSAL,t.Type.INTEGER,!1,"\0"),t.create(t.Class.UNIVERSAL,t.Type.SEQUENCE,!0,[t.create(t.Class.UNIVERSAL,t.Type.OID,!1,t.oidToDer(r.rsaEncryption).getBytes()),t.create(t.Class.UNIVERSAL,t.Type.NULL,!1,"")]),t.create(t.Class.UNIVERSAL,t.Type.OCTETSTRING,!1,t.toDer(e).getBytes())])},n.encryptPrivateKeyInfo=function(n,i,s){s=s||{},s.saltSize=s.saltSize||8,s.count=s.count||2048,s.algorithm=s.algorithm||"aes128";var o=e.random.getBytes(s.saltSize),u=s.count,a=e.util.createBuffer();a.putInt16(u);var f,l,c;if(s.algorithm.indexOf("aes")===0){var h;if(s.algorithm==="aes128")f=16,h=r["aes128-CBC"];else if(s.algorithm==="aes192")f=24,h=r["aes192-CBC"];else{if(s.algorithm!=="aes256")throw{message:"Cannot encrypt private key. Unknown encryption algorithm.",algorithm:s.algorithm};f=32,h=r["aes256-CBC"]}var p=e.pkcs5.pbkdf2(i,o,u,f),d=e.random.getBytes(16),v=e.aes.createEncryptionCipher(p);v.start(d),v.update(t.toDer(n)),v.finish(),c=v.output.getBytes(),l=t.create(t.Class.UNIVERSAL,t.Type.SEQUENCE,!0,[t.create(t.Class.UNIVERSAL,t.Type.OID,!1,t.oidToDer(r.pkcs5PBES2).getBytes()),t.create(t.Class.UNIVERSAL,t.Type.SEQUENCE,!0,[t.create(t.Class.UNIVERSAL,t.Type.SEQUENCE,!0,[t.create(t.Class.UNIVERSAL,t.Type.OID,!1,t.oidToDer(r.pkcs5PBKDF2).getBytes()),t.create(t.Class.UNIVERSAL,t.Type.SEQUENCE,!0,[t.create(t.Class.UNIVERSAL,t.Type.OCTETSTRING,!1,o),t.create(t.Class.UNIVERSAL,t.Type.INTEGER,!1,a.getBytes())])]),t.create(t.Class.UNIVERSAL,t.Type.SEQUENCE,!0,[t.create(t.Class.UNIVERSAL,t.Type.OID,!1,t.oidToDer(h).getBytes()),t.create(t.Class.UNIVERSAL,t.Type.OCTETSTRING,!1,d)])])])}else{if(s.algorithm!=="3des")throw{message:"Cannot encrypt private key. Unknown encryption algorithm.",algorithm:s.algorithm};f=24;var m=new e.util.ByteBuffer(o),p=e.pkcs12.generateKey(i,m,1,u,f),d=e.pkcs12.generateKey(i,m,2,u,f),v=e.des.createEncryptionCipher(p);v.start(d),v.update(t.toDer(n)),v.finish(),c=v.output.getBytes(),l=t.create(t.Class.UNIVERSAL,t.Type.SEQUENCE,!0,[t.create(t.Class.UNIVERSAL,t.Type.OID,!1,t.oidToDer(r["pbeWithSHAAnd3-KeyTripleDES-CBC"]).getBytes()),t.create(t.Class.UNIVERSAL,t.Type.SEQUENCE,!0,[t.create(t.Class.UNIVERSAL,t.Type.OCTETSTRING,!1,o),t.create(t.Class.UNIVERSAL,t.Type.INTEGER,!1,a.getBytes())])])}var g=t.create(t.Class.UNIVERSAL,t.Type.SEQUENCE,!0,[l,t.create(t.Class.UNIVERSAL,t.Type.OCTETSTRING,!1,c)]);return g},n.pbe.getCipherForPBES2=function(r,i,s){var o={},u=[];if(!t.validate(i,c,o,u))throw{message:"Cannot read password-based-encryption algorithm parameters. ASN.1 object is not a supported EncryptedPrivateKeyInfo.",errors:u};r=t.derToOid(o.kdfOid);if(r!==n.oids.pkcs5PBKDF2)throw{message:"Cannot read encrypted private key. Unsupported key derivation function OID.",oid:r,supportedOids:["pkcs5PBKDF2"]};r=t.derToOid(o.encOid);if(r!==n.oids["aes128-CBC"]&&r!==n.oids["aes192-CBC"]&&r!==n.oids["aes256-CBC"])throw{message:"Cannot read encrypted private key. Unsupported encryption scheme OID.",oid:r,supportedOids:["aes128-CBC","aes192-CBC","aes256-CBC"]};var a=o.kdfSalt,f=e.util.createBuffer(o.kdfIterationCount);f=f.getInt(f.length()<<3);var l;r===n.oids["aes128-CBC"]?l=16:r===n.oids["aes192-CBC"]?l=24:r===n.oids["aes256-CBC"]&&(l=32);var h=e.pkcs5.pbkdf2(s,a,f,l),p=o.encIv,d=e.aes.createDecryptionCipher(h);return d.start(p),d},n.pbe.getCipherForPKCS12PBE=function(r,i,s){var o={},u=[];if(!t.validate(i,h,o,u))throw{message:"Cannot read password-based-encryption algorithm parameters. ASN.1 object is not a supported EncryptedPrivateKeyInfo.",errors:u};var a=e.util.createBuffer(o.salt),f=e.util.createBuffer(o.iterations);f=f.getInt(f.length()<<3);var l,c,p;switch(r){case n.oids["pbeWithSHAAnd3-KeyTripleDES-CBC"]:l=24,c=8,p=e.des.startDecrypting;break;case n.oids["pbewithSHAAnd40BitRC2-CBC"]:l=5,c=8,p=function(t,n){var r=e.rc2.createDecryptionCipher(t,40);return r.start(n,null),r};break;default:throw{message:"Cannot read PKCS #12 PBE data block. Unsupported OID.",oid:r}}var d=e.pkcs12.generateKey(s,a,1,f,l),v=e.pkcs12.generateKey(s,a,2,f,c);return p(d,v)},n.pbe.getCipher=function(e,t,r){switch(e){case n.oids.pkcs5PBES2:return n.pbe.getCipherForPBES2(e,t,r);case n.oids["pbeWithSHAAnd3-KeyTripleDES-CBC"]:case n.oids["pbewithSHAAnd40BitRC2-CBC"]:return n.pbe.getCipherForPKCS12PBE(e,t,r);default:throw{message:"Cannot read encrypted PBE data block. Unsupported OID.",oid:e,supportedOids:["pkcs5PBES2","pbeWithSHAAnd3-KeyTripleDES-CBC","pbewithSHAAnd40BitRC2-CBC"]}}},n.decryptPrivateKeyInfo=function(r,i){var s=null,o={},u=[];if(!t.validate(r,l,o,u))throw{message:"Cannot read encrypted private key. ASN.1 object is not a supported EncryptedPrivateKeyInfo.",errors:u};var a=t.derToOid(o.encryptionOid),f=n.pbe.getCipher(a,o.encryptionParams,i),c=e.util.createBuffer(o.encryptedData);return f.update(c),f.finish()&&(s=t.fromDer(f.output)),s},n.encryptedPrivateKeyToPem=function(n,r){var i={type:"ENCRYPTED PRIVATE KEY",body:t.toDer(n).getBytes()};return e.pem.encode(i,{maxline:r})},n.encryptedPrivateKeyFromPem=function(n){var r=e.pem.decode(n)[0];if(r.type!=="ENCRYPTED PRIVATE KEY")throw{message:'Could not convert encrypted private key from PEM; PEM header type is "ENCRYPTED PRIVATE KEY".',headerType:r.type};if(r.procType&&r.procType.type==="ENCRYPTED")throw{message:"Could not convert encrypted private key from PEM; PEM is encrypted."};return t.fromDer(r.body)},n.encryptRsaPrivateKey=function(r,i,s){s=s||{};if(!s.legacy){var o=n.wrapRsaPrivateKey(n.privateKeyToAsn1(r));return o=n.encryptPrivateKeyInfo(o,i,s),n.encryptedPrivateKeyToPem(o)}var u,a,f,l;switch(s.algorithm){case"aes128":u="AES-128-CBC",f=16,a=e.random.getBytes(16),l=e.aes.createEncryptionCipher;break;case"aes192":u="AES-192-CBC",f=24,a=e.random.getBytes(16),l=e.aes.createEncryptionCipher;break;case"aes256":u="AES-256-CBC",f=32,a=e.random.getBytes(16),l=e.aes.createEncryptionCipher;break;case"3des":u="DES-EDE3-CBC",f=24,a=e.random.getBytes(8),l=e.des.createEncryptionCipher;break;default:throw{message:'Could not encrypt RSA private key; unsupported encryption algorithm "'+s.algorithm+'".',algorithm:s.algorithm}}var c=T(i,a.substr(0,8),f),h=l(c);h.start(a),h.update(t.toDer(n.privateKeyToAsn1(r))),h.finish();var p={type:"RSA PRIVATE KEY",procType:{version:"4",type:"ENCRYPTED"},dekInfo:{algorithm:u,parameters:e.util.bytesToHex(a).toUpperCase()},body:h.output.getBytes()};return e.pem.encode(p)},n.decryptRsaPrivateKey=function(r,i){var s=null,o=e.pem.decode(r)[0];if(o.type!=="ENCRYPTED PRIVATE KEY"&&o.type!=="PRIVATE KEY"&&o.type!=="RSA PRIVATE KEY")throw{message:'Could not convert private key from PEM; PEM header type is not "ENCRYPTED PRIVATE KEY", "PRIVATE KEY", or "RSA PRIVATE KEY".',headerType:o.type};if(o.procType&&o.procType.type==="ENCRYPTED"){var u,a;switch(o.dekInfo.algorithm){case"DES-EDE3-CBC":u=24,a=e.des.createDecryptionCipher;break;case"AES-128-CBC":u=16,a=e.aes.createDecryptionCipher;break;case"AES-192-CBC":u=24,a=e.aes.createDecryptionCipher;break;case"AES-256-CBC":u=32,a=e.aes.createDecryptionCipher;break;case"RC2-40-CBC":u=5,a=function(t){return e.rc2.createDecryptionCipher(t,40)};break;case"RC2-64-CBC":u=8,a=function(t){return e.rc2.createDecryptionCipher(t,64)};break;case"RC2-128-CBC":u=16,a=function(t){return e.rc2.createDecryptionCipher(t,128)};break;default:throw{message:'Could not decrypt private key; unsupported encryption algorithm "'+o.dekInfo.algorithm+'".',algorithm:o.dekInfo.algorithm}}var f=e.util.hexToBytes(o.dekInfo.parameters),l=T(i,f.substr(0,8),u),c=a(l);c.start(f),c.update(e.util.createBuffer(o.body));if(!c.finish())return s;s=c.output.getBytes()}else s=o.body;return o.type==="ENCRYPTED PRIVATE KEY"?s=n.decryptPrivateKeyInfo(t.fromDer(s),i):s=t.fromDer(s),s!==null&&(s=n.privateKeyFromAsn1(s)),s},n.setRsaPublicKey=n.rsa.setPublicKey,n.setRsaPrivateKey=n.rsa.setPrivateKey}var t="pki";if(typeof define!="function"){if(typeof module!="object"||!module.exports)return typeof forge=="undefined"&&(forge={}),e(forge);var n=!0;define=function(e,t){t(require,module)}}var r,i=function(n,i){i.exports=function(i){var s=r.map(function(e){return n(e)}).concat(e);i=i||{},i.defined=i.defined||{};if(i.defined[t])return i[t];i.defined[t]=!0;for(var o=0;o<s.length;++o)s[o](i);return i[t]}},s=define;define=function(e,t){return r=typeof e=="string"?t.slice(2):e.slice(2),n?(delete define,s.apply(null,Array.prototype.slice.call(arguments,0))):(define=s,define.apply(null,Array.prototype.slice.call(arguments,0)))},define("forge/pki",["require","module","./aes","./asn1","./des","./jsbn","./md","./mgf","./oids","./pem","./pbkdf2","./pkcs12","./pss","./random","./rc2","./rsa","./util"],function(){i.apply(null,Array.prototype.slice.call(arguments,0))})}(),function(){function e(e,t,n,r,i,s,o){var u={privateKey:"-----BEGIN RSA PRIVATE KEY-----\r\nMIICXQIBAAKBgQDL0EugUiNGMWscLAVM0VoMdhDZEJOqdsUMpx9U0YZI7szokJqQ\r\nNIwokiQ6EonNnWSMlIvy46AhnlRYn+ezeTeU7eMGTkP3VF29vXBo+dLq5e+8VyAy\r\nQ3FzM1wI4ts4hRACF8w6mqygXQ7i/SDu8/rXqRGtvnM+z0MYDdKo80efzwIDAQAB\r\nAoGAIzkGONi5G+JifmXlLJdplom486p3upf4Ce2/7mqfaG9MnkyPSairKD/JXvfh\r\nNNWkkN8DKKDKBcVVElPgORYT0qwrWc7ueLBMUCbRXb1ZyfEulimG0R3kjUh7NYau\r\nDaIkVgfykXGSQMZx8FoaT6L080zd+0emKDDYRrb+/kgJNJECQQDoUZoiC2K/DWNY\r\nh3/ppZ0ane2y4SBmJUHJVMPQ2CEgxsrJTxet668ckNCKaOP/3VFPoWC41f17DvKq\r\nnoYINNntAkEA4JbZBZBVUrQFhHlrpXT4jzqtO2RlKZzEq8qmFZfEErxOT1WMyyCi\r\nlAQ5gUKardo1Kf0omC8Xq/uO9ZYdED55KwJBALs6cJ65UFaq4oLJiQPzLd7yokuE\r\ndcj8g71PLBTW6jPxIiMFNA89nz3FU9wIVp+xbMNhSoMMKqIPVPC+m0Rn260CQQDA\r\nI83fWK/mZWUjBM33a68KumRiH238v8XyQxj7+C8i6D8G2GXvkigFAehAkb7LZZd+\r\nKLuGFyPlWv3fVWHf99KpAkBQFKk3MRMl6IGJZUEFQe4l5whm8LkGU4acSqv9B3xt\r\nqROkCrsFrMPqjuuzEmyHoQZ64r2PLJg7FOuyhBnQUOt4\r\n-----END RSA PRIVATE KEY-----\r\n",publicKey:"-----BEGIN PUBLIC KEY-----\r\nMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDL0EugUiNGMWscLAVM0VoMdhDZ\r\nEJOqdsUMpx9U0YZI7szokJqQNIwokiQ6EonNnWSMlIvy46AhnlRYn+ezeTeU7eMG\r\nTkP3VF29vXBo+dLq5e+8VyAyQ3FzM1wI4ts4hRACF8w6mqygXQ7i/SDu8/rXqRGt\r\nvnM+z0MYDdKo80efzwIDAQAB\r\n-----END PUBLIC KEY-----\r\n"},a="9200ece65cdaed36bcc20b94c65af852e4f88f0b4fe5b249d54665f815992ac43a1399e65d938c6a7f16dd39d971a53ca66523209dbbfbcb67afa579dbb0c220672813d9e6f4818f29b9becbb29da2032c5e422da97e0c39bfb7a2e7d568615a5073af0337ff215a8e1b2332d668691f4fb731440055420c24ac451dd3c913f4";describe("rsa",function(){it("should generate 512 bit key pair",function(){var i=n.generateKeyPair(512);e.equal(t.privateKeyToPem(i.privateKey).indexOf("-----BEGIN RSA PRIVATE KEY-----"),0),e.equal(t.publicKeyToPem(i.publicKey).indexOf("-----BEGIN PUBLIC KEY-----"),0);var s=r.sha1.create();s.update("0123456789abcdef");var o=i.privateKey.sign(s);e.ok(i.publicKey.verify(s.digest().getBytes(),o))}),it("should convert private key to/from PEM",function(){var n=t.privateKeyFromPem(u.privateKey);e.equal(t.privateKeyToPem(n),u.privateKey)}),it("should convert public key to/from PEM",function(){var n=t.publicKeyFromPem(u.publicKey);e.equal(t.publicKeyToPem(n),u.publicKey)}),function(){var n=["aes128","aes192","aes256","3des"];for(var r=0;r<n.length;++r){var i=n[r];it("should PKCS#8 encrypt and decrypt private key with "+i,function(){var n=t.privateKeyFromPem(u.privateKey),r=t.encryptRsaPrivateKey(n,"password",{algorithm:i}),n=t.decryptRsaPrivateKey(r,"password");e.equal(t.privateKeyToPem(n),u.privateKey)})}}(),function(){var n=["aes128","aes192","aes256","3des"];for(var r=0;r<n.length;++r){var i=n[r];it("should legacy (OpenSSL style) encrypt and decrypt private key with "+i,function(){var n=t.privateKeyFromPem(u.privateKey),r=t.encryptRsaPrivateKey(n,"password",{algorithm:i,legacy:!0}),n=t.decryptRsaPrivateKey(r,"password");e.equal(t.privateKeyToPem(n),u.privateKey)})}}(),it("should verify signature",function(){var n=t.publicKeyFromPem(u.publicKey),i=r.sha1.create();i.update("0123456789abcdef");var s=o.hexToBytes(a);e.ok(n.verify(i.digest().getBytes(),s))}),it("should sign and verify",function(){var n=t.privateKeyFromPem(u.privateKey),i=t.publicKeyFromPem(u.publicKey),s=r.sha1.create();s.update("0123456789abcdef");var o=n.sign(s);e.ok(i.verify(s.digest().getBytes(),o))}),function(){function a(n){var u=n.keySize;it("should rsa encrypt using a "+u+"-bit key",function(){var r="it need's to be about 20% cooler",i=t.publicKeyFromPem(n.publicKeyPem),s=i.encrypt(r);i=t.privateKeyFromPem(n.privateKeyPem),e.equal(i.decrypt(s),r)}),it("should rsa decrypt using a "+u+"-bit key",function(){var r=o.decode64(n.encrypted),i=t.privateKeyFromPem(n.privateKeyPem);e.equal(i.decrypt(r),"too many secrets\n")}),it("should rsa sign using a "+u+"-bit key and PKCS#1 v1.5 padding",function(){var i=t.privateKeyFromPem(n.privateKeyPem),s=r.sha1.create();s.start(),s.update("just testing");var u=o.decode64(n.signature);e.equal(i.sign(s),u)}),it("should verify an rsa signature using a "+u+"-bit key and PKCS#1 v1.5 padding",function(){var i=o.decode64(n.signature),s=t.publicKeyFromPem(n.publicKeyPem),u=r.sha1.create();u.start(),u.update("just testing"),e.equal(s.verify(u.digest().getBytes(),i),!0)}),it("should rsa sign using a "+u+"-bit key and PSS padding",function(){var o=t.privateKeyFromPem(n.privateKeyPem),u=t.publicKeyFromPem(n.publicKeyPem),a=r.sha1.create();a.start(),a.update("just testing");var f=s.create(r.sha1.create(),i.mgf1.create(r.sha1.create()),20),l=o.sign(a,f);a.start(),a.update("just testing"),e.equal(u.verify(a.digest().getBytes(),l,f),!0)}),it("should verify an rsa signature using a "+u+"-bit key and PSS padding",function(){var u=o.decode64(n.signaturePss),a=t.publicKeyFromPem(n.publicKeyPem),f=r.sha1.create();f.start(),f.update("just testing");var l=s.create(r.sha1.create(),i.mgf1.create(r.sha1.create()),20);e.equal(a.verify(f.digest().getBytes(),u,l),!0)})}var n=[{keySize:1024,privateKeyPem:"-----BEGIN RSA PRIVATE KEY-----\r\nMIICWwIBAAKBgQDCjvkkLWNTeYXqEsqGiVCW/pDt3/qAodNMHcU9gOU2rxeWwiRu\r\nOhhLqmMxXHLi0oP5Xmg0m7zdOiLMEyzzyRzdp21aqp3k5qtuSDkZcf1prsp1jpYm\r\n6z9EGpaSHb64BCuUsQGmUPKutd5RERKHGZXtiRuvvIyue7ETq6VjXrOUHQIDAQAB\r\nAoGAOKeBjTNaVRhyEnNeXkbmHNIMSfiK7aIx8VxJ71r1ZDMgX1oxWZe5M29uaxVM\r\nrxg2Lgt7tLYVDSa8s0hyMptBuBdy3TJUWruDx85uwCrWnMerCt/iKVBS22fv5vm0\r\nLEq/4gjgIVTZwgqbVxGsBlKcY2VzxAfYqYzU8EOZBeNhZdECQQDy+PJAPcUN2xOs\r\n6qy66S91x6y3vMjs900OeX4+bgT4VSVKmLpqRTPizzcL07tT4+Y+pAAOX6VstZvZ\r\n6iFDL5rPAkEAzP1+gaRczboKoJWKJt0uEMUmztcY9NXJFDmjVLqzKwKjcAoGgIal\r\nh+uBFT9VJ16QajC7KxTRLlarzmMvspItUwJAeUMNhEpPwm6ID1DADDi82wdgiALM\r\nNJfn+UVhYD8Ac//qsKQwxUDseFH6owh1AZVIIBMxg/rwUKUCt2tGVoW3uQJAIt6M\r\nAml/D8+xtxc45NuC1n9y1oRoTl1/Ut1rFyKbD5nnS0upR3uf9LruvjqDtaq0Thvz\r\n+qQT4RoFJ5pfprSO2QJAdMkfNWRqECfAhZyQuUrapeWU3eQ0wjvktIynCIwiBDd2\r\nMfjmVXzBJhMk6dtINt+vBEITVQEOdtyTgDt0y3n2Lw==\r\n-----END RSA PRIVATE KEY-----\r\n",publicKeyPem:"-----BEGIN PUBLIC KEY-----\r\nMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDCjvkkLWNTeYXqEsqGiVCW/pDt\r\n3/qAodNMHcU9gOU2rxeWwiRuOhhLqmMxXHLi0oP5Xmg0m7zdOiLMEyzzyRzdp21a\r\nqp3k5qtuSDkZcf1prsp1jpYm6z9EGpaSHb64BCuUsQGmUPKutd5RERKHGZXtiRuv\r\nvIyue7ETq6VjXrOUHQIDAQAB\r\n-----END PUBLIC KEY-----\r\n",encrypted:"jsej3OoacmJ1VjWrlw68F+drnQORAuKAqVu6RMbz1xSXjzA355vctrJZXolRU0mvzuu/6VuNynkKGGyRJ6DHt85CvwTMChw4tOMV4Dy6bgnUt3j+DZA2sWTwFhOlpzvNQMK70QpuqrXtOZmAO59EwoDeJkW/iH6t4YzNOVYo9Jg=",signature:"GT0/3EV2zrXxPd1ydijJq3R7lkI4c0GtcprgpG04dSECv/xyXtikuzivxv7XzUdHpu6QiYmM0xE4D4i7LK3Mzy+f7aB4o/dg8XXO3htLiBzVI+ZJCRh06RdYctPtclAWmyZikZ8Etw3NnA/ldKuG4jApbwRb21UFm5gYLrJ4SP4=",signaturePss:"F4xffaANDBjhFxeSJx8ANuBbdhaWZjUHRQh4ueYQMPPCaR2mpwdqxE04sbgNgIiZzBuLIAI4HpTMMoDk3Rruhjefx3+9UhzTxgB0hRI+KzRChRs+ToltWWDZdYzt9T8hfTlELeqT4V8HgjDuteO/IAvIVlRIBwMNv53Iebu1FY4="},{keySize:1025,privateKeyPem:"-----BEGIN RSA PRIVATE KEY-----\r\nMIICXgIBAAKBgQGIkej4PDlAigUh5fbbHp1WXuTHhOdQfAke+LoH0TM4uzn0QmgK\r\nSJqxzB1COJ5o0DwZw/NR+CNy7NUrly+vmh2YPwsaqN+AsYBF9qsF93oN8/TBtaL/\r\nGRoRGpDcCglkj1kZnDaWR79NsG8mC0TrvQCkcCLOP0c2Ux1hRbntOetGXwIDAQAB\r\nAoGBAIaJWsoX+ZcAthmT8jHOICXFh6pJBe0zVPzkSPz82Q0MPSRUzcsYbsuYJD7Z\r\noJBTLQW3feANpjhwqe2ydok7y//ONm3Th53Bcu8jLfoatg4KYxNFIwXEO10mPOld\r\nVuDIGrBkTABe6q2P5PeUKGCKLT6i/u/2OTXTrQiJbQ0gU8thAkEBjqcFivWMXo34\r\nCb9/EgfWCCtv9edRMexgvcFMysRsbHJHDK9JjRLobZltwtAv3cY7F3a/Cu1afg+g\r\njAzm5E3gowJBAPwYFHTLzaZToxFKNQztWrPsXF6YfqHpPUUIpT4UzL6DhGG0M00U\r\nqMyhkYRRqmGOSrSovjg2hjM2643MUUWxUxUCQDPkk/khu5L3YglKzyy2rmrD1MAq\r\ny0v3XCR3TBq89Ows+AizrJxbkLvrk/kfBowU6M5GG9o9SWFNgXWZnFittocCQQDT\r\ne1P1419DUFi1UX6NuLTlybx3sxBQvf0jY6xUF1jn3ib5XBXJbTJqcIRF78iyjI9J\r\nXWIugDc20bTsQOJRSAA9AkEBU8kpueHBaiXTikqqlK9wvc2Lp476hgyKVmVyBGye\r\n9TLTWkTCzDPtManLy47YtXkXnmyazS+DlKFU61XAGEnZfg==\r\n-----END RSA PRIVATE KEY-----\r\n",publicKeyPem:"-----BEGIN PUBLIC KEY-----\r\nMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQGIkej4PDlAigUh5fbbHp1WXuTH\r\nhOdQfAke+LoH0TM4uzn0QmgKSJqxzB1COJ5o0DwZw/NR+CNy7NUrly+vmh2YPwsa\r\nqN+AsYBF9qsF93oN8/TBtaL/GRoRGpDcCglkj1kZnDaWR79NsG8mC0TrvQCkcCLO\r\nP0c2Ux1hRbntOetGXwIDAQAB\r\n-----END PUBLIC KEY-----\r\n",encrypted:"AOVeCUN8BOVkZvt4mxyNn/yCYE1MZ40A3e/osh6EvCBcJ09hyYbx7bzKSrdkhRnDyW0pGtgP352CollasllQZ9HlfI2Wy9zKM0aYZZn8OHBA+60Tc3xHHDGznLZqggUKuhoNpj+faVZ1uzb285eTpQQa+4mLUue2svJD4ViM8+ng",signature:"AFSx0axDYXlF2rO3ofgUhYSI8ZlIWtJUUZ62PhgdBp9O5zFqMX3DXoiov1e7NenSOz1khvTSMctFWzKP3GU3F0yewe+Yd3UAZE0dM8vAxigSSfAchUkBDmp9OFuszUie63zwWwpG+gXtvyfueZs1RniBvW1ZmXJvS+HFgX4ouzwd",signaturePss:"AQvBdhAXDpu+7RpcybMgwuTUk6w+qa08Lcq3G1xHY4kC7ZUzauZd/Jn9e0ePKApDqs7eDNAOV+dQkU2wiH/uBg6VGelzb0hFwcpSLyBW92Vw0q3GlzY7myWn8qnNzasrt110zFflWQa1GiuzH/C8f+Z82/MzlWDxloJIYbq2PRC8"},{keySize:1031,privateKeyPem:"-----BEGIN RSA PRIVATE KEY-----\r\nMIICXwIBAAKBgWyeKqA2oA4klYrKT9hjjutYQksJNN0cxwaQwIm9AYiLxOsYtT/C\r\novJx5Oy1EvkbYQbfvYsGISUx9bW8yasZkTHR55IbW3+UptvQjTDtdxBQTgQOpsAh\r\nBJtZYY3OmyH9Sj3F3oB//oyriNoj0QYyfsvlO8UsMmLzpnf6qfZBDHA/9QIDAQAB\r\nAoGBBj/3ne5muUmbnTfU7lOUNrCGaADonMx6G0ObAJHyk6PPOePbEgcmDyNEk+Y7\r\naEAODjIzmttIbvZ39/Qb+o9nDmCSZC9VxiYPP+rjOzPglCDT5ks2Xcjwzd3If6Ya\r\nUw6P31Y760OCYeTb4Ib+8zz5q51CkjkdX5Hq/Yu+lZn0Vx7BAkENo83VfL+bwxTm\r\nV7vR6gXqTD5IuuIGHL3uTmMNNURAP6FQDHu//duipys83iMChcOeXtboE16qYrO0\r\n9KC0cqL4JQJBB/aYo/auVUGZA6f50YBp0b2slGMk9TBQG0iQefuuSyH4kzKnt2e3\r\nQ40SBmprcM+DfttWJ11bouec++goXjz+95ECQQyiTWYRxulgKVuyqCYnvpLnTEnR\r\n0MoYlVTHBriVPkLErYaYCYgse+SNM1+N4p/Thv6KmkUcq/Lmuc5DSRfbl1iBAkEE\r\n7GKtJQvd7EO1bfpXnARQx+tWhwHHkgpFBBVHReMZ0rQEFhJ5o2c8HZEiZFNvGO2c\r\n1fErP14zlu2JFZ03vpCI8QJBCQz9HL28VNjafSAF2mon/SNjKablRjoGGKSoSdyA\r\nDHDZ/LeRsTp2dg8+bSiG1R+vPqw0f/BT+ux295Sy9ocGEM8=\r\n-----END RSA PRIVATE KEY-----\r\n",publicKeyPem:"-----BEGIN PUBLIC KEY-----\r\nMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgWyeKqA2oA4klYrKT9hjjutYQksJ\r\nNN0cxwaQwIm9AYiLxOsYtT/CovJx5Oy1EvkbYQbfvYsGISUx9bW8yasZkTHR55Ib\r\nW3+UptvQjTDtdxBQTgQOpsAhBJtZYY3OmyH9Sj3F3oB//oyriNoj0QYyfsvlO8Us\r\nMmLzpnf6qfZBDHA/9QIDAQAB\r\n-----END PUBLIC KEY-----\r\n",encrypted:"ShSS4/fEAkuS6XiQakhOpWp82IXaaCaDNtsndU4uokvriqgCGZyqc+IkIk3eVmZ8bn4vVIRR43ydFuvGgsptVjizOdLGZudph3TJ1clcYEMcCXk4z5HaEu0bx5SW9jmzHhE/z+WV8PB48q7y7C2qtmPmfttG2NMsNLBvkiaDopRO",signature:"Z3vYgRdezrWmdA3NC1Uz2CcHRTcE+/C2idGZA1FjUGqFztAHQ31k0QW/F5zuJdKvg8LQU45S3KxW+OQpbGPL98QbzJLhml88mFGe6OinLXJbi7UQWrtXwamc2jMdiXwovSLbXaXy6PX2QW089iC8XuAZftVi3T/IKV0458FQQprg",signaturePss:"R6QsK6b3QinIPZPamm/dP0Zndqti1TzAkFTRSZJaRSa1u2zuvZC5QHF4flDjEtHosWeDyxrBE7PHGQZ0b1bHv9qgHGsJCMwaQPj3AWj9fjYmx7b86KM2vHr8q/vqDaa9pTvVRSSwvD6fwoZPc9twQEfdjdDBAiy23yLDzk/zZiwM"},{keySize:1032,privateKeyPem:"-----BEGIN RSA PRIVATE KEY-----\r\nMIICYQIBAAKBggDPhzn5I3GecxWt5DKbP+VhM2AFNSOL0+VbYEOR1hnlZdLbxGK4\r\ncPQzMr2qT6dyttJcsgWr3xKobPkz7vsTZzQATSiekm5Js5dGpaj5lrq/x2+WTZvn\r\n55x9M5Y5dlpusDMKcC3KaIX/axc+MbvPFzo6Eli7JLCWdBg01eKo30knil0CAwEA\r\nAQKBggCNl/sjFF7SOD1jbt5kdL0hi7cI9o+xOLs1lEGmAEmc7dNnZN/ibhb/06/6\r\nwuxB5aEz47bg5IvLZMbG+1hNjc26D0J6Y3Ltwrg8f4ZMdDrh4v0DZ8hy/HbEpMrJ\r\nTd5dk3mtw9FLow10MB5udPLTDKhfDpTcWiObKm2STtFeBk3xeEECQQ6Cx6bZxQJ1\r\nzCxflV5Xi8BgAQaUKMqygugte+HpOLflL0j1fuZ0rPosUyDOEFkTzOsPxBYYOU8i\r\nGzan1GvW3WwRAkEOTTRt849wpgC9xx2pF0IrYEVmv5gEMy3IiRfCNgEoBwpTWVf4\r\nQFpN3V/9GFz0WQEEYo6OTmkNcC3Of5zbHhu1jQJBBGxXAYQ2KnbP4uLL/DMBdYWO\r\nKnw1JvxdLPrYXVejI2MoE7xJj2QXajbirAhEMXL4rtpicj22EmoaE4H7HVgkrJEC\r\nQQq2V5w4AGwvW4TLHXNnYX/eB33z6ujScOuxjGNDUlBqHZja5iKkCUAjnl+UnSPF\r\nexaOwBrlrpiLOzRer94MylKNAkEBmI58bqfkI5OCGDArAsJ0Ih58V0l1UW35C1SX\r\n4yDoXSM5A/xQu2BJbXO4jPe3PnDvCVCEyKpbCK6bWbe26Y7zuw==\r\n-----END RSA PRIVATE KEY-----\r\n",publicKeyPem:"-----BEGIN PUBLIC KEY-----\r\nMIGgMA0GCSqGSIb3DQEBAQUAA4GOADCBigKBggDPhzn5I3GecxWt5DKbP+VhM2AF\r\nNSOL0+VbYEOR1hnlZdLbxGK4cPQzMr2qT6dyttJcsgWr3xKobPkz7vsTZzQATSie\r\nkm5Js5dGpaj5lrq/x2+WTZvn55x9M5Y5dlpusDMKcC3KaIX/axc+MbvPFzo6Eli7\r\nJLCWdBg01eKo30knil0CAwEAAQ==\r\n-----END PUBLIC KEY-----\r\n",encrypted:"pKTbv+xgXPDc+wbjsANFu1/WTcmy4aZFKXKnxddHbU5S0Dpdj2OqCACiBwu1oENPMgPAJ27XRbFtKG+eS8tX47mKP2Fo0Bi+BPFtzuQ1bj3zUzTwzjemT+PU+a4Tho/eKjPhm6xrwGAoQH2VEDEpvcYf+SRmGFJpJ/zPUrSxgffj",signature:"R9WBFprCfcIC4zY9SmBpEM0E+cr5j4gMn3Ido5mktoR9VBoJqC6eR6lubIPvZZUz9e4yUSYX0squ56Q9Y0yZFQjTHgsrlmhB2YW8kpv4h8P32Oz2TLcMJK9R2tIh9vvyxwBkd/Ml1qG60GnOFUFzxUad9VIlzaF1PFR6EfnkgBUW",signaturePss:"v9UBd4XzBxSRz8yhWKjUkFpBX4Fr2G+ImjqbePL4sAZvYw1tWL+aUQpzG8eOyMxxE703VDh9nIZULYI/uIb9HYHQoGYQ3WoUaWqtZg1x8pZP+Ad7ilUWk5ImRl57fTznNQiVdwlkS5Wgheh1yJCES570a4eujiK9OyB0ba4rKIcM"}];for(var u=0;u<n.length;++u)a(n[u]);it("should ensure maximum message length for a 1024-bit key is exceeded",function(){var r=t.publicKeyFromPem(n[0].publicKeyPem),i=o.createBuffer().fillWithByte(0,118);e.throws(function(){r.encrypt(i.getBytes())})}),it("should ensure maximum message length for a 1025-bit key is not exceeded",function(){var r=t.publicKeyFromPem(n[1].publicKeyPem),i=o.createBuffer().fillWithByte(0,118);e.doesNotThrow(function(){r.encrypt(i.getBytes())})})}()})}typeof define=="function"?define("test/rsa",["forge/pki","forge/rsa","forge/md","forge/mgf","forge/pss","forge/util"],function(t,n,r,i,s,o){e(ASSERT,t(),n(),r(),i(),s(),o())}):typeof module=="object"&&module.exports&&e(require("assert"),require("../../js/pki")(),require("../../js/rsa")(),require("../../js/md")(),require("../../js/mgf")(),require("../../js/pss")(),require("../../js/util")())}(),function(){function e(e,t,n,r,i){describe("pkcs1",function(){function s(){var e,t,n,r,i,s,o,u,a,l,p;e="qLOyhK+OtQs4cDSoYPFGxJGfMYdjzWxVmMiuSBGh4KvEx+CwgtaTpef87Wdc9GaFEncsDLxkp0LGxjD1M8jMcvYq6DPEC/JYQumEu3i9v5fAEH1VvbZi9cTg+rmEXLUUjvc5LdOq/5OuHmtme7PUJHYW1PW6ENTP0ibeiNOfFvs=",t="AQAB",n="UzOc/befyEZqZVxzFqyoXFX9j23YmP2vEZUX709S6P2OJY35P+4YD6DkqylpPNg7FSpVPUrE0YEri5+lrw5/Vf5zBN9BVwkm8zEfFcTWWnMsSDEW7j09LQrzVJrZv3y/t4rYhPhNW+sEck3HNpsx3vN9DPU56c/N095lNynq1dE=",r="0yc35yZ//hNBstXA0VCoG1hvsxMr7S+NUmKGSpy58wrzi+RIWY1BOhcu+4AsIazxwRxSDC8mpHHcrSEurHyjnQ==",i="zIhT0dVNpjD6wAT0cfKBx7iYLYIkpJDtvrM9Pj1cyTxHZXA9HdeRZC8fEWoN2FK+JBmyr3K/6aAw6GCwKItddw==",s="DhK/FxjpzvVZm6HDiC/oBGqQh07vzo8szCDk8nQfsKM6OEiuyckwX77L0tdoGZZ9RnGsxkMeQDeWjbN4eOaVwQ==",o="lSl7D5Wi+mfQBwfWCd/U/AXIna/C721upVvsdx6jM3NNklHnkILs2oZu/vE8RZ4aYxOGt+NUyJn18RLKhdcVgw==",u="T0VsUCSTvcDtKrdWo6btTWc1Kml9QhbpMhKxJ6Y9VBHOb6mNXb79cyY+NygUJ0OBgWbtfdY2h90qjKHS9PvY4Q==",a=c(e,t),l=h(e,t,n,r,i,s,o,u),p=[{title:"RSAES-OAEP Encryption Example 1.1",message:"ZigZThIHPbA7qUzanvlTI5fVDbp5uYcASv7+NA==",seed:"GLd26iEGnWl3ajPpa61I4d2gpe8=",encrypted:"NU/me0oSbV01/jbHd3kaP3uhPe9ITi05CK/3IvrUaPshaW3pXQvpEcLTF0+K/MIBA197bY5pQC3lRRYYwhpTX6nXv8W43Z/CQ/jPkn2zEyLW6IHqqRqZYXDmV6BaJmQm2YyIAD+Ed8EicJSg2foejEAkMJzh7My1IQA11HrHLoo="},{title:"RSAES-OAEP Encryption Example 1.2",message:"dQxAR/VH6OQUEYVlIymKybriRe+vE5f75W+d1Q==",seed:"DMdCzkqbfzL5UbyyUe/ZJf5P418=",encrypted:"ZA2xrMWOBWj+VAfl+bcB3/jDyR5xbFNvx/zsbLW3HBFlmI1KJ54Vd9cw/Hopky4/AMgVFSNtjY4xAXp6Cd9DUtkEzet5qlg63MMeppikwFKD2rqQib5UkfZ8Gk7kjcdLu+ZkOu+EZnm0yzlaNS1e0RWRLfaW/+BwKTKUbXFJK0Q="},{title:"RSAES-OAEP Encryption Example 1.3",message:"2Urggy5kRc5CMxywbVMagrHbS6rTD3RtyRbfJNTjwkUf/1mmQj6w4dAtT+ZGz2md/YGMbpewUQ==",seed:"JRTfRpV1WmeyiOr0kFw27sZv0v0=",encrypted:"Qjc27QNfYCavJ2w1wLN0GzZeX3bKCRtOjCni8L7+5gNZWqgyLWAtLmJeleuBsvHJck6CLsp224YYzwnFNDUDpDYINbWQO8Y344efsF4O8yaF1a7FBnzXzJb+SyZwturDBmsfz1aGtoWJqvt9YpsC2PhiXKODNiTUgA+wgbHPlOs="},{title:"RSAES-OAEP Encryption Example 1.4",message:"UuZQ2Y5/KgSLT4aFIVO5fgHdMW80ahn2eoU=",seed:"xENaPhoYpotoIENikKN877hds/s=",encrypted:"RerUylUeZiyYAPGsqCg7BSXmq64wvktKunYvpA/T044iq+/Gl5T267vAXduxEhYkfS9BL9D7qHxuOs2IiBNkb9DkjnhSBPnD9z1tgjlWJyLd3Ydx/sSLg6Me5vWSxM/UvIgXTzsToRKq47n3uA4PxvclW6iA3H2AIeIq1qhfB1U="},{title:"RSAES-OAEP Encryption Example 1.5",message:"jaif2eX5dKKf7/tGK0kYD2z56AI=",seed:"sxjELfO+D4P+qCP1p7R+1eQlo7U=",encrypted:"NvbjTZSo002qy6M6ITnQCthak0WoYFHnMHFiAFa5IOIZAFhVohOg8jiXzc1zG0UlfHd/6QggK+/dC1g4axJE6gz1OaBdXRAynaROEwMP12Dc1kTP7yCU0ZENP0M+HHxt0YvB8t9/ZD1mL7ndN+rZBZGQ9PpmyjnoacTrRJy9xDk="},{title:"RSAES-OAEP Encryption Example 1.6",message:"JlIQUIRCcQ==",seed:"5OwJgsIzbzpnf2o1YXTrDOiHq8I=",encrypted:"Qs7iYXsezqTbP0gpOG+9Ydr78DjhgNg3yWNm3yTAl7SrD6xr31kNghyfEGQuaBrQW414s3jA9Gzi+tY/dOCtPfBrB11+tfVjb41AO5BZynYbXGK7UqpFAC6nC6rOCN7SQ7nYy9YqaK3iZYMrVlZOQ6b6Qu0ZmgmXaXQt8VOeglU="}],f(a,l,"sha1",p),e="AZR8f86QQl9HJ55whR8l1eYjFv6KHfGTcePmKOJgVD5JAe9ggfaMC4FBGQ0q6Nq6fRJQ7G22NulE7Dcih3x8HQpn8UsWlMXwN5RRpD5Joy3eg2cLc9qRocmbwjtDamAFXGEPC6+ZwaB5VluVo/FSZjLR1Npg8g7aJeZTxPACdm9F",t="AQAB",n="CCPyD6212okIip0AiT4h+kobEfvJPGSjvguq6pf7O5PD/3E3BMGcljwdEHqumQVHOfeeAuGG3ob4em3e/qbYzNHTyBpHv6clW+IGAaSksvCKFnteJ51xWxtFW91+qyRZQdl2i5rO+zzNpZUto87nJSW0UBZjqO4VyemS2SRi/jk=",r="AVnb3gSjPvBvtgi4CxkPTT4ivME6yOSggQM6v6QW7bCzOKoItXMJ6lpSQOfcblQ3jGlBTDHZfdsfQG2zdpzEGkM=",i="AStlLzBAOzi0CZX9b/QaGsyK2nA3Mja3IC05su4wz7RtsJUR9vMHzGHMIWBsGKdbimL4It8DG6DfDa/VUG9Wi9c=",s="Q271CN5zZRnC2kxYDZjILLdFKj+1763Ducd4mhvGWE95Wt270yQ5x0aGVS7LbCwwek069/U57sFXJIx7MfGiVQ==",o="ASsVqJ89+ys5Bz5z8CvdDBp7N53UNfBc3eLv+eRilIt87GLukFDV4IFuB4WoVrSRCNy3XzaDh00cpjKaGQEwZv8=",u="AnDbF9WRSwGNdhGLJDiac1Dsg2sAY6IXISNv2O222JtR5+64e2EbcTLLfqc1bCMVHB53UVB8eG2e4XlBcKjI6A==",a=c(e,t),l=h(e,t,n,r,i,s,o,u),p=[{title:"RSAES-OAEP Encryption Example 2.1",message:"j/AMqmBccCgwY02abD1CxlK1jPHZL+xXC+7n",seed:"jEB7XsKJnlCZxT6M55O/lOcbF4I=",encrypted:"AYGviSK5/LTXnZLr4ZgVmS/AwUOdi81JE5ig9K06Mppb2ThVYNtTJoPIt9oE5LEq7Wqs30ccNMnNqJGt3MLfNFZlOqY4Lprlm1RFUlfrCZ1WK74QRT8rbRPFnALhDx+Ku12g0FcJMtrPLQkB23KdD+/MBU5wlo6lQMgbBLyu/nIO"},{title:"RSAES-OAEP Encryption Example 2.2",message:"LQ==",seed:"tgDPPC5QbX8Wd4yRDTqLAD7uYdU=",encrypted:"AYdZ/x32OyeSQQViMUQWqK6vKsY0tG+UCrgtZNvxZe7jMBHadJ1Lq24vzRgSnJ5JJ32EUxErQpoiKoRxsHCZOZjnWIYcTT9tdJ2RxCkNMyx6SrP36jX/OgfUl8lV/w/8lQBrYsbSloENm/qwJBlseTQBLC35eO8pmrojmUDLoQJF"},{title:"RSAES-OAEP Encryption Example 2.3",message:"dPyIxRvJD3evnV6aSnATPUtOCzTaPDfH744=",seed:"pzdoruqpH52MHtb50rY0Z/B8yuM=",encrypted:"AYgCurBMYDJegcSWIxHyvnwq3OkwQaAHGciPlXV18sefG3vIztEVxwazEcCKLZhso7apM2sUfCnG8ilAnd7GUb0f3VoLf2EMmTf9tKOnYjZLizIGtOpIX9CY0I9j1KqLsml9Ant1DDLX906vUYDS6bZrF8svpVUjvCgNoQ0UviBT"},{title:"RSAES-OAEP Encryption Example 2.4",message:"p+sqUDaTHSfU6JEybZlpL/rdqb9+/T405iLErcCF9yHf6IUHLHiiA7FRc5vlQPqMFToQ8Ao=",seed:"mns7DnCL2W+BkOyrT7mys4BagVY=",encrypted:"AKRXjLwXYximOPun0B3xV0avRNT2zZbX58SVy/QlsJxknTK/iG2kj7r5iaIRcYfK+x+1gDF2kOPM1EaSC3r4KzHbWATYfQFRSsv6kVbngvhn9r7ZRJ4OmiwJvOzGqgh2NpZeNLPsdm8v4uQwGKL93rFAYWoOnYLlMxAk7gZS/HZB"},{title:"RSAES-OAEP Encryption Example 2.5",message:"LvKwZvhUwz873LtZlKQ15z1sbA==",seed:"6zzrvErcFrtI6IyK7A40r39Cf9M=",encrypted:"AOvF9f2nfP2tPINkGpAl531y2Kb7M6gQ9ZUPjXTHPo2THoY02GqxJGJWrge2AFtxt/L7mDUSGDMc5puP+9ydoIu8nHBPh23rnfn8LsBlyth/kJCweswXqn+ZeyespIgG6Jf3cdlRQf5FJtilMBtnhifvq3B/1A++vW55KiVhPnrs"},{title:"RSAES-OAEP Encryption Example 2.6",message:"in+zRMi2yyzy7x9kP5oyGPbhm7qJwA==",seed:"TEXPTVfJjj1tIJWtxRxInrUN/4Q=",encrypted:"AQg57CDCe5BS5Vvvubd+b8JukHXXpUN4xkar31HkRb1XFd6BeJ9W8YA9kXB2Sp6Ty3h5hpQCPuc5POBLxdj4xaUsFx1Dg346ymL2CesKpf+wlg7wQZjddU9X9/vmq/dlzxGLTKRDsjtaqyZvlSMmrEWBEAZEMl+LchrNXQT/FO86"}],f(a,l,"sha1",p),e="ArWP7AOahgcApNe2Ri+T5s3UkRYd3XT06BC0DjwWUgBqXCd7J3TBEwWky6taeO+lfheobfej+jb8Sx0iSfIux8LdakYyMqzOqQbWbr6AtXBLEHKdpvgzI0q7Xv3UopLL+tM7TTP6ehS4w5e1bjrNISA0KLd836M6bacGs9iw/EPp",t="AQAB",n="FbSKW1aDqUZw4jtXGPgU+g4T+FA49QcRGCy6YVEFgfPSLH4jLvk34i5VHWi4bi+MsarYvi5Ij13379J54/Vo1Orzb4DPcUGs5g/MkRP7bEqEH9ULvHxRL/y+/yFIeqgR6zyoxiAFNGqG3oa/odipSP0/NIwi6q3zM8PObOEyCP0=",r="Ab8B0hbXNZXPAnDCvreNQKDYRH0x2pGamD9+6ngbd9hf43Gz6Tc+e2khfTFQoC2JWN5/rZ1VUWCVi0RUEn4Ofq8=",i="AY0zmWWBZts4KYFteylUFnWenJGYf1stiuzWOwS0i9ey/PIpu3+KbciLoT3S45rVW20aBhYHCPlwC+gLj9N0TOc=",s="BsCiSdIKby7nXIi0lNU/aq6ZqkJ8iMKLFjp2lEXl85DPQMJ0/W6mMppc58fOA6IVg5buKnhFeG4J4ohalyjk5Q==",o="0dJ8Kf7dkthsNI7dDMv6wU90bgUc4dGBHfNdYfLuHJfUvygEgC9kJxh7qOkKivRCQ7QHmwNEXmAuKfpRk+ZP6Q==",u="jLL3Vr2JQbHTt3DlrTHuNzsorNpp/5tvQP5Xi58a+4WDb5Yn03rP9zwneeY0uyYBHCyPfzNhriqepl7WieNjmg==",a=c(e,t),l=h(e,t,n,r,i,s,o,u),p=[{title:"RSAES-OAEP Encryption Example 3.1",message:"CHggtWno+o0=",seed:"jO1rGWKQgFeQ6QkHQBXmogsMSJQ=",encrypted:"AmoEhdlq69lrQ4IIUJm5Yuaivew9kMjbYl4UNy3oXi1be6q2XI+vkbtVBPtJWvzlyYiz9qUuIOHWy9NWbFzR8rgxi7VCzA6iXEqrmTKvogdg6t3seEOWoH6g7yTU5vTTflBSp6MeFGqkgKERu+kmQBMH4A9BADOEK22C/lzk366A"},{title:"RSAES-OAEP Encryption Example 3.2",message:"RlOsrxcZYLAfUqe+Y6OrIdw2jsQ7UNguw3geBA==",seed:"tCkdZWdVCEjMFWlnyAm6q2ylB/A=",encrypted:"Ak24nHgCmJvgeDhHhjCElBvyCddhmH44+Xy19vG8iNpypQtz668RyHnE+V3ze4ULj2XXYi4lsbiJ6A/oC6yiBp1uDh2CmVP8RZBp3pjql5i0UeVX6Zq/j+PZzPkJbrvz5SVdO04cbS7K3wZ6NZ7qhkBazUfV4WVRfMr9R9bb7kv1"},{title:"RSAES-OAEP Encryption Example 3.3",message:"2UzQ4I+kBO2J",seed:"zoko9gWVWCVACLrdl5T63NL9H2U=",encrypted:"Ajm85oEDJEFSiHfW0ci7KKo7yX8d9YRWNhiZV5doOETKhmZHMvS+16CqsIOqq/tyOPWC4wlYwgJOROVwQ7l5UP1UPal3yQzd5TN9YYRC+Z5g13g6tZzm3Z1pxHrR6WK+wi0FiVz/jT9k7VJh2SsmeFEDk0hJkLo/fwaBiub/zoo6"},{title:"RSAES-OAEP Encryption Example 3.4",message:"bMZBtrYeb5Y5dNrSOpATKE7x",seed:"bil59S1oFKV9g7CQBUiI8RmluaM=",encrypted:"AplMYq/Xb0mLof0s9kKFf8qB9Dc8sI8cuu5vAlw7UStCw+h3kRNHZkgDnb4Ek/kkYpL6wolQYA58DzLt+cgbnexFw73gzI2IR1kBaZB7fcWZHOspuwcU1hPZbfDxLsXY01B8jueueN2D8hb6Yd4QA2OspIp+kUrp9C3fvpQ7Cdmg"},{title:"RSAES-OAEP Encryption Example 3.5",message:"31FRgyth9PJYkftBcvMo0u3fg3H/z9vpl5OSlfMOymkYAXz9oRU796avh1kyIw==",seed:"LXYL/jjFneNM3IuMeKOOZihKLSc=",encrypted:"AWIEL/aWlZKmFnAxgRojmDTOY4q/VP7IuZR4Eir+LuZ/jFsYsDOYBb/bxaTmcgs3xZz7qUJGTFl/9TKhGYIVRf0uWbEU5h2vcYIFKfUCnPUklUMnw07F5vW6fvzE3pQ6uK1O14exRUMp9w23mKOo9NkvgnTispSK3mJ86O4z5Dxg"},{title:"RSAES-OAEP Encryption Example 3.6",message:"PDutiTxUSm1SCrAiMZGIyNUEt6eIuFCQO4WXLqoYVS4RNKetYJiCYlT/erZys9jrMVj6xtTLrvE=",seed:"8XR3nF/Tz+AHuty3o2ybVb/Pvw4=",encrypted:"ABEgUeddBklDvER4B15DSC/VnO4Ged5ok+7DqUPapJC5aRyT38BGS2YjufPb0+cAgyZPA0s3T3QWThoAdjcl5XR0S6C524NDTzHflvbiom9tjro0i9RobCI4rAfDeqw3hdHH7qL4Gf2RSReY7Y6c715Dt4Gw4CduN8Q/+UktAFcw"}],f(a,l,"sha1",p),e="BRJAtswABPpI0BNGccB4x8jew7Pi8lvCVkRnM52ziFPQa4XupbLeNTv/QqwuRryX+uaslhjalTelyPVTweNXYlmR1hCNzXiF+zolQT9T78rZSMs1zZua6cHGdibRE9V93kxb6na7W7felsANBzculoWm11z50jn6FI1wkxtfP7A5",t="AQAB",n="BBH/yjt8penpvn/jioUQXjU4ltsFxXlq7NKnJRYes2UchimpuGK5BNewx7N/jLWhwrVAAQGKAKHrLK/k7k6UksNIvCvtq0ueu/Bk6O/zIrkAn47sZTkF9A34ijzcSdRWf3VifUGspiQSm0agt8aY5eZfK3uhAsdJoQE1tlQNBAE=",r="AnRYwZ7BY2kZ5zbJryXWCaUbj1YdGca/aUPdHuGriko/IyEAvUC4jezGuiNVSLbveSoRyd6CPQp5IscJW266VwE=",i="AhDumzOrYXFuJ9JRvUZfSzWhojLi2gCQHClL8iNQzkkNCZ9kK1N1YS22O6HyA4ZJK/BNNLPCK865CdE0QbU7UTk=",s="OfoCi4JuiMESG3UKiyQvqaNcW2a9/R+mN9PMSKhKT0V6GU53J+Sfe8xuWlpBJlf8RwxzIuvDdBbvRYwweowJAQ==",o="AV2ZqEGVlDl5+p4b4sPBtp9DL0b9A+R9W++7v9ax0Tcdg++zMKPgIJQrL+0RXl0CviT9kskBnRzs1t1M8eVMyJk=",u="AfC3AVFws/XkIiO6MDAcQabYfLtw4wy308Z9JUc9sfbL8D4/kSbj6XloJ5qGWywrQmUkz8UqaD0x7TDrmEvkEro=",a=c(e,t),l=h(e,t,n,r,i,s,o,u),p=[{title:"RSAES-OAEP Encryption Example 4.1",message:"SoZglTTuQ0psvKP36WLnbUVeMmTBn2Bfbl/2E3xlxW1/s0TNUryTN089FmyfDG+cUGutGTMJctI=",seed:"HKwZzpk971X5ggP2hSiWyVzMofM=",encrypted:"BMzhlhSEXglBUqP+GOVOMzDETl77xkrhaIbLGGkBTMV4Gx+PngRThNARKhNcoNEunIio5AY0Ft6q44RPYNbpb+FVFF9FJbmjRDHKN2YYD3DhWl5djosaUW/4cGCfE/iWk1ztGIJ5pY7RPQcRQnfXXGVoYH4KsJL9gDoiPkqO4LGo"},{title:"RSAES-OAEP Encryption Example 4.2",message:"sK3E8/4R2lnOmSdz2QWZQ8AwRkl+6dn5oG3xFm20bZj1jSfsB0wC7ubL4kSci5/FCAxcP0QzCSUS7EaqeTdDyA==",seed:"9UXViXWF49txqgy42nbFHQMq6WM=",encrypted:"AJe2mMYWVkWzA0hvv1oqRHnA7oWIm1QabwuFjWtll7E7hU60+DmvAzmagNeb2mV4yEH5DWRXFbKA03FDmS3RhsgLlJt3XK6XNw5OyXRDE2xtpITpcP/bEyOiCEeCHTsYOB3hO7SarqZlMMSkuCcfPq4XLNNm4H5mNvEBnSoortFe"},{title:"RSAES-OAEP Encryption Example 4.3",message:"v21C5wFwex0CBrDItFoccmQf8SiJIZqCveqWW155qWsNAWPtnVeOya2iDy+88eo8QInYNBm6gbDGDzYG2pk=",seed:"rZl/7vcw1up75g0NxS5y6sv90nU=",encrypted:"AwH5NenEery0isu+CYldn1lxrxSDnaT/lUF+5FPR/XcxkHK7cpfhtV11Yc2dG7JMGpo3xhmGQwgkKASHnYbr0AHc5Rg5deFQaYm3DlqDQ0FU1cv9aiR4fmDrDGWNKsGTMC0RksbmItShKtS1OSO8okbfMcY5XjdwLGp4rggfudBl"},{title:"RSAES-OAEP Encryption Example 4.4",message:"+y7xEvXnZuuUAZKXk0eU974vb8HFjg==",seed:"E2RU31cw9zyAen5A2MGjEqxbndM=",encrypted:"AtEQrTCvtye+tpHdDPF9CvGh5/oMwEDsGkuiakLFnQp5ai4iyPNXzMmLZRms62gulF5iy3NGFKUpQHzUUr7j5E/s6EI8wZ5VVIuLmUuEnH7N5JM+dgN+HQzkQnWwhxDGjkMBMLkpcw7XfgmwFWQsVZPwTk/7lBB5gQKo6W/9/hHk"},{title:"RSAES-OAEP Encryption Example 4.5",message:"KMzUR7uehRZtq7nlt9GtrcS5058gTpbV5EDOmtkovBwihA==",seed:"vKgFf4JLLqJX8oYUB+72PTMghoE=",encrypted:"ANu4p0OdkO/ZGaN3xU+uj+EexYw7hYNi4jrRuKRDEHmQZrmTR6pSVpHSrcWNmwbjTyiMFwOQxfDhHAqjZFlZ8Y7nno8r6NesXCPQYfGN10uMXypY/LXrDFT5nwGoMkdWgpJTZYM0CUjXqMl8Ss0emNHincMg6XomBTKoqnp1ih7C"},{title:"RSAES-OAEP Encryption Example 4.6",message:"8iJCdR7GsQ==",seed:"Ln4eF/ZHtd3QM+FUcvkPaBLzrE4=",encrypted:"AKX/pHaMi77K7i23fo8u7JlZWTNUVSCDXlun25ST0+F83e/mpfVnYkRxkI204tg6D77mBgj8hASVA7IjSgfcg7J7IoR62JIP9C9nTvebdigLACM9K1G4yycDqdQr+8glDJbsMsBR5X8bS6Uo24nDfkxU4n5uZKxpY1roh9lUFhmp"}],f(a,l,"sha1",p),e="Cq3z+cEl5diR8xrESOmT3v5YD4ArRfnX8iulAh6cR1drWh5oAxup205tq+TZah1vPSZyaM/0CABfEY78rbmYiNHCNEZxZrKiuEmgWoicBgrA2gxfrotV8wm6YucDdC+gMm8tELARAhSJ/0l3cBkNiV/Tn1IpPDnv1zppi9q58Q7Z",t="AQAB",n="AlbrTLpwZ/LSvlQNzf9FgqNrfTHRyQmbshS3mEhGaiaPgPWKSawEwONkiTSgIGwEU3wZsjZkOmCCcyFE33X6IXWI95RoK+iRaCdtxybFwMvbhNMbvybQpDr0lXF/fVKKz+40FWH2/zyuBcV4+EcNloL5wNBy+fYGi1bViA9oK+LF",r="A7DTli9tF1Scv8oRKUNI3PDn45+MK8aCTyFktgbWh4YNrh5jI5PP7fUTIoIpBp4vYOSs1+YzpDYGP4I4X0iZNwc=",i="AuTDLi9Rcmm3ByMJ8AwOMTZffOKLI2uCkS3yOavzlXLPDtYEsCmC5TVkxS1qBTl95cBSov3cFB73GJg2NGrrMx8=",s="AehLEZ0lFh+mewAlalvZtkXSsjLssFsBUYACmohiKtw/CbOurN5hYat83iLCrSbneX31TgcsvTsmc4ALPkM429U=",o="65CqGkATW0zqBxl87ciBm+Hny/8lR2YhFvRlpKn0h6sS87pP7xOCImWmUpfZi3ve2TcuP/6Bo4s+lgD+0FV1Tw==",u="AS9/gTj5QEBi64WkKSRSCzj1u4hqAZb0i7jc6mD9kswCfxjngVijSlxdX4YKD2wEBxp9ATEsBlBi8etIt50cg8s=",a=c(e,t),l=h(e,t,n,r,i,s,o,u),p=[{title:"RSAES-OAEP Encryption Example 5.1",message:"r3GpAeOmHTEy8Pwf20dPnqZXklf/wk0WQXAUWz296A==",seed:"RMkuKD93uUmcYD2WNmDIfS+TlGE=",encrypted:"A2BGpKR9ntO6mokTnBBQOOt0krBaXWi/1TrM/0WX96aGUbR7SkYn2Sfkhe7XtFZkIOi0CYeeXWBuriUdIqXfeZ95IL/BF7mSVypTsSYxRrzqAzhcxehTyaEByMPhvaMaUZgHSWxsteXvtAiCOjUrj6BmH7Zk763Vk965n/9e0ADl"},{title:"RSAES-OAEP Encryption Example 5.2",message:"o7hEoII5qKxBYFrxemz9pNNQE2WFkDpBenkmh2BRmktKwzA+xz8Ph8+zI5k=",seed:"yyj1hgZZ/O7knD7q/OYlpwgDvTI=",encrypted:"A9brZU7c5hW8WfRVJl7U5aGCI8u5vk5AabRzgE1d6W9U3KqmA9BJxdlKoUcN/NIlQGa3x7Yf8fb2dw4yFcUTmf1ONOxQgrxI8ImECtBDVK5m3A8b0Y5GGjPMEli0Q6KDem3yZ1mqIwIzSYb4c4DJzJ1Tvp+ZYF0smpfaewkVpKet"},{title:"RSAES-OAEP Encryption Example 5.3",message:"MIsOy9LHbLd/xvcMXt0jP9LyCSnWKfAmlTu2Ko9KOjFL3hld6FtfgW2iqrB00my2rN3zI647nGeKw88S+93n",seed:"IoX0DXcEgvmp76LHLLOsVXFtwMo=",encrypted:"B3CVIYFkn5+fB/9ib/OiLDXEYkQ9kF1Fap/Qv/Q8rCynqfVU6UeLmsw6yDiwIED/0+GEfeLkJTkp+d2e5ARDJamwXKu4CLLuhA004V0QWj8feydpWhoHotc/4I7KqjycnU1aif+JDVRyfXrkDA7BqN2GFl2O4sY2gUEBaki1W2ln"},{title:"RSAES-OAEP Encryption Example 5.4",message:"FcW57hGF",seed:"SfpF06eN0Q39V3OZ0esAr37tVRM=",encrypted:"CBK3Z2jry2QtBAJY5fREGgGFIb2WaH5sXomfzWwXWI/1moLMiuA6S0WzEpmvF4jDKffc0oX4z0ztgmBrl2EmcaRb7coTNEIUTRYX0RT4AoV/D51zl1HFej+e5ACRLGHi5pkr4DGkPdSPproU7vfEIrXtxOevoE/dOPQC0ci7cZq/"},{title:"RSAES-OAEP Encryption Example 5.5",message:"IQJuaADH+nKPyqug0ZauKNeirE/9irznlPCYX2DIpnNydzZdP+oR24kjogKa",seed:"8Ch0EyNMxQNHJKCUxFhrh6/xM/w=",encrypted:"B7YOFOyVS/0p5g0AR+eJ9R1XGGxjWJkDMGeTztP2gkHHQ1KaumpjdPkuGeAWPvozaX4Zb3Zh36qkeqxr3l5R3rUHxyxYmiyhaT2WsUYDgSSbLNuerER2nySJxdPS+Z8O48fuW/ZKWsecQr1DPxSb6MtZVINhZAWVUTyXr3vCUJcj"},{title:"RSAES-OAEP Encryption Example 5.6",message:"VB43totsiHK4TAI=",seed:"2fukXJbyHm4m0p6yzctlhb6cs0E=",encrypted:"CMNtTdozQjsu1oMNhfZBG6Hc9HCh+uDr7+58CJ8lbO90y5bqacOPYPOavuRBKby0yS3n95diOyAHTj2cKJlwHtkHHh76C92E1MPlEwMC2PAkC6ukuEpxzAMvIjWl/w+uJ3w+j5ESvvRMmuINF1/JpAWL/JMLoxsC4uT0REg3EPJK"}],f(a,l,"sha1",p),e="ErF/ba0uzRn/RtwT94YPCeDgz7Z3s4pSWSMFzq8CLBZtuQ0ErCnjP33RLZ+vZuCBa7Y+rSZ8x9RsF8N74hS8oqItcjpk5EQHQ2tvyWVymu/CVU83bNXc6mgpN4CmK/OdAClIWhYLu55dwJctIaUE9S5e4CiqQWMy9RCy6c/19yKv",t="AQAB",n="ApXso1YGGDaVWc7NMDqpz9r8HZ8GlZ33X/75KaqJaWG80ZDcaZftp/WWPnJNB7TcEfMGXlrpfZaDURIoC5CEuxTyoh69ToidQbnEEy7BlW/KuLsv7QV1iEk2Uixf99MyYZBIJOfK3uTguzctJFfPeOK9EoYij/g/EHMc5jyQz/P5",r="BKbOi3NY36ab3PdCYXAFr7U4X186WKJO90oiqMBct8w469TMnZqdeJpizQ9g8MuUHTQjyWku+k/jrf8pDEdJo4s=",i="BATJqAM3H+20xb4588ALAJ5eCKY74eQANc2spQEcxwHPfuvLmfD/4Xz9Ckv3vv0t1TaslG23l/28Sr6PKTSbke0=",s="A5Ycj3YKor1RVMeq/XciWzus0BOa57WUjqMxH8zYb7lcda+nZyhLmy3lWVcvFdjQRMfrg6G+X63yzDd8DYR1KUs=",o="AiGX4GZ0IZaqvAP6L+605wsVy3h9YXrNMbt1x7wjStcG98SNIYLR8P+cIo3PQZZ7bAum0sCtEQobhXgx7CReLLE=",u="BAHEwMU9RdvbXp2W0P7PQnXfCXS8Sgc2tKdMMmkFPvtoas4kBuIsngWN20rlQGJ64v2wgmHo5+S8vJlNqvowXEU=",a=c(e,t),l=h(e,t,n,r,i,s,o,u),p=[{title:"RSAES-OAEP Encryption Example 6.1",message:"QEbKi6ozR8on9J4NgfnMHXG+m6UX1A==",seed:"3Q9s/kFeiOWkaaUfu6bf1ArbQ4Q=",encrypted:"BjDuvNKFbCT3mIBuQfnmc0Xtqc7aOGrMn6yuoe7tBqzlg3CXGNnRafrfQU1cdvkploM+8wW3Wx5LlfZiog+u3DuuDEgnqL+KiO29V+wgOieoQfAuQ6YVurGoysBwHeNN6972KgiAibVew26nUi/T7I0GtqBz5t+DMVO8Cu/ZO9Gj"},{title:"RSAES-OAEP Encryption Example 6.2",message:"XMcsYCMd8Ds9QPm1eTG8MRCflyUn8osZ50gMcojLPJKyJRIhTkvmyRR5Ldq99X+qiqc=",seed:"jRS9lGoTURSPXK4u2aDGU+hevYU=",encrypted:"Drw3N2FzpP0vicxVwspismsR1Rw8fOSeiEX3TnYHMXxDa8jSO5Zn3+udCHI0tHvGg3F1rlwFWfa4HX0iQW0+UPSsUz2PCBLy2555H+nHdayLatD1Na2c6yOkoCAUxYqz+NMWFJmiYPOTSOcUriodNEMgj9i3Isz9+zk+mAEfmeY/"},{title:"RSAES-OAEP Encryption Example 6.3",message:"sg5lEwMJL0vMtDBwwPhtIwSTYu2WZC/FYywn20pS49gx8qsGiyOxSYecAC9r8/7ul1kRElYs",seed:"bAdbxFUg8WXAv16kxd8ZG8nvDkQ=",encrypted:"Cpi/EJNhk5RDbPaNjzji8Vj96OpU80NfI5uNBrgyGEQgJHau7ZYAlJJIDOOo1wVJjEyMaPAVAdyB22CPYAhzUMjDsL0unvaoFFi3yAG4ny5P6Z1JALpqS15althl3Gdsd1WSh5QTDWKAqBYKGQ8t8+p8+aoCcdiOnmkF7PHFFS1l"},{title:"RSAES-OAEP Encryption Example 6.4",message:"aE4wOMXAQfc=",seed:"O7w71mN9/hKEaQECm/WwwHEDQ5w=",encrypted:"AI56Z8rPtcTiS+x97hSRF/GVmM6MRYCP74jGCP+c1uaVJjuaPArUuLpMlSOOlqhCK4U1YpyNU4I3RHmtE/o5l0skL5p1nur5yDrVqMoYlAoBYrp1WHbfJj9L1QxlJcVgkCZ8Hw4JzgiZoM81nogSCr2b+JNEWzyud9Ngc1mumlL4"},{title:"RSAES-OAEP Encryption Example 6.5",message:"MkiMsmLQQdbk3TX5h788ppbbHwasKaRGkw==",seed:"tGtBiT6L7zJvZ1k4OoMHHa5/yrw=",encrypted:"AAA0dEFse2i9+WHDhXN5RNfx9AyzlTQ8aTzAtP5jsx/t8erurJzMBnizHcMuCXdIlRTE8JCF9imKllPwGupARf9YLuiHviauV1tz7vfzd0kh43Wj0ZrdoMoxqhhJiHwfQsrJZ396L06SP25ahos4wITvGHWU3J9/BI/qLgKVU4Sr"},{title:"RSAES-OAEP Encryption Example 6.6",message:"ULoUvoRicgJ5wwa6",seed:"CiQDMSpB49UvBg+8E6Z95c92Cac=",encrypted:"CgJt2l/IeF972b91Mntj6F4sD97l2ttl69ysmuHelcksZyq0M6p6jmnOam2Il/rErEpU3oQa5eW7znaHh515Y0zqejBoQGXHFNUkCbkoJWu/U+q81SMetyWVBFNzmb0pFktybTOkbacBNgpBaKCRzKty1Epi/tJGwP/qWxNIq1Rw"}],f(a,l,"sha1",p),e="MRF58Lz8m508oxXQDvMNe906LPrpkRv+3LlIs6R4LQcytqtEqkvwN0GmRNwBvsPmmwGgM+Z12KzXxJJcaxrsMRkFHf2Jdi0hXUVHX/y1n5CBSGI/NxdxVvauht16fF9D3B4fkIJUBYooSl8GwAIXk6h/GsX+/33K7mnF5Ro3ieNz",t="AQAB",n="Bwz8/y/rgnbidDLEXf7kj0m3kX1lMOHwyjRg8y4CdhdEh8VuIqRdJQDXd1SVIZ19Flqc872Swyr5qY2NycwpaACtyUoKVPtA80KRv4TujqErbxCTWcbTVCpQ+cdn9c//BaaBwuZW+3fKqttL6UaNirzU35j1jobSBT+hNJ90jiGx",r="B0kmLBEc1HDsJWbms3MvwJMpRpqhkHHTucAZBlFMbx0muqFL6rCXHIt+YRpPeQCdb+p3aSjKJShbDeNkPRo/jHE=",i="BrweUOlsAr9jbp7qi4mbvr92Ud533UdMPpvCO62BgrYZBMfZffvr+x4AEIh4tuZ+QVOR1nlCwrK/m0Q1+IsMsCM=",s="A7x+p/CqsUOrxs6LlxGGNqMBcuTP4CyPoN2jt7qvkPgJKYKYVSX0iL38tL1ybiJjmsZKMJKrf/y/HVM0z6ULW/E=",o="AmKmqinCo8Z9xTRsBjga/Zh6o8yTz7/s9U/dn514fX9ZpSPTmJedoTei9jgf6UgB98lNohUY3DTLQIcMRpeZStk=",u="ZJ1MF7buFyHnctA4mlWcPTzflVDUV8RrA3t0ZBsdUhZq+KITyDliBs37pEIvGNb2Hby10hTJcb9IKuuXanNwwg==",a=c(e,t),l=h(e,t,n,r,i,s,o,u),p=[{title:"RSAES-OAEP Encryption Example 7.1",message:"R6rpCQ==",seed:"Q90JoH/0ysccqkYy7l4cHa7kzY8=",encrypted:"FojkzneUu6bLcBQWns1VnO3iowtWpSto2f4Yzxlz75eyoDFTlRx1X2KUqkmtvbVYRatodfs5hsk+z5J5YoQNKC+eVM6LaQ98DLi71zRA2VcdGxbNkmD56rR4PMSC5SI9xglzhxeD7Cewrg/UdzLLwoahc/ySsA+0umgkZHzZPIXB"},{title:"RSAES-OAEP Encryption Example 7.2",message:"HZsuIiPZvBO/ufFiznNdtIunxo9oIqChp7auFlg05w==",seed:"Opw87HuE+b063svGc+yZ1UsivJs=",encrypted:"EFLtOXsuAeHQ7hxQvyQ2P5XlBPSgNDSgj9giV07WuXNu27XzkNsQMhR5qKE5NQ4r1Jd8N3jvMx8+eK4RiyaEUfIKLwHUcfXVPFZpNxcbLbwtS95FmleZ8DctZXQjmyMj0kXQu4HChrY8iaNhAXM35JAviKRn9MfyRL/Vq0ZDf/O2"},{title:"RSAES-OAEP Encryption Example 7.3",message:"2Xb8",seed:"dqdeW2FXpVbPiIS7LkXCk91UXPU=",encrypted:"IVXNhD/ySk7outt2lCYAKKSQgTuos2mky/EG7BSOUphwf1llvn0QHBBJ6oWEwkzWNFWtnBBNaGKC0/uAOkwRwcLpuRxxeIAdG2ZA8AP1co3wB7ikzMkrzgXkGicnjXyFAYxSQUMTpQd3iQAdTwGRC3Kq0F0iCqFKWHM6dIm8VFVr"},{title:"RSAES-OAEP Encryption Example 7.4",message:"1HOGI98iOqQ4Q9+EZ1NMQdAT4MgDxiTiY2ZrI5veQKXymuuN5549qmHdA3D0m9SwE4NLmCEq72scXuNzs8s=",seed:"eGYxSmrW8rJQo1lB2yj1hktYWFk=",encrypted:"CrFMNzrrfUMo0KqtjAlNiLnrCYuV8hBUopCCUivnwnoxKHi2N5F+PYGebDxWjbXYQ4ArBtUdnpiivgv0DAMUI7AO37/4Mg77kXG9IERlOky5xRIvbGXoPNouw8EmAnqcGla6h00P6iPzgLgs8kC4z1QABHWMTHfZNBV6dPP8Er+s"},{title:"RSAES-OAEP Encryption Example 7.5",message:"u0cjHKXqHTrUbJk0XZqKYQ==",seed:"shZu1HLVjbEMqyxrAAzM8Qp9xQk=",encrypted:"AoOHoxgndDR5i02X9GAGjfUpj6ulBBuhF2Ghy3MWskGEEU7FACV+JYntO2B6HrvpemzC4CvxtoH0IxKjO3p32OeFXEpt4D48BGQ/eGuRomSg1oBeLOqR5oF363pk2SVeTyfnE7fM7ADcIA69IcLqK7iQ/q5JQt+UHcP5eJDtNHR4"},{title:"RSAES-OAEP Encryption Example 7.6",message:"IYSCcJXTXD+G9gDo5ZdUATKW",seed:"Umc73iyhZsKqRhMawdyAjWfX07E=",encrypted:"FMZ4qUrWBSXvOelZsvO6XAl6lP+RK2fbrOgFNcGHq9R9B1QgsYchUrugj3/DHzE7v5JzyRL8TAFJqbDPt5gH40brMyBpYRvsD/m80Wjx98M+dzE86kVLlOJUnuzwAuKs9/by0oRdT+CqsuWpLd9oxICuESR5NdH2JXSEIhauZ0EV"}],f(a,l,"sha1",p),e="W98OMNMh3aUUf4gkCPppGVSA34+A0/bov1gYUE82QnypsfVUC5xlqPaXTPhEeiRNkoAgG7Sfy75jeNGUTNIn4jD5bj0Q+Bnc7ydsZKALKktnAefQHeX6veOx6aDfgvRjE1nNImaWR/uxcXJGE07XtJfP/73EK1nHOpbtkBZiEt/3",t="AQAB",n="D30enlqqJf0T5KBmOuFE4NFfXNGLzbCd8sx+ZOPF6RWtYmRTBBYdCYxxW7eri9AdB+rz/tfH7QivKopi70SrFrMg4Ur3Kkj5av4mKgrkz2XmNekQeQzU7lzqdopLJjn35vZ3s/C7a+MrdXR9iQkDbwJk9Y1AHNuhMXFhV6dez2Mx",r="CgLvhEjZ+ti70NAEyMKql1HvlyHBsNAyNqVLDflHy67VolXuno4g1JHqFyP+CUcEqXYuiK/RbrtZlEEsqWbcT58=",i="CS02Ln7ToL/Z6f0ObAMBtt8pFZz1DMg7mwz01u6nGmHgArRuCuny3mLSW110UtSYuByaxvxYWT1MP7T11y37sKk=",s="B8cUEK8QOWLbNnQE43roULqk6cKd2SFFgVKUpnx9HG3tJjqgMKm2M65QMD4UA10a8BQSPrpoeCAwjY68hbaVfX0=",o="rix1OAwCwBatBYkbMwHeiB8orhFxGCtrLIO+p8UV7KnKKYx7HKtYF6WXBo/IUGDeTaigFjeKrkPH+We8w3kEuQ==",u="BZjRBZ462k9jIHUsCdgF/30fGuDQF67u6c76DX3X/3deRLV4Mi9kBdYhHaGVGWZqqH/cTNjIj2tuPWfpYdy7o9A=",a=c(e,t),l=h(e,t,n,r,i,s,o,u),p=[{title:"RSAES-OAEP Encryption Example 8.1",message:"BQt1Xl5ogPe56daSp0w3quRJsxv+pt7/g3R6iX9sLIJbsa2/hQo8lplLXeWzPLx9SheROnln",seed:"dwb/yh7PsevuKlXlxuJM0nl6QSU=",encrypted:"CbNoPYousPspW2LtH7kpC3FEV7eCUxn0ZHhyr4ibMECUcgIK0SkSvxmxHUgZ9JYUgk/9hNCcChfn0XMJ0SkZeQQQqimVaZ9qhtvjJCtazCOvRWkQgNaxroEPs+MFcIfwlwCSzgC+lWL/QFO2Jizgyqk+E3I9LjpboHXUXw1htUth"},{title:"RSAES-OAEP Encryption Example 8.2",message:"TraNzZPKmxnfERvUNgj1VwJv5KodXPrCJ6PrWrlUjBigbd7SP4GCWYay/NcRCezvfv+Ihz8HXCqgxGn2nJK8",seed:"o3F9oUO03P+8dCZlqPqVBYVUg0M=",encrypted:"Ls8VyXxaFbFHaumGs3G1eiQoT0oWKo0MgYLnkF55IlbxgSul+D8fehMOQtzAIjKETtwUoxpo7peuVko4OjQRZWQkxfYt22Rgk8Nnvh/NpCbPAKBtist+V3dvu9hVrD31BvwWsdfD8hEPPYBo6R4YY2ODHIQJaA2NqezYzx+iDuOd"},{title:"RSAES-OAEP Encryption Example 8.3",message:"hgSsVjKMGrWtkXhh",seed:"7gYgkHPMoCa7Jk5Rhb+MaLdzn4Y=",encrypted:"S8iRMKWy2rt8L8+Q610Or55oG3FGo48xc6PZz+xS6p4KQZMuZIqdaTRMUNp2P1GgPJV2ITHoBSJU3NIkjLpA/TFmd4bOBaK3tTGsnaye1YSlm2d8GortjF0V1owFVp4r54C/fbY4/Sv9KoWrJ2hg83dzOPypif/XQ9E+4I4MqYk/"},{title:"RSAES-OAEP Encryption Example 8.4",message:"/dpfv27DYanZpKxoryFqBob0OLHg5cNrlV904QfznA3dzA==",seed:"mQrVc9xIqXMjW22CVDYY8ulVEF0=",encrypted:"LkVoR9j8Nv8BR9aZNZS5OXIn1Xd1LHnQ+QT8sDnU2BL+pgWntXTdgsp4b5N1I0hDjun1tUVJhdXw4WmePnrRdaMuFfA96wQquf4d2dsbuG+MCJzLRefvDF7nyptykMprFb7UcDl4ioqT/4Pg6NYkTHEAY2Le72m29Bb7PGhDg/vQ"},{title:"RSAES-OAEP Encryption Example 8.5",message:"Sl9JFL7iXePGk0HeBw==",seed:"7MY7KPB1byL1Ksjm7BJRpuwwRxg=",encrypted:"H7k1b9XEsXltsuv30NOTzIEK32FF3vwvznFPedk4ANXirCEeqLvsyktlS5TDsYsw3Vds403JVDbvV6CUFWRZIzWaXXtBce8iwkZw8bIp02A+kfdmcbffl+cxfJdzRHbV89F9Ic+Ctbqfg98uWI02mE/RtYRGi9I7LodfMvaJU/ey"},{title:"RSAES-OAEP Encryption Example 8.6",message:"jgfWb3uICnJWOrzT81CSvDNAn7f4jyRyvg==",seed:"OSXHGzYtQKCm3kIUVXm6Hn3UWfw=",encrypted:"Ov2cZgAUeyF5jYGMZVoPTJIS2ybQsN/cKnWUzLPSL1vx18PhEs1z/H1QnHqLr908J00TmQCflgnsS+ZHfkU/B1qjPbOChwwcNAmu85LXOGrjppa5mpS02gWJRH6VXRbJixdgKlm9c2J5/Nj7KAxEYtWQv6m/E/7VcOr96XMwosIQ"}],f(a,l,"sha1",p),e="zyzUHjTKOnKOpcuK/2TDbSe971Nk4zb9aNMSPFoZaowocBPoU9UVbVjRUZVFIPtPbXsXq7aBd2WQnFdhGWWdkCsZBu2KKxDBVcJNEkUo2rnurjeb6sZuSkEXhty4/QBi68Aw3hIZoEwqjBt90xMeTWtsruLjGl7UGsFQmy7x7iqxg2S+VoypQcJezIT/nWQ7XsGqrhAqINc/R5t4D9bakQdSEtnqwDoGdNiZ66LkMfTES2Fba6IjK9SzO67XPWJd",t="AQAB",n="GYwUHiNxWpK8z2oRmlvBE4lGjSgR9UjXJ+F7SrDrmG1vIR77U7cffMvqh+5px17mFQCMUzLetSvzkKvfv+N9cgU2gVmyY4wd4ybiHSIlHw+1hIs78VAF0qdDMPCv6RbuYszBNE0dg6cJ5gZ2JzhA9/N3QkpeCk2nXwGzH/doGc+cv90hUkPDkXwD7zgZkxLlZ7O/eu06tFfzce+KFCP0W2jG4oLsERu6KDO5h/1p+tg7wbjGE8Xh6hbBHtEl6n7B",r="/I1sBL7E65qBksp5AMvlNuLotRnezzOyRZeYxpCd9PF2230jGQ/HK4hlpxiviV8bzZFFKYAnQjtgXnCkfPWDkKjD6I/IxI6LMuPaIQ374+iB6lZ0tqNIwh6T+eVepl79",i="0gDUXniKrOpgakAdBGD4fdXBAn4S3BoNdYbok52c94m0D1GsBEKWHefSHMIeBcgxVcHyqpGTOHz9+VbLSNFTuicEBvm7ulN9SYfZ4vmULXoUy//+p0/s3ako0j4ln17h",s="2xaAL3mi8NRfNY1p/TPkS4H66ChiLpOlQlPpl9AbB0N1naDoErSqTmyL6rIyjVQxlVpBimf/JqjFyAel2jVOBe8xzIz3WPRjcylQsD4mVyb7lOOdalcqJiRKsI23V1Kt",o="oKMXz+ffFCP4em3uhFH04rSmflSX8ptPHk6DC5+t2UARZwJvVZblo5yXgX4PXxbifhnsmQLgHX6m+5qjx2Cv7h44G2neasnAdYWgatnEugC/dcitL6iYpHnoCuKU/tKh",u="CyHzNcNTNC60TDqiREV4DC1lW5QBdMrjjHyKTmSTwLqf0wN0gmewg7mnpsth5C2zYrjJiW23Bk4CrVrmFYfaFbRknJBZSQn+s328tlS+tyaOyAHlqLSqORG+vYhULwW+",a=c(e,t),l=h(e,t,n,r,i,s,o,u),p=[{title:"RSAES-OAEP Encryption Example 9.1",message:"9zX9VbqSWSw7Urj5xPaaqhy++P6IrdCVWVQSRn+c9OwLiWxZ7aFiEOdUnIq7EM28IaEuyba1uP0vEDmetg==",seed:"jsll8TSj7Jkx6SocoNyBadXqcFw=",encrypted:"JnvNEYrKsfyLqByF1zADy4YQ+lXB2X2o1Ip8fwaJak23UaooQlW502rWXzdlPYKfGzf5e4ABlCVFsvwsVac3bKehvksXYMjgWjPlqiUmuNmOMXCI54NMdVsqWbEmMaGCwF1dQ6sXeSZPhFb1Fc5X399RLVST2re3M43Et9eNucCRrDuvU3pp/H9UnZefDv+alP2kFpvU0dGaacmeM8O1VJDVAbObHtrhGP9nk6FTJhWE06Xzn25oLj0XyM0SYfpy"},{title:"RSAES-OAEP Encryption Example 9.2",message:"gbkGYFAVpjqr5C3fEeGXiRL1QEx0dLJtzj7Ugr+WHsyBi/QgxUZZ",seed:"7LG4sl+lDNqwjlYEKGf0r1gm0Ww=",encrypted:"k6yfBnHsKay7RE7/waV0E1HWD9sOOT+/dUrPDeSXYaFIQd93cum8gnc5ZqFYTE1yuuoAEY+D81zKblN8vU2BH1WDspeD2KbZTNMb5w1vUmwQ/wnG+nzgaXlaP80FEf1fy1ZLzIDqnHjzi4ABJTnYpN32/oHpzdt/UNu7vMfl2GCXzPTsSRifuL8xi+bVoHFdUWtJrxkSWM0y3IM85utGc8A6Gbus6IzFSJX2NswMHsiQltEc4jWiZcoXZCMqaJro"},{title:"RSAES-OAEP Encryption Example 9.3",message:"/TJkKd+biQ4JtUsYuPNPHiQ=",seed:"6JuwMsbOYiy9tTvJRmAU6nf3d8A=",encrypted:"gevdlQVLDIIu+a12k/Woet+0tMTOcN8t+E7UnATaWLpfwgoZ4abot6OQCyJ5bcToae5rQnktFajs61bAnGmRToE86o9pMeS47W9CGvKY1ZXJf0eJx8qmEsfvNgmEwhuT7cVAEGi1r0x4qHcbmE1TuOqK3y9qfUoLp2x14d2fZY8g3tSkYHHUbXeRtWgD2P6n8LD45Brj8JODpvlYX+d1Pqr/0r+UVjEIvuzCB7u1NfX8xwXw3en3CMYvSanJA3HT"},{title:"RSAES-OAEP Encryption Example 9.4",message:"8UWbXwyS8BoPcjouVmJITY+MCiD8KdrWrNQ7tfPv/fThtj4H/f5mKNDXTKGb8taeSgq/htKTklp5Z3L4CI4=",seed:"YG87mcC5zNdx6qKeoOTIhPMYnMw=",encrypted:"vMNflM3mbLETZiXWJblEMqNbIvPS+hGmE/8PylvVf4e5AszcHNCuvLBxXuhp0dH+OV9nkwA/XspGUFnIhmDURv9fCBhVICJVfjjAimfq2ZEmIlTxBoKXXsVjl3aFN/SXevbV9qrOt/sl3sWTcjAjH9iXivSRGaKfKeQkq4JytHVieS1clPd0uIKdCw2fGoye3fN1dNX6JI7vqcUnH8XsJXnIG91htBD6Yf425CQiHBE63bJ1ZkyAHTTKjGNR5KhY"},{title:"RSAES-OAEP Encryption Example 9.5",message:"U+boxynW+cMZ3TF+dLDbjkzMol88gwV0bhN6xjpj7zc557WVq7lujVXlT3vUGrQzN4/7kR0=",seed:"/LxCFALp7KvGCCr6QLpfJlIshA4=",encrypted:"Iyr7ySf6CML2onuH1KXLCcB9wm+uc9c6kFWIOfT9ZtKBuH7HNLziN7oWZpjtgpEGp95pQs1s3OeP7Y0uTYFCjmZJDQNiZM75KvlB0+NQVf45geFNKcu5pPZ0cwY7rseaEXn1oXycGDLyg4/X1eWbuWWdVtzooBnt7xuzrMxpfMbMenePYKBkx/b11SnGIQJi4APeWD6B4xZ7iZcfuMDhXUT//vibU9jWTdeX0Vm1bSsI6lMH6hLCQb1Y1O4nih8u"},{title:"RSAES-OAEP Encryption Example 9.6",message:"trKOohmNDBAIvGQ=",seed:"I6reDh4Iu5uaeNIwKlL5whsuG6I=",encrypted:"Q4zH3AimjaJJ5CUF+Fc7pg4sJ3PVspD0z53/cY6EIIHDg+ZwJKDylZTqmHudJeS3OPKFlw0ZWrs6jIBU49eda5yagye6WW8SWeJxJmdHZpB9jVgv86hHYVSSmtsebRI1ssy07I9mO6nMZwqSvr2FPI2/acZDbQFvYa3YNulHMkUENCB/n9TEPewqEqlY76Ae/iZpiZteYEwlXFX7cWbeVYnjaVl7sJFowG3V2xd+BqF0DrLVyC+uym2S/O6ZMbqf"}],f(a,l,"sha1",p),e="rkXtVgHOxrjMBfgDk1xnTdvg11xMCf15UfxrDK7DE6jfOZcMUYv/ul7Wjz8NfyKkAp1BPxrgfk6+nkF3ziPn9UBLVp5O4b3PPB+wPvETgC1PhV65tRNLWnyAha3K5vovoUF+w3Y74XGwxit2Dt4jwSrZK5gIhMZB9aj6wmva1KAzgaIv4bdUiFCUyCUG1AGaU1ooav6ycbubpZLeGNz2AMKu6uVuAvfPefwUzzvcfNhP67v5UMqQMEsiGaeqBjrvosPBmA5WDNZK/neVhbYQdle5V4V+/eYBCYirfeQX/IjY84TE5ucsP5Q+DDHAxKXMNvh52KOsnX1Zhg6q2muDuw==",t="AQAB",n="BWsEIW/l81SsdyUKS2sMhSWoXFmwvYDFZFCiLV9DjllqMzqodeKR3UP0jLiLnV/A1Jn5/NHDl/mvwHDNnjmMjRnmHbfHQQprJnXfv100W4BNIBrdUC1c4t/LCRzpmXu+vlcwbzg+TViBA/A29+hdGTTRUqMj5KjbRR1vSlsbDxAswVDgL+7iuI3qStTBusyyTYQHLRTh0kpncfdAjuMFZPuG1Dk6NLzwt4hQHRkzA/E6IoSwAfD2Ser3kyjUrFxDCrRBSSCpRg7Rt7xA7GU+h20Jq8UJrkW1JRkBFqDCYQGEgphQnBw786SD5ydAVOFelwdQNumJ9gkygHtSV3UeeQ==",r="7PWuzR5VFf/6y9daKBbG6/SQGM37RjjhhdZqc5a2+AkPgBjH/ZXMNLhX3BfwzGUWuxNGq01YLK2te0EDNSOHtwM40IQEfJ2VObZJYgSz3W6kQkmSB77AH5ZCh/9jNsOYRlgzaEb1bkaGGIHBAjPSF2vxWl6W3ceAvIaKp30852k=",i="vEbEZPxqxMp4Ow6wijyEG3cvfpsvKLq9WIroheGgxh5IWKD7JawpmZDzW+hRZMJZuhF1zdcZJwcTUYSZK2wpt0bdDSyr4UKDX30UjMFhUktKCZRtSLgoRz8c52tstohsNFwD4F9B1RtcOpCj8kBzx9dKT+JdnPIcdZYPP8OGMYM=",s="xzVkVx0A+xXQij3plXpQkV1xJulELaz0K8guhi5Wc/9qAI7U0uN0YX34nxehYLQ7f9qctra3QhhgmBX31FyiY8FZqjLSctEn+vS8jKLXc3jorrGbCtfaPLPeCucxSYD2K21LCoddHfA8G645zNgz72zX4tlSi/CE0flp55Tp9sE=",o="Jlizf235wQML4dtoEX+p2H456itpO35tOi9wlHQT7sYULhj7jfy2rFRdfIagrUj4RXFw8O+ya8SBJsU+/R0WkgGY3CoRB9woLbaoDNMGI2C6P6E/cOQxL/GmzWuPxM2cXD2xfG1qVyEvc64p9hkye61ZsVOFhYW6Tii2CmKkXkk=",u="bzhSazklCFU07z5BWoNu3ouGFYosfL/sywvYNDBP7Gg7qNT0ecQz1DQW5jJpYjzqEAd22Fr/QB0//2EO5lQRzjsTY9Y6lwnu3kJkfOpWFJPVRXCoecGGgs2XcQuWIF7DERfXO182Ij+t1ui6kN18DuYdROFjJR4gx/ZuswURfLg=",a=c(e,t),l=h(e,t,n,r,i,s,o,u),p=[{title:"RSAES-OAEP Encryption Example 10.1",message:"i7pr+CpsD4bV8XVul5VocLCJU7BrTrIFvBaU7g==",seed:"R+GrcRn+5WyV7l6q2G9A0KpjvTM=",encrypted:"U+pdwIzSYPs7hYVnKH+pFVLDCy/r+6IT8K6HcC0GjRm6sH/ldFI9+0ITnWjDxa/u4L/ky3lpy/OCuATW5hOWFE4tDmB0H4mTwwFLWLmxlXqLq80jr4VPTDVvsWYqpyv8x+WGVZ3EKA0WDBJnhacj6+6+/3HxFZRECq74fRB5Ood0ojnUoEyH/hRnudr4UgjsbHJVeUqWzCkUL5qL1Bjjwf1nNEsM0IKd87K+xgJTGWKTxrNNP3XTLyE91Fxic9UFrfTM7RBXy3WPwmru+kQSVe1OZMGZ7gdefxZkYYL9tGRzm2irXa/w5j6VUgFoJPBUv008jJCpe7a2VTKE60KfzA=="},{title:"RSAES-OAEP Encryption Example 10.2",message:"5q0YHwU7WKkE8kV1EDc+Vw==",seed:"bRf1tMH/rDUdGVv3sJ0J8JpAec8=",encrypted:"orGkMKnWV+L6HCu17UP/slwFowj+kJPAEDF5X1h0QAEQgorlj7m1gc6d3dPlSa4EoJhUWb3mxiZZTnsF3EJ4sqFGXBNoQIgjyF6W3GbDowmDxjlmT8RWmjf+IeWhlbV3bu0t+NjTYa9obnUCKbvWY/FhhopQYV4MM3vsDKNf7AuxnDbrLgu8wFgvodk6rNsGEGP1nyzh7kNgXl2J7KGD0qzf6fgQEQIq07Q6PdQX2slLThHqgbGSlm6WaxgggucZZGB7T4AC82KZhEoR8q4PrqwurnD49PmAiKzc0KxVbp/MxRFSGQj60m8ExkIBRQMFd4dYsFOL+LW7FEqCjmKXlQ=="},{title:"RSAES-OAEP Encryption Example 10.3",message:"UQos9g6Gb6I0BVPJTqOfvCVjEeg+lEVLQSQ=",seed:"OFOHUU3szHx0DdjN+druSaHL/VQ=",encrypted:"mIbD5nZKi5qE6EFI69jDsaqAUDgaePZocUwW2c/Spu3FaXnFNdne47RLhcGL6JKJkjcXEUciFtld2pjS7oNHybFN/9/4SqSNJawG99fmU5islnsc6Qkl9n3OBJt/gS2wdCmXp01E/oHb4Oej/q8uXECviI1VDdu+O8IGV6KVQ/j8KRO5vRphsqsiVuxAm719wNF3F+olxD9C7Sffhzi/SvxnZv96/whZVV7ig5IPTIpjxKc0DLr93DOezbSwUVAC+WyTK1t5Fnr2mcCtP8z98PROhacCYr8uGP40uFBYmXXoZ/+WnUjqvyEicVRs3AWmnstSblKHDINvMHvXmHgO3g=="},{title:"RSAES-OAEP Encryption Example 10.4",message:"vN0ZDaO30wDfmgbiLKrip18QyR/2Z7fBa96LUwZKJkmpQEXJ",seed:"XKymoPdkFhqWhPhdkrbg7zfKi2U=",encrypted:"Yxjp+1wNBeUwfhaDQ26QMpOsRkI1iqoiPXFjATq6h+Lf2o5gxoYOKaHpJoYWPqC5F18ynKOxMaHt06d3Wai5e61qT49DlvKM9vOcpYES5IFg1uID2qWFbzrKX/7Vd69JlAjj39Iz4+YE2+NKnEyQgt5lUnysYzHSncgOBQig+nEi5/Mp9sylz6NNTR2kF4BUV+AIvsVJ5Hj/nhKnY8R30Vu7ePW2m9V4MPwsTtaG15vHKpXYX4gTTGsK/laozPvIVYKLszm9F5Cc8dcN4zNa4HA5CT5gbWVTZd5lULhyzW3h1EDuAxthlF9imtijU7DUCTnpajxFDSqNXu6fZ4CTyA=="},{title:"RSAES-OAEP Encryption Example 10.5",message:"p91sfcJLRvndXx6RraTDs9+UfodyMqk=",seed:"lbyp44WYlLPdhp+n7NW7xkAb8+Q=",encrypted:"dSkIcsz9SkUFZg1lH1babaoJyhMB2JBjL2qZLz1WXO5GSv3tQO07W+k1ZxTqWqdlX0oTZsLxfHKPbyxaXR+OKEKbxOb48s/42o3A4KmAjkX9CeovpAyyts5v//XA4VnRG2jZCoX3uE4QOwnmgmZkgMZXUFwJKSWUaKMUeG106rExVzzyNL9X232eZsxnSBkuAC3A3uqTBYXwgx/c2bwz1R957S/8Frz01ZgS/OvKo/kGmw5EVobWRMJcz2O0Vu5fpv/pbxnN91H+2erzWVd1Tb9L/qUhaqGETcUHyy0IDnIuuhUDCMK1/xGTYg8XZuz0SBuvuUO9KSh38hNspJSroA=="},{title:"RSAES-OAEP Encryption Example 10.6",message:"6vGnOhsMRglTfeac2SKLvPuajKjGw++vBW/kp/RjTtALfDnsaSLXuOosBOus",seed:"n0fd9C6X7qhWqb28cU6zrCL26zI=",encrypted:"LSB6c0Mqj7TAMFGz9zsophdkCY36NMR6IJlfgRWqaBZnm1V+gtvuWEkIxuaXgtfes029Za8GPVf8p2pf0GlJL9YGjZmE0gk1BWWmLlx38jA4wSyxDGY0cJtUfEb2tKcJvYXKEi10Rl75d2LCl2Pgbbx6nnOMeL/KAQLcXnnWW5c/KCQMqrLhYaeLV9JiRX7YGV1T48eunaAhiDxtt8JK/dIyLqyXKtPDVMX87x4UbDoCkPtnrfAHBm4AQo0s7BjOWPkyhpje/vSy617HaRj94cGYy7OLevxnYmqa7+xDIr/ZDSVjSByaIh94yCcsgtG2KrkU4cafavbvMMpSYNtKRg=="}],f(a,l,"sha1",p)}function o(){var e,t,n,r,i,s,o,u,a,l,p;e="qLOyhK+OtQs4cDSoYPFGxJGfMYdjzWxVmMiuSBGh4KvEx+CwgtaTpef87Wdc9GaFEncsDLxkp0LGxjD1M8jMcvYq6DPEC/JYQumEu3i9v5fAEH1VvbZi9cTg+rmEXLUUjvc5LdOq/5OuHmtme7PUJHYW1PW6ENTP0ibeiNOfFvs=",t="AQAB",n="UzOc/befyEZqZVxzFqyoXFX9j23YmP2vEZUX709S6P2OJY35P+4YD6DkqylpPNg7FSpVPUrE0YEri5+lrw5/Vf5zBN9BVwkm8zEfFcTWWnMsSDEW7j09LQrzVJrZv3y/t4rYhPhNW+sEck3HNpsx3vN9DPU56c/N095lNynq1dE=",r="0yc35yZ//hNBstXA0VCoG1hvsxMr7S+NUmKGSpy58wrzi+RIWY1BOhcu+4AsIazxwRxSDC8mpHHcrSEurHyjnQ==",i="zIhT0dVNpjD6wAT0cfKBx7iYLYIkpJDtvrM9Pj1cyTxHZXA9HdeRZC8fEWoN2FK+JBmyr3K/6aAw6GCwKItddw==",s="DhK/FxjpzvVZm6HDiC/oBGqQh07vzo8szCDk8nQfsKM6OEiuyckwX77L0tdoGZZ9RnGsxkMeQDeWjbN4eOaVwQ==",o="lSl7D5Wi+mfQBwfWCd/U/AXIna/C721upVvsdx6jM3NNklHnkILs2oZu/vE8RZ4aYxOGt+NUyJn18RLKhdcVgw==",u="T0VsUCSTvcDtKrdWo6btTWc1Kml9QhbpMhKxJ6Y9VBHOb6mNXb79cyY+NygUJ0OBgWbtfdY2h90qjKHS9PvY4Q==",a=c(e,t),l=h(e,t,n,r,i,s,o,u),p=[{title:"RSAES-OAEP Encryption Example 1.1",message:"ZigZThIHPbA7qUzanvlTI5fVDbp5uYcASv7+NA==",seed:"GLd26iEGnWl3ajPpa61I4d2gpe8Yt3bqIQadaXdqM+k=",encrypted:"W1QN+A1CKWotV6aZW7NYnUy7SmZd34SiX0jiPiLj9+8sZW6O/L7793+IFFSO3VKbPWhrjJPyR3ZmZ+yHDCzTDkRth+s5FN3nuFtlD3XQmmh0+x60PvAUiXJnAMcwxV96wHKjsUNPSnE1fsrCPBpIO5ZRaJ1pIF6R25IeuMwDujo="},{title:"RSAES-OAEP Encryption Example 1.2",message:"dQxAR/VH6OQUEYVlIymKybriRe+vE5f75W+d1Q==",seed:"DMdCzkqbfzL5UbyyUe/ZJf5P418Mx0LOSpt/MvlRvLI=",encrypted:"jsKSyOW1BkucnZpnt9fS72P/lamWQqexXEDPVs8uzGlFj24Rj+cqGYVlt7i9nTmOGj2YrvM8swUTJQCYIF+QBiKbkcA7WBTBXfiUlkHvpWQD0bLwOkp1CmwfpF4sq2gTsCuSaGzZAc50ZAIOvpldizU7uOCwNNGOlERcFkvhfEE="},{title:"RSAES-OAEP Encryption Example 1.3",message:"2Urggy5kRc5CMxywbVMagrHbS6rTD3RtyRbfJNTjwkUf/1mmQj6w4dAtT+ZGz2md/YGMbpewUQ==",seed:"JRTfRpV1WmeyiOr0kFw27sZv0v0lFN9GlXVaZ7KI6vQ=",encrypted:"LcQ1BhOH4Vs0XX8/QJ6q/L0vSs9BUXfA20lQ6mwAt/gvUaUOvKJWBujoxt1QgpRnU6WuH7cSCFWXuKNnrhofpFF3CBTLIUbHZFoou0A4Roi4vFGFvYYu96Boy+oWivwB9/BKs1QMQeHADgNwUgqVD15+q27yHdfIH7kGp+DiGas="},{title:"RSAES-OAEP Encryption Example 1.4",message:"UuZQ2Y5/KgSLT4aFIVO5fgHdMW80ahn2eoU=",seed:"xENaPhoYpotoIENikKN877hds/vEQ1o+Ghimi2ggQ2I=",encrypted:"ZMkqw9CM3SuY2zPBr8/9QbgXaVon4O4AKIufl3i7RVPD07fiTOnXF0aSWKUcdXNhE6ZcXc0Ha97/S5aw6mQKYfbmjaSq/H45s2nfZYTNIa74OgsV1DTDDLSF6/3J2UKhsG0LGIFaV9cNjfucDA5KbfQbzTq8u/+WN06J6nbInrI="},{title:"RSAES-OAEP Encryption Example 1.5",message:"jaif2eX5dKKf7/tGK0kYD2z56AI=",seed:"sxjELfO+D4P+qCP1p7R+1eQlo7WzGMQt874Pg/6oI/U=",encrypted:"NzKEr8KhWRbX/VHniUE8ap0HzdDEWOyfl7dfNHXjL4h/320dmK633rGUvlA7sE4z9yuMj/xF++9ZeBzN6oSPLhVJV/aivUfcC8J99lwwp49W7phnvkUA4WUSmUeX+XRhwj8cR27mf5lu/6kKKbgasdt4BHqXcc5jOZICnld6vdE="},{title:"RSAES-OAEP Encryption Example 1.6",message:"JlIQUIRCcQ==",seed:"5OwJgsIzbzpnf2o1YXTrDOiHq8Lk7AmCwjNvOmd/ajU=",encrypted:"nfQEzsDY2gS9UYXF85t+u0Tm7HrOmmf+LqxCD+6N4XD36NoQ96PE9Squ83PvxKy8Bj8Q0N2L8E5Z5/9AWxLPCBqOkqkqIqO7ZDQMmpHml3H1yz82rpAzAQi6acZDSFQAW8NKhg4nEEwfwKdaGQcI0JZm6FrTQUuXskOqFUT0NJc="}],f(a,l,"sha256",p),e="AZR8f86QQl9HJ55whR8l1eYjFv6KHfGTcePmKOJgVD5JAe9ggfaMC4FBGQ0q6Nq6fRJQ7G22NulE7Dcih3x8HQpn8UsWlMXwN5RRpD5Joy3eg2cLc9qRocmbwjtDamAFXGEPC6+ZwaB5VluVo/FSZjLR1Npg8g7aJeZTxPACdm9F",t="AQAB",n="CCPyD6212okIip0AiT4h+kobEfvJPGSjvguq6pf7O5PD/3E3BMGcljwdEHqumQVHOfeeAuGG3ob4em3e/qbYzNHTyBpHv6clW+IGAaSksvCKFnteJ51xWxtFW91+qyRZQdl2i5rO+zzNpZUto87nJSW0UBZjqO4VyemS2SRi/jk=",r="AVnb3gSjPvBvtgi4CxkPTT4ivME6yOSggQM6v6QW7bCzOKoItXMJ6lpSQOfcblQ3jGlBTDHZfdsfQG2zdpzEGkM=",i="AStlLzBAOzi0CZX9b/QaGsyK2nA3Mja3IC05su4wz7RtsJUR9vMHzGHMIWBsGKdbimL4It8DG6DfDa/VUG9Wi9c=",s="Q271CN5zZRnC2kxYDZjILLdFKj+1763Ducd4mhvGWE95Wt270yQ5x0aGVS7LbCwwek069/U57sFXJIx7MfGiVQ==",o="ASsVqJ89+ys5Bz5z8CvdDBp7N53UNfBc3eLv+eRilIt87GLukFDV4IFuB4WoVrSRCNy3XzaDh00cpjKaGQEwZv8=",u="AnDbF9WRSwGNdhGLJDiac1Dsg2sAY6IXISNv2O222JtR5+64e2EbcTLLfqc1bCMVHB53UVB8eG2e4XlBcKjI6A==",a=c(e,t),l=h(e,t,n,r,i,s,o,u),p=[{title:"RSAES-OAEP Encryption Example 2.1",message:"j/AMqmBccCgwY02abD1CxlK1jPHZL+xXC+7n",seed:"jEB7XsKJnlCZxT6M55O/lOcbF4KMQHtewomeUJnFPow=",encrypted:"AR3o2JwhHLKUfOLZ26KXD9INUK1/fWJzdZix7E545qladDYdpHRaE5zBP9nf6IPmZvBUPq75n1E4suxm+Bom7crf9be1HXCFZnmR/wo92CKg4D1zRlBwr/3Gitr3h9rU6N+tid2x9yOYj955rf3Bq4j6wmjYQpWphbhBIBMoliyJ"},{title:"RSAES-OAEP Encryption Example 2.2",message:"LQ==",seed:"tgDPPC5QbX8Wd4yRDTqLAD7uYdW2AM88LlBtfxZ3jJE=",encrypted:"AIeYuAD2aYZYnEu1YK+INur95FfP2pTz8/k4r3xwL4bVMufgvzWFLdVK24fP96jTteLkrX6HjmebBVeUhSWG3ahebh3LH5yVS9yx+xHzM1Jxc8X1rS+kYgdCGWFbszMF/vP0ogisy5XthHqcoHNEM4Rzln7ugrXuS+dNuuPEjIAf"},{title:"RSAES-OAEP Encryption Example 2.3",message:"dPyIxRvJD3evnV6aSnATPUtOCzTaPDfH744=",seed:"pzdoruqpH52MHtb50rY0Z/B8yuOnN2iu6qkfnYwe1vk=",encrypted:"AMkW9IJHAFs0JbfwRZhrRITtj1bQVDLcjFCwYxHMDBlSHIqpDzSAL8aMxiUq41Feo9S2O/1ZTXIiK8baJpWs9y+BPqgi1lABB6JJIvU2QZYMzWK0XgjkWk12g6HSPFhuK4yf+LQ1UYpbKVquUdZ9POOCR8S7yS+tdful6qP8Wpkm"},{title:"RSAES-OAEP Encryption Example 2.4",message:"p+sqUDaTHSfU6JEybZlpL/rdqb9+/T405iLErcCF9yHf6IUHLHiiA7FRc5vlQPqMFToQ8Ao=",seed:"mns7DnCL2W+BkOyrT7mys4BagVaaezsOcIvZb4GQ7Ks=",encrypted:"AJ6YQ3DNjd7YXZzjHASKxPmwFbHKwoEpof+P+Li3+o6Xa95C21XyWZF0iCXc5USp5jwLt66T6G3aYQkEpoyFGvSPA3NV6tOUabopdmslYCkOwuOIsFLiuzkJc4Hu6nWXeJtTVtHn7FmzQgzQOMjuty1YConfe78YuQvyE3IAKkr2"},{title:"RSAES-OAEP Encryption Example 2.5",message:"LvKwZvhUwz873LtZlKQ15z1sbA==",seed:"6zzrvErcFrtI6IyK7A40r39Cf9PrPOu8StwWu0jojIo=",encrypted:"AMv457W0EOt8RH+LAEoMQ7dKjZamzOdwTHJepDkaGGoQHi2z8coCiVemL5XYZ+ctjPBdw3y3nlMn1sif9i3WCzY26ram8PL5eVYk7Bm3XBjv9wuhw1RZmLFzKfJS+3vi+RTFhwjyyeaJrc07f5E7Cu7CVWNh3Oe3lvSF3TB2HUI8"},{title:"RSAES-OAEP Encryption Example 2.6",message:"in+zRMi2yyzy7x9kP5oyGPbhm7qJwA==",seed:"TEXPTVfJjj1tIJWtxRxInrUN/4RMRc9NV8mOPW0gla0=",encrypted:"AJ5iMVr3Q6ZZlqLj/x8wWewQBcUMnRoaS2lrejzqRk12Bw120fXolT6pgo20OtM6/ZpZSN7vCpmPOYgCf93MOqKpN1pqumUH33+iP1a+tos5351SidwwNb2hLy3JfhkapvjB+c9JvbIolIgr+xeWhWPmMDam/Du/y+EsBOdZrbYc"}],f(a,l,"sha256",p),e="ArWP7AOahgcApNe2Ri+T5s3UkRYd3XT06BC0DjwWUgBqXCd7J3TBEwWky6taeO+lfheobfej+jb8Sx0iSfIux8LdakYyMqzOqQbWbr6AtXBLEHKdpvgzI0q7Xv3UopLL+tM7TTP6ehS4w5e1bjrNISA0KLd836M6bacGs9iw/EPp",t="AQAB",n="FbSKW1aDqUZw4jtXGPgU+g4T+FA49QcRGCy6YVEFgfPSLH4jLvk34i5VHWi4bi+MsarYvi5Ij13379J54/Vo1Orzb4DPcUGs5g/MkRP7bEqEH9ULvHxRL/y+/yFIeqgR6zyoxiAFNGqG3oa/odipSP0/NIwi6q3zM8PObOEyCP0=",r="Ab8B0hbXNZXPAnDCvreNQKDYRH0x2pGamD9+6ngbd9hf43Gz6Tc+e2khfTFQoC2JWN5/rZ1VUWCVi0RUEn4Ofq8=",i="AY0zmWWBZts4KYFteylUFnWenJGYf1stiuzWOwS0i9ey/PIpu3+KbciLoT3S45rVW20aBhYHCPlwC+gLj9N0TOc=",s="BsCiSdIKby7nXIi0lNU/aq6ZqkJ8iMKLFjp2lEXl85DPQMJ0/W6mMppc58fOA6IVg5buKnhFeG4J4ohalyjk5Q==",o="0dJ8Kf7dkthsNI7dDMv6wU90bgUc4dGBHfNdYfLuHJfUvygEgC9kJxh7qOkKivRCQ7QHmwNEXmAuKfpRk+ZP6Q==",u="jLL3Vr2JQbHTt3DlrTHuNzsorNpp/5tvQP5Xi58a+4WDb5Yn03rP9zwneeY0uyYBHCyPfzNhriqepl7WieNjmg==",a=c(e,t),l=h(e,t,n,r,i,s,o,u),p=[{title:"RSAES-OAEP Encryption Example 3.1",message:"CHggtWno+o0=",seed:"jO1rGWKQgFeQ6QkHQBXmogsMSJSM7WsZYpCAV5DpCQc=",encrypted:"AJqBCgTJGSHjv2OR0lObiDY2gZmWdutHfVeadCdFr2W4mS3ZHwet283wbtY/bsM8w0rVxNAPh3NZNrcRt56NhoT0NzD2IK3WNy39Im/CfbicvC6Vq2PyXUh1iza+90PUM3jECPP5NsOx658MzEnYyFZFb9izZIna6YLsXwkWoHVO"},{title:"RSAES-OAEP Encryption Example 3.2",message:"RlOsrxcZYLAfUqe+Y6OrIdw2jsQ7UNguw3geBA==",seed:"tCkdZWdVCEjMFWlnyAm6q2ylB/C0KR1lZ1UISMwVaWc=",encrypted:"ARCj8j/hSsscyXtuINlyU0HuC+d7wZc7bSekF60BJFWKeKa1p28d4KsJXmdqI22sxha7PgkI9bgpfgdBd8KHp12g5y68uXiwRyPOvv8s6YDKmJFhbW13LHbE3iZHch2YG1eHi/20M/IrsAqCuk/W5Q/dP5eSVM1hLT9LBVsX3rIH"},{title:"RSAES-OAEP Encryption Example 3.3",message:"2UzQ4I+kBO2J",seed:"zoko9gWVWCVACLrdl5T63NL9H2XOiSj2BZVYJUAIut0=",encrypted:"Anfa/o/QML7UxLCHcSUWFPUWhcp955u97b5wLqXuLnWqoeQ3POhwasFh3/ow2lkzjjIdU47jkYJEk6A0dNgYiBuDg57/KN5yS2Px/QOSV+2nYEzPgSUHGyZacrHVkj/ZVyZ+ni7Iyf/QkNTfvPGxqmZtX6cq095jgdG1ELgYsTdr"},{title:"RSAES-OAEP Encryption Example 3.4",message:"bMZBtrYeb5Y5dNrSOpATKE7x",seed:"bil59S1oFKV9g7CQBUiI8RmluaNuKXn1LWgUpX2DsJA=",encrypted:"AalUnNYX91mP0FrqphpfhU22832WgnjDNRU1pkpSrd5eD7t7Q1YhYE+pKds6glA8i1AE/li216hJs2IbCJMddyaXrDzT8V9/UfIUaSkLfcRYBrTn9DEDOTjY1Xnn38poLOFykpZbAz5hdbOh0qG39qFgl5QZG0+aTBd1tmlMZBfO"},{title:"RSAES-OAEP Encryption Example 3.5",message:"31FRgyth9PJYkftBcvMo0u3fg3H/z9vpl5OSlfMOymkYAXz9oRU796avh1kyIw==",seed:"LXYL/jjFneNM3IuMeKOOZihKLSctdgv+OMWd40zci4w=",encrypted:"AGgQQYTuy9dW6e3SwV5UFYbEtqQD7TDtxcrMYOmYlTPgTwIFpo4GbQbtgD9BMFAW7a1lIzLxKEld49jH6m95Xgtq/BAVFl/gXin5MMbiZfRTOl38miBTg5a6IS9w6tcrWIBeY5Z5n4iCuUqF9r/m9TqvxWF0aMP2VGVKZn+LHMVj"},{title:"RSAES-OAEP Encryption Example 3.6",message:"PDutiTxUSm1SCrAiMZGIyNUEt6eIuFCQO4WXLqoYVS4RNKetYJiCYlT/erZys9jrMVj6xtTLrvE=",seed:"8XR3nF/Tz+AHuty3o2ybVb/Pvw7xdHecX9PP4Ae63Lc=",encrypted:"Aps8BQrRkPPwpNIjHw3NBznsDvp1hIHmlbG5wRERr9+Ar4ervO2GA/MMUVNijdZEtFnCGjbLwpM6RKzCk96jJX1bIgzq7hnmIzwKmq2Ue4qqO29rQL39jpCS87BBo/YKMbkYsPc2yYSDMBMOe9VDG63pvDgFGrlk/3Yfz1km3+/Y"}],f(a,l,"sha256",p),e="BRJAtswABPpI0BNGccB4x8jew7Pi8lvCVkRnM52ziFPQa4XupbLeNTv/QqwuRryX+uaslhjalTelyPVTweNXYlmR1hCNzXiF+zolQT9T78rZSMs1zZua6cHGdibRE9V93kxb6na7W7felsANBzculoWm11z50jn6FI1wkxtfP7A5",t="AQAB",n="BBH/yjt8penpvn/jioUQXjU4ltsFxXlq7NKnJRYes2UchimpuGK5BNewx7N/jLWhwrVAAQGKAKHrLK/k7k6UksNIvCvtq0ueu/Bk6O/zIrkAn47sZTkF9A34ijzcSdRWf3VifUGspiQSm0agt8aY5eZfK3uhAsdJoQE1tlQNBAE=",r="AnRYwZ7BY2kZ5zbJryXWCaUbj1YdGca/aUPdHuGriko/IyEAvUC4jezGuiNVSLbveSoRyd6CPQp5IscJW266VwE=",i="AhDumzOrYXFuJ9JRvUZfSzWhojLi2gCQHClL8iNQzkkNCZ9kK1N1YS22O6HyA4ZJK/BNNLPCK865CdE0QbU7UTk=",s="OfoCi4JuiMESG3UKiyQvqaNcW2a9/R+mN9PMSKhKT0V6GU53J+Sfe8xuWlpBJlf8RwxzIuvDdBbvRYwweowJAQ==",o="AV2ZqEGVlDl5+p4b4sPBtp9DL0b9A+R9W++7v9ax0Tcdg++zMKPgIJQrL+0RXl0CviT9kskBnRzs1t1M8eVMyJk=",u="AfC3AVFws/XkIiO6MDAcQabYfLtw4wy308Z9JUc9sfbL8D4/kSbj6XloJ5qGWywrQmUkz8UqaD0x7TDrmEvkEro=",a=c(e,t),l=h(e,t,n,r,i,s,o,u),p=[{title:"RSAES-OAEP Encryption Example 4.1",message:"SoZglTTuQ0psvKP36WLnbUVeMmTBn2Bfbl/2E3xlxW1/s0TNUryTN089FmyfDG+cUGutGTMJctI=",seed:"HKwZzpk971X5ggP2hSiWyVzMofMcrBnOmT3vVfmCA/Y=",encrypted:"AooWJVOiXRikAgxb8XW7nkDMKIcrCgZNTV0sY352+QatjTq4go6/DtieHvIgUgb/QYBYlOPOZkdiMWXtOFdapIMRFraGeq4mKhEVmSM8G5mpVgc62nVR0jX49AXeuw7kMGxnKTV4whJanPYYQRoOb0L4Mf+8uJ5QdqBE03Ohupsp"},{title:"RSAES-OAEP Encryption Example 4.3",message:"v21C5wFwex0CBrDItFoccmQf8SiJIZqCveqWW155qWsNAWPtnVeOya2iDy+88eo8QInYNBm6gbDGDzYG2pk=",seed:"rZl/7vcw1up75g0NxS5y6sv90nWtmX/u9zDW6nvmDQ0=",encrypted:"AtYYko32Vmzn3ZtrsDQH9Mw/cSQk9pePdwQZJ6my7gYXWYpBdhbEN/fH7LMmvjtHnKLLTDazfF1HT0tTG6E+TY002cy+fMUvdRn0rfmFkNeHeqVOABP2EmI4eXFCBbbIlpshLxbA3vDTzPPZZqwMN+KPG4O11wmS9DcyHYtpsIOU"},{title:"RSAES-OAEP Encryption Example 4.4",message:"+y7xEvXnZuuUAZKXk0eU974vb8HFjg==",seed:"E2RU31cw9zyAen5A2MGjEqxbndMTZFTfVzD3PIB6fkA=",encrypted:"AZX8z/njjTP/ApNNF+BNGUjlczSK/7iKULnZhiAKo4LJ0XaTzTtvL9jacr+OkRxSPUCpQeK36wXdi9qjsl3SO9D7APyzN1nNE5Nu5YstiAfEMVNpdRYGdgpUasEZ4jshBRGXYW28uTMcFWRtzrlol9Lc7IhIkldTXZsR9zg11KFn"},{title:"RSAES-OAEP Encryption Example 4.5",message:"KMzUR7uehRZtq7nlt9GtrcS5058gTpbV5EDOmtkovBwihA==",seed:"vKgFf4JLLqJX8oYUB+72PTMghoG8qAV/gksuolfyhhQ=",encrypted:"A8GIo5X2qOS6MdKjYJg+h3hi2endxxeb3F5A8v+MbC7/8WbBJnzOvKLb6YMukOfAqutJiGGzdPQM9fopdhbRwS/Ovw4ksvmNBVM+Q26CFPqvdhV8P0WxmeYTxGFGrLgma+fwxpe7L6mj300Jq6Y/5kfTEJSXNdKuLRn0JsIg8LSD"},{title:"RSAES-OAEP Encryption Example 4.6",message:"8iJCdR7GsQ==",seed:"Ln4eF/ZHtd3QM+FUcvkPaBLzrE4ufh4X9ke13dAz4VQ=",encrypted:"AM9cnO14EVBadGQYTnkkbm/vYwqmnYvnAutrc4bZR3XC0DNhhuUlzFosUSmaC1LrjKcFfcqZOwzlev5uZycR7tUlLihC6lf4o0khAjUb03Dj+ubNsDKNCOA6vP63N3p6jSVIak7EPu0KtBLuNpIyW5mdkMuwssV7CNLOQ6qG7zxZ"}],f(a,l,"sha256",p),e="Cq3z+cEl5diR8xrESOmT3v5YD4ArRfnX8iulAh6cR1drWh5oAxup205tq+TZah1vPSZyaM/0CABfEY78rbmYiNHCNEZxZrKiuEmgWoicBgrA2gxfrotV8wm6YucDdC+gMm8tELARAhSJ/0l3cBkNiV/Tn1IpPDnv1zppi9q58Q7Z",t="AQAB",n="AlbrTLpwZ/LSvlQNzf9FgqNrfTHRyQmbshS3mEhGaiaPgPWKSawEwONkiTSgIGwEU3wZsjZkOmCCcyFE33X6IXWI95RoK+iRaCdtxybFwMvbhNMbvybQpDr0lXF/fVKKz+40FWH2/zyuBcV4+EcNloL5wNBy+fYGi1bViA9oK+LF",r="A7DTli9tF1Scv8oRKUNI3PDn45+MK8aCTyFktgbWh4YNrh5jI5PP7fUTIoIpBp4vYOSs1+YzpDYGP4I4X0iZNwc=",i="AuTDLi9Rcmm3ByMJ8AwOMTZffOKLI2uCkS3yOavzlXLPDtYEsCmC5TVkxS1qBTl95cBSov3cFB73GJg2NGrrMx8=",s="AehLEZ0lFh+mewAlalvZtkXSsjLssFsBUYACmohiKtw/CbOurN5hYat83iLCrSbneX31TgcsvTsmc4ALPkM429U=",o="65CqGkATW0zqBxl87ciBm+Hny/8lR2YhFvRlpKn0h6sS87pP7xOCImWmUpfZi3ve2TcuP/6Bo4s+lgD+0FV1Tw==",u="AS9/gTj5QEBi64WkKSRSCzj1u4hqAZb0i7jc6mD9kswCfxjngVijSlxdX4YKD2wEBxp9ATEsBlBi8etIt50cg8s=",a=c(e,t),l=h(e,t,n,r,i,s,o,u),p=[{title:"RSAES-OAEP Encryption Example 5.1",message:"r3GpAeOmHTEy8Pwf20dPnqZXklf/wk0WQXAUWz296A==",seed:"RMkuKD93uUmcYD2WNmDIfS+TlGFEyS4oP3e5SZxgPZY=",encrypted:"BOGyBDRo+2G7OC79yDEzJwwLMPuhIduDVaaBdb5svHj/ZAkVlyGVnH0j+ECliT42Nhvp4kZts+9cJ0W+ui7Q9KXbjmX033MpxrvSV1Ik//kHhX6xTn51UGpaOTiqofjM3QTTi9DVzRtAarWd/c8oAldrGok1vs+tJEDbcA5KvZz7"},{title:"RSAES-OAEP Encryption Example 5.2",message:"o7hEoII5qKxBYFrxemz9pNNQE2WFkDpBenkmh2BRmktKwzA+xz8Ph8+zI5k=",seed:"yyj1hgZZ/O7knD7q/OYlpwgDvTLLKPWGBln87uScPuo=",encrypted:"AeleoSbRCOqBTpyWGLCrZ2G3mfjCYzMvupBy+q+sOKAfBzaLCjCehEUmIZFhe+CvtmVvyKGFqOwHUWgvks9vFU7Gfi580aZm7d4FtaGGVHBO6Q32/6IS7a+KSk7L6rPWwBTI+kyxb5SW12HTEowheKkFTda06tU0l4Ji45xP2tyh"},{title:"RSAES-OAEP Encryption Example 5.3",message:"MIsOy9LHbLd/xvcMXt0jP9LyCSnWKfAmlTu2Ko9KOjFL3hld6FtfgW2iqrB00my2rN3zI647nGeKw88S+93n",seed:"IoX0DXcEgvmp76LHLLOsVXFtwMoihfQNdwSC+anvosc=",encrypted:"Ci3TBMV4P0o59ap6Wztb9LQHfJzYSOAaYaiXjk85Q9FYhAREaeS5YXhegKbbphMIS5i1SYJShmwpYu/t8SGHiX/72v6NnRgafDKzttROuF/HJoFkTBKH6C9NKke+mxoDy/YVZ9qYzFY6PwzB4pTDwku9s5Ha4DmRBlFdA/z713a4"},{title:"RSAES-OAEP Encryption Example 5.4",message:"FcW57hGF",seed:"SfpF06eN0Q39V3OZ0esAr37tVRNJ+kXTp43RDf1Xc5k=",encrypted:"AcMQiclY0MMdT9K4kPqZ7JYHTaSolc8B3huHcQ4U5mG11/9XjzWjTLha8Liy0w909aaPbaB7+ZQTebg7x3F4yeWFRmnAJMaIFGBW/oA952mEaJ+FR2HO0xfRPzCRCaaU7cyOxy0gnR8d9FMunt9fhbffM9TvOfR6YDE5Duz6Jg0W"},{title:"RSAES-OAEP Encryption Example 5.5",message:"IQJuaADH+nKPyqug0ZauKNeirE/9irznlPCYX2DIpnNydzZdP+oR24kjogKa",seed:"8Ch0EyNMxQNHJKCUxFhrh6/xM/zwKHQTI0zFA0ckoJQ=",encrypted:"A/gvyZ/MNHUG3JGcisvAw/h1bhviZsqIsEM5+gBpLfj7d8iq28yZa6z5cnS4cJWywHxyQMgt9BAd37im/f5WcIcB+TZS9uegFSdgaetpYf4ft/1wMlcdc1ReCrTrCKPFHLLczeifyrnJSVvQD84kQY21b4fW9uLbSiGO0Ly94il1"},{title:"RSAES-OAEP Encryption Example 5.6",message:"VB43totsiHK4TAI=",seed:"2fukXJbyHm4m0p6yzctlhb6cs0HZ+6RclvIebibSnrI=",encrypted:"AWmTYpBHOqRBGy1h5mF88hMmBVNLN++kXAqQr4PKszqorigNQZbvwbOdWYNLsXydyvKi55ds8tTvXf4rRBswyuNmbtT0t2FVCTnTjNzA1cMSahInbdKfL/1wib3CjyQmC0TbbIa3kkAdXkiYytSafDxwNyan1OWtJcMLkJ6l8WRm"}],f(a,l,"sha256",p),e="ErF/ba0uzRn/RtwT94YPCeDgz7Z3s4pSWSMFzq8CLBZtuQ0ErCnjP33RLZ+vZuCBa7Y+rSZ8x9RsF8N74hS8oqItcjpk5EQHQ2tvyWVymu/CVU83bNXc6mgpN4CmK/OdAClIWhYLu55dwJctIaUE9S5e4CiqQWMy9RCy6c/19yKv",t="AQAB",n="ApXso1YGGDaVWc7NMDqpz9r8HZ8GlZ33X/75KaqJaWG80ZDcaZftp/WWPnJNB7TcEfMGXlrpfZaDURIoC5CEuxTyoh69ToidQbnEEy7BlW/KuLsv7QV1iEk2Uixf99MyYZBIJOfK3uTguzctJFfPeOK9EoYij/g/EHMc5jyQz/P5",r="BKbOi3NY36ab3PdCYXAFr7U4X186WKJO90oiqMBct8w469TMnZqdeJpizQ9g8MuUHTQjyWku+k/jrf8pDEdJo4s=",i="BATJqAM3H+20xb4588ALAJ5eCKY74eQANc2spQEcxwHPfuvLmfD/4Xz9Ckv3vv0t1TaslG23l/28Sr6PKTSbke0=",s="A5Ycj3YKor1RVMeq/XciWzus0BOa57WUjqMxH8zYb7lcda+nZyhLmy3lWVcvFdjQRMfrg6G+X63yzDd8DYR1KUs=",o="AiGX4GZ0IZaqvAP6L+605wsVy3h9YXrNMbt1x7wjStcG98SNIYLR8P+cIo3PQZZ7bAum0sCtEQobhXgx7CReLLE=",u="BAHEwMU9RdvbXp2W0P7PQnXfCXS8Sgc2tKdMMmkFPvtoas4kBuIsngWN20rlQGJ64v2wgmHo5+S8vJlNqvowXEU=",a=c(e,t),l=h(e,t,n,r,i,s,o,u),p=[{title:"RSAES-OAEP Encryption Example 6.1",message:"QEbKi6ozR8on9J4NgfnMHXG+m6UX1A==",seed:"3Q9s/kFeiOWkaaUfu6bf1ArbQ4TdD2z+QV6I5aRppR8=",encrypted:"C3d3hdR81ybq+Wuf6QUfy2KHVuQjrsvVH2HuE2LbJT2o2ZPdrDHIoGphdGj+GWNTrcV/d8iPLJlZ0CR3O2e2b7wLUVPMorv1HidYA8B8eJxkg5FIsPuK836LchnGqQlE7ObiWOjSuIw4lZ/ULCfOYejelr6PJXSxWgQUlV78sbvP"},{title:"RSAES-OAEP Encryption Example 6.2",message:"XMcsYCMd8Ds9QPm1eTG8MRCflyUn8osZ50gMcojLPJKyJRIhTkvmyRR5Ldq99X+qiqc=",seed:"jRS9lGoTURSPXK4u2aDGU+hevYWNFL2UahNRFI9cri4=",encrypted:"DXAHBh/uWFjxl/kIwrzm0MXeHNH5MSmoPc0mjn00UcCUFmOwTQipPmLmephH+rNOOfCQVvwP5wysU3/w2hjmk/rl6Jb4qNc+KqDiij7fKSKhPGTvY3aiXZ2LflnJ3yv4LdT9KvvWsZrHEWfsEG+fQZW4c1OMEpOMC4N44nc88yRm"},{title:"RSAES-OAEP Encryption Example 6.3",message:"sg5lEwMJL0vMtDBwwPhtIwSTYu2WZC/FYywn20pS49gx8qsGiyOxSYecAC9r8/7ul1kRElYs",seed:"bAdbxFUg8WXAv16kxd8ZG8nvDkRsB1vEVSDxZcC/XqQ=",encrypted:"AMe1ZPYbk4lABLKDLhwJMM4AfK46Jyilp/vQ9M921AamJzanoNGdlj6ZEFkbIO68hc/Wp4Qr43iWtjcasgpLw2NS0vroRi91VI5k9BZgXtgNG7Z9FBOtPjM61Um2PWSFpAyfaZS7zoJlfRKciEa+XUKa4VGly4fYSXXAbUJV2YHc"},{title:"RSAES-OAEP Encryption Example 6.4",message:"aE4wOMXAQfc=",seed:"O7w71mN9/hKEaQECm/WwwHEDQ5w7vDvWY33+EoRpAQI=",encrypted:"AJS/vpVJKJuLwnnzENVQChT5MCBa0mLxw/a9nt+6Zj4FL8nucIl7scjXSOkwBDPcyCWr7gqdtjjZ9z6RCQv0HfjmVKI2M6AxI2MYuzwftIQldbhCRqo8AlyK3XKjfcK+Rzvii53W8Xw4Obbsv9OCLnCrrbK8aO3XKgrHPmDthH7x"},{title:"RSAES-OAEP Encryption Example 6.5",message:"MkiMsmLQQdbk3TX5h788ppbbHwasKaRGkw==",seed:"tGtBiT6L7zJvZ1k4OoMHHa5/yry0a0GJPovvMm9nWTg=",encrypted:"CmNUKnNQco5hWHxCISdwN5M7LbL7YJ0u7bfH82LulE32VdATd3vcJmRiFtcczNNudMlHVhl6/ZsDVY1zymLrK2kLIYWeG9Iag3rQ5xhjLAdpMYBBuwjrJ8Oqc4+2qH57bBveynuE5xRpd9p+CkkiRP7x7g4B/iAwrmFxPtrxV/q/"},{title:"RSAES-OAEP Encryption Example 6.6",message:"ULoUvoRicgJ5wwa6",seed:"CiQDMSpB49UvBg+8E6Z95c92CacKJAMxKkHj1S8GD7w=",encrypted:"DpQAu4uQ4zbkpP/f698+a5f3MhAXCi3QTcP7vXmQVlkH0CFlCnDESNG36Jk2ybe3VmzE2deBHBKI9a5cHUzM9Lsa/AoxnbD5qd2fJt9k19dSRtDWZUR/Bn/AdVHwstzsX/vRLe6qOk9Kf01OZcvKrmlWh2IBLs8/6sEJhBWXNAKj"}],f(a,l,"sha256",p),e="MRF58Lz8m508oxXQDvMNe906LPrpkRv+3LlIs6R4LQcytqtEqkvwN0GmRNwBvsPmmwGgM+Z12KzXxJJcaxrsMRkFHf2Jdi0hXUVHX/y1n5CBSGI/NxdxVvauht16fF9D3B4fkIJUBYooSl8GwAIXk6h/GsX+/33K7mnF5Ro3ieNz",t="AQAB",n="Bwz8/y/rgnbidDLEXf7kj0m3kX1lMOHwyjRg8y4CdhdEh8VuIqRdJQDXd1SVIZ19Flqc872Swyr5qY2NycwpaACtyUoKVPtA80KRv4TujqErbxCTWcbTVCpQ+cdn9c//BaaBwuZW+3fKqttL6UaNirzU35j1jobSBT+hNJ90jiGx",r="B0kmLBEc1HDsJWbms3MvwJMpRpqhkHHTucAZBlFMbx0muqFL6rCXHIt+YRpPeQCdb+p3aSjKJShbDeNkPRo/jHE=",i="BrweUOlsAr9jbp7qi4mbvr92Ud533UdMPpvCO62BgrYZBMfZffvr+x4AEIh4tuZ+QVOR1nlCwrK/m0Q1+IsMsCM=",s="A7x+p/CqsUOrxs6LlxGGNqMBcuTP4CyPoN2jt7qvkPgJKYKYVSX0iL38tL1ybiJjmsZKMJKrf/y/HVM0z6ULW/E=",o="AmKmqinCo8Z9xTRsBjga/Zh6o8yTz7/s9U/dn514fX9ZpSPTmJedoTei9jgf6UgB98lNohUY3DTLQIcMRpeZStk=",u="ZJ1MF7buFyHnctA4mlWcPTzflVDUV8RrA3t0ZBsdUhZq+KITyDliBs37pEIvGNb2Hby10hTJcb9IKuuXanNwwg==",a=c(e,t),l=h(e,t,n,r,i,s,o,u),p=[{title:"RSAES-OAEP Encryption Example 7.1",message:"R6rpCQ==",seed:"Q90JoH/0ysccqkYy7l4cHa7kzY9D3Qmgf/TKxxyqRjI=",encrypted:"CdXefX8LEW8SqnT1ly7/dvScQdke1rrSIBF4NcFO/G+jg0u7yjsqLLfTa8voI44Ue3W6lVuj5SkVYaP9i7VPmCWA4nFfeleuy23gbHylm4gokcCmzcAm2RLfPQYPnxIb3hoQ2C3wXo/aWoLIMFPYzI19g5uY90XMEchAci3FVC/a"},{title:"RSAES-OAEP Encryption Example 7.2",message:"HZsuIiPZvBO/ufFiznNdtIunxo9oIqChp7auFlg05w==",seed:"Opw87HuE+b063svGc+yZ1UsivJs6nDzse4T5vTrey8Y=",encrypted:"DDar5/aikhAVropPgT3SVzSMRtdS9sEmVBEqg9my/3na0Okz51EcAy436TOZVsM0exezvKYsVbDQhtOM0Mn9r6oyBsqzUR4lx6Gt2rYDYC4X1aMsJSVcQs9pDqeAWfIAmDIIQH/3IN2uJ6u4Xl2+gFCpp8RP0F//Rj2llnEsnRsl"},{title:"RSAES-OAEP Encryption Example 7.3",message:"2Xb8",seed:"dqdeW2FXpVbPiIS7LkXCk91UXPV2p15bYVelVs+IhLs=",encrypted:"GpTkYrRFNyD9Jw1Pc1TSPSfc9Yb8k4Fw1l4kCwqPodlAboKMJe+yuXoGgVeB7Jb7JTQklGpQc1keZUzUUVZO0Q4qYUelFFe5lWM2uhq21VCbvcchrMTP6Wjts05hVgJHklLKF5cOtBGpQC0FlkwCYoXUAk//wejNycM/ZXw+ozkB"},{title:"RSAES-OAEP Encryption Example 7.4",message:"1HOGI98iOqQ4Q9+EZ1NMQdAT4MgDxiTiY2ZrI5veQKXymuuN5549qmHdA3D0m9SwE4NLmCEq72scXuNzs8s=",seed:"eGYxSmrW8rJQo1lB2yj1hktYWFl4ZjFKatbyslCjWUE=",encrypted:"G5GJEPP4ifUCg+3OHEq41DFvaucXwgdSGyuDX6/yQ1+e30d0OIjIFv4JTUXv6Oi8/uADg+EN5Ug+lEyf0RNSS4wfKgRfAaXK6x1U8dh48g/bED27ZCZ+MjhAkUcjMO0h4m3nNfLxAju7nxO2cJzNI9n1TBCMngJBco0zzhOvMZaN"},{title:"RSAES-OAEP Encryption Example 7.5",message:"u0cjHKXqHTrUbJk0XZqKYQ==",seed:"shZu1HLVjbEMqyxrAAzM8Qp9xQmyFm7UctWNsQyrLGs=",encrypted:"HebBc/6i18c2FbG7ibWuxyQgtiN1uhtxyNsXw1Kuz8zo7RkBkt5JZEwucKyXFSwI6drZlK6QaqCRZwPQsdc2wnZlQzbkilVf1TiACqzDdpKX5i+SbCTUsOyGETV3vtxFe7/SatEKseFSLEWkIfZxAFcisIs5hWmLJdqfWQeYuMrK"},{title:"RSAES-OAEP Encryption Example 7.6",message:"IYSCcJXTXD+G9gDo5ZdUATKW",seed:"Umc73iyhZsKqRhMawdyAjWfX07FSZzveLKFmwqpGExo=",encrypted:"DX+W3vsdnJfe63BVUFYgCAG1VmTqG/DbQ4nZgWTUGHhuijUshLtz07dHar21GJ9Ory8QQPX67PgKGnBMp0fJBnqKO3boMOEcc52HEnQxOWIW2h2rgmDtnaYtvK85pddXzhbuXkXg4DDnoMy+4XzgbLfArK12deGB0wruBbQyv3Ar"}],f(a,l,"sha256",p),e="W98OMNMh3aUUf4gkCPppGVSA34+A0/bov1gYUE82QnypsfVUC5xlqPaXTPhEeiRNkoAgG7Sfy75jeNGUTNIn4jD5bj0Q+Bnc7ydsZKALKktnAefQHeX6veOx6aDfgvRjE1nNImaWR/uxcXJGE07XtJfP/73EK1nHOpbtkBZiEt/3",t="AQAB",n="D30enlqqJf0T5KBmOuFE4NFfXNGLzbCd8sx+ZOPF6RWtYmRTBBYdCYxxW7eri9AdB+rz/tfH7QivKopi70SrFrMg4Ur3Kkj5av4mKgrkz2XmNekQeQzU7lzqdopLJjn35vZ3s/C7a+MrdXR9iQkDbwJk9Y1AHNuhMXFhV6dez2Mx",r="CgLvhEjZ+ti70NAEyMKql1HvlyHBsNAyNqVLDflHy67VolXuno4g1JHqFyP+CUcEqXYuiK/RbrtZlEEsqWbcT58=",i="CS02Ln7ToL/Z6f0ObAMBtt8pFZz1DMg7mwz01u6nGmHgArRuCuny3mLSW110UtSYuByaxvxYWT1MP7T11y37sKk=",s="B8cUEK8QOWLbNnQE43roULqk6cKd2SFFgVKUpnx9HG3tJjqgMKm2M65QMD4UA10a8BQSPrpoeCAwjY68hbaVfX0=",o="rix1OAwCwBatBYkbMwHeiB8orhFxGCtrLIO+p8UV7KnKKYx7HKtYF6WXBo/IUGDeTaigFjeKrkPH+We8w3kEuQ==",u="BZjRBZ462k9jIHUsCdgF/30fGuDQF67u6c76DX3X/3deRLV4Mi9kBdYhHaGVGWZqqH/cTNjIj2tuPWfpYdy7o9A=",a=c(e,t),l=h(e,t,n,r,i,s,o,u),p=[{title:"RSAES-OAEP Encryption Example 8.1",message:"BQt1Xl5ogPe56daSp0w3quRJsxv+pt7/g3R6iX9sLIJbsa2/hQo8lplLXeWzPLx9SheROnln",seed:"dwb/yh7PsevuKlXlxuJM0nl6QSV3Bv/KHs+x6+4qVeU=",encrypted:"DZZvGJ61GU6OOkaPl2t8iLNAB1VwLjl3RKd/tcu19Vz9j68fjCFBQvASq9FK6Sul/N6sXIVsi4ypx/1m77bErYJqiGwkE8sQz/g4ViwQmeCvpfbCoq00B5LxklezvhnM5OeSxFtO/8AtYimLrJ3sUmDYk7xkDI20/Lb8/pyOFsjH"},{title:"RSAES-OAEP Encryption Example 8.2",message:"TraNzZPKmxnfERvUNgj1VwJv5KodXPrCJ6PrWrlUjBigbd7SP4GCWYay/NcRCezvfv+Ihz8HXCqgxGn2nJK8",seed:"o3F9oUO03P+8dCZlqPqVBYVUg0OjcX2hQ7Tc/7x0JmU=",encrypted:"DwsnkHG2jNLgSU4LEvbkOuSaQ9+br9t3dwen8KDGmLkKVJgWGu+TNxyyo2gsBCw7S4eqEFrl49ENEhMehdjrHCBLrEBrhbHxgncKrwIXmcjX1DOCrQXEfbT4keig8TaXkasow5qby9Ded6MWcLu1dZnXPfiuiXaOYajMGJ1D3/y7"},{title:"RSAES-OAEP Encryption Example 8.3",message:"hgSsVjKMGrWtkXhh",seed:"7gYgkHPMoCa7Jk5Rhb+MaLdzn4buBiCQc8ygJrsmTlE=",encrypted:"PAKF3K/lSKcZKWQDr56LmmVqSltcaKEfS7G6+rwG239qszt8eKG6fMYJsP4h7ZfXyV1zuIZXTVhXgiRQbA9os0AhkWiMJJouhsAn60R20BOLQOtQxlXxVOvUMPGuG5EP2O+nTI0VCXky5kHNJdfJolSW+pJLVdSu4mX9Ooga1CSx"},{title:"RSAES-OAEP Encryption Example 8.4",message:"/dpfv27DYanZpKxoryFqBob0OLHg5cNrlV904QfznA3dzA==",seed:"mQrVc9xIqXMjW22CVDYY8ulVEF2ZCtVz3EipcyNbbYI=",encrypted:"LcCLDDj2S5ZOKwpvobOk6rfBWMBbxs3eWR+Edk3lKaoEAFFD5sQv0AaIs3r7yI8sOir9HvS6GKf+jc9t31zIDCIJc3sKVyrNZfEeUFSvihjbPZDo6IaZ8Jau8woE2p1z7n9rG+cbMwKuILRPSEN4hE0QSA/qz0wcye6bjb6NbK20"},{title:"RSAES-OAEP Encryption Example 8.5",message:"Sl9JFL7iXePGk0HeBw==",seed:"7MY7KPB1byL1Ksjm7BJRpuwwRxjsxjso8HVvIvUqyOY=",encrypted:"U+PBTMw6peNHnFQ3pwix/KvVeWu1nSKQGcr9QPpYNgHhuFZK6ARR7XhKxFtDoUMP+iVTXprcow4lr1Uaw4PnEx+cPe0Khl15R8GLiuh5Vm9p3lTPW1u58iP2Oa81pQZTB5AuFiD0fnFZsl+BYfjDVah3cMIu83KOBRPOdLY0j8iq"},{title:"RSAES-OAEP Encryption Example 8.6",message:"jgfWb3uICnJWOrzT81CSvDNAn7f4jyRyvg==",seed:"OSXHGzYtQKCm3kIUVXm6Hn3UWfw5JccbNi1AoKbeQhQ=",encrypted:"WK9hbyje7E0PLeXtWaJxqD4cFkdL5x4vawlKJSOO1OKyZ6uaY8vMYBhBO47xRIqtab5Ul5UGCwdvwPR69PpARsiiSfJHVavkihXixHGgZViGTMU/7J7ftSiNT9hAwrj4JL4f1+8RhTp6WKRzsXAEKpvLK0TrzQL3ioF3QtTsiu/a"}],f(a,l,"sha256",p),e="zyzUHjTKOnKOpcuK/2TDbSe971Nk4zb9aNMSPFoZaowocBPoU9UVbVjRUZVFIPtPbXsXq7aBd2WQnFdhGWWdkCsZBu2KKxDBVcJNEkUo2rnurjeb6sZuSkEXhty4/QBi68Aw3hIZoEwqjBt90xMeTWtsruLjGl7UGsFQmy7x7iqxg2S+VoypQcJezIT/nWQ7XsGqrhAqINc/R5t4D9bakQdSEtnqwDoGdNiZ66LkMfTES2Fba6IjK9SzO67XPWJd",t="AQAB",n="GYwUHiNxWpK8z2oRmlvBE4lGjSgR9UjXJ+F7SrDrmG1vIR77U7cffMvqh+5px17mFQCMUzLetSvzkKvfv+N9cgU2gVmyY4wd4ybiHSIlHw+1hIs78VAF0qdDMPCv6RbuYszBNE0dg6cJ5gZ2JzhA9/N3QkpeCk2nXwGzH/doGc+cv90hUkPDkXwD7zgZkxLlZ7O/eu06tFfzce+KFCP0W2jG4oLsERu6KDO5h/1p+tg7wbjGE8Xh6hbBHtEl6n7B",r="/I1sBL7E65qBksp5AMvlNuLotRnezzOyRZeYxpCd9PF2230jGQ/HK4hlpxiviV8bzZFFKYAnQjtgXnCkfPWDkKjD6I/IxI6LMuPaIQ374+iB6lZ0tqNIwh6T+eVepl79",i="0gDUXniKrOpgakAdBGD4fdXBAn4S3BoNdYbok52c94m0D1GsBEKWHefSHMIeBcgxVcHyqpGTOHz9+VbLSNFTuicEBvm7ulN9SYfZ4vmULXoUy//+p0/s3ako0j4ln17h",s="2xaAL3mi8NRfNY1p/TPkS4H66ChiLpOlQlPpl9AbB0N1naDoErSqTmyL6rIyjVQxlVpBimf/JqjFyAel2jVOBe8xzIz3WPRjcylQsD4mVyb7lOOdalcqJiRKsI23V1Kt",o="oKMXz+ffFCP4em3uhFH04rSmflSX8ptPHk6DC5+t2UARZwJvVZblo5yXgX4PXxbifhnsmQLgHX6m+5qjx2Cv7h44G2neasnAdYWgatnEugC/dcitL6iYpHnoCuKU/tKh",u="CyHzNcNTNC60TDqiREV4DC1lW5QBdMrjjHyKTmSTwLqf0wN0gmewg7mnpsth5C2zYrjJiW23Bk4CrVrmFYfaFbRknJBZSQn+s328tlS+tyaOyAHlqLSqORG+vYhULwW+",a=c(e,t),l=h(e,t,n,r,i,s,o,u),p=[{title:"RSAES-OAEP Encryption Example 9.1",message:"9zX9VbqSWSw7Urj5xPaaqhy++P6IrdCVWVQSRn+c9OwLiWxZ7aFiEOdUnIq7EM28IaEuyba1uP0vEDmetg==",seed:"jsll8TSj7Jkx6SocoNyBadXqcFyOyWXxNKPsmTHpKhw=",encrypted:"kuBqApUSIPP0yfNvL0I57K2hReD8CcPhiYZFlPPmdM0cVFQHvdPMjQ2GcEekoBMk2+JR2H3IY6QF0JcANECuoepAuEvks/XolStfJNyUVUO3vLbWGlA1JOOSPiWElIdM0hmLN5In0DizqQit7R0mzH3Y1vUGPBhzOnNgNVQgrWVvqJugjG1SPY7LaZxIjhnz3O/8EkCpxLWcyWkFLX+ujnxIKxAqjmvEztiwLLlcWbJKILOy7KE1lctyh58wYP6e"},{title:"RSAES-OAEP Encryption Example 9.2",message:"gbkGYFAVpjqr5C3fEeGXiRL1QEx0dLJtzj7Ugr+WHsyBi/QgxUZZ",seed:"7LG4sl+lDNqwjlYEKGf0r1gm0WzssbiyX6UM2rCOVgQ=",encrypted:"iNEGT/cssEWuXX1C+SWyMK1hhUjRdNz9l8FeCBhftw8I5JUY1EDXPi2hUpESGxbJOjbyricua+QVvfP/UeoPfOxCcpRSoA3DlviB0ExCJTpCb2NSv9qXtw6Z7qEqk2YyQD7mAsGb2/Y3ug3KkKrF68MAxsWFV3tmL2NV2h+yfW6qz1dVAbAIUZeRuLIbaLdY9F7O4yPC68zkaX9NcTg0tOtnAJth9fMAOFX8sVbvKBgeOuVHV1A8HcAbmqkLMIyp"},{title:"RSAES-OAEP Encryption Example 9.3",message:"/TJkKd+biQ4JtUsYuPNPHiQ=",seed:"6JuwMsbOYiy9tTvJRmAU6nf3d8Dom7Ayxs5iLL21O8k=",encrypted:"JiwfWprF58xVjVRR9B9r0mhomwU5IzkxXCZDgYJwYUcacmrz+KRLKMmtCMN7DLA2lOsfK+72mU+RLmhwfAAhBYmLGR8dLLstazb5xzU9wIM9u3jAl5iyyMLSo6wk/3SH0f7vC2bnFtMkhoHsd3VSTpzl5Q+SqX/4Q1JAMGWMMiHdyjCH+WaXNdTrboPEnPVtTcBGthkkYu8r/G0IkBR6OMPCZFgl/J4uiRTGCRbZx7UC02g6+qNMQY+ksygV6R8w"},{title:"RSAES-OAEP Encryption Example 9.4",message:"8UWbXwyS8BoPcjouVmJITY+MCiD8KdrWrNQ7tfPv/fThtj4H/f5mKNDXTKGb8taeSgq/htKTklp5Z3L4CI4=",seed:"YG87mcC5zNdx6qKeoOTIhPMYnMxgbzuZwLnM13Hqop4=",encrypted:"YXo+2y1QMWzjHkLtCW6DjdJ6fS5qdm+VHALYLFhG/dI1GmOwGOiOrFqesc5KPtWE73N5nJ680e6iYQYdFIsny6a4VH9mq/2Lr6qasMgM27znPzK8l6uQ1pTcDu1fJ4gCJABshzVEXzeTWx6OyKZsOFL8eXiNCwQpyfP9eH0tRjc+F75H3dnzX6AEVff4t0yKjDqp7aRMxFZGidcMJ6KetiNXUg1dhs/lHzItdQ7oMSUAgMnHYAvJDGqy5L4F8XXM"},{title:"RSAES-OAEP Encryption Example 9.5",message:"U+boxynW+cMZ3TF+dLDbjkzMol88gwV0bhN6xjpj7zc557WVq7lujVXlT3vUGrQzN4/7kR0=",seed:"/LxCFALp7KvGCCr6QLpfJlIshA78vEIUAunsq8YIKvo=",encrypted:"fwY+yhF2kyhotPKPlHEXcTOqVRG8Kg9bDJE/cSPUOoyVoiV0j57o9xpEYtZBuM5RanPUsTDcYNvorKqP5mbN81JV3SmEkIRTL7JoHGpJAMDHFjXBfpAwgUCPhfJ2+CUCIyOoPZqlt4w+K9l+WeFZYDatr0HC1NO+stbvWq358HRdX27TexTocG5OEB4l9gqhnUYD2JHNlGidsm0vzFQJoIMaH26x9Kgosg6tZQ0t3jdoeLbTCSxOMM9dDQjjK447"},{title:"RSAES-OAEP Encryption Example 9.6",message:"trKOohmNDBAIvGQ=",seed:"I6reDh4Iu5uaeNIwKlL5whsuG6Ijqt4OHgi7m5p40jA=",encrypted:"PISd/61VECapJ7gfG4J2OroSl69kvIZD2uuqmiro3E4pmXfpdOW/q+1WCr574Pjsj/xrIUdgmNMAl8QjciO/nArYi0IFco1tCRLNZqMDGjzZifHIcDNCsvnKg/VRmkPrjXbndebLqMtw7taeVztYq1HKVAoGsdIvLkuhmsK0Iaesp+/8xka40c9hWwcXHsG+I7pevwFarxQQbuUjXSkZ2ObWgzgGSiGCw9QNUGpO0usATLSd0AFkeE+IM/KAwJCy"}],f(a,l,"sha256",p),e="rkXtVgHOxrjMBfgDk1xnTdvg11xMCf15UfxrDK7DE6jfOZcMUYv/ul7Wjz8NfyKkAp1BPxrgfk6+nkF3ziPn9UBLVp5O4b3PPB+wPvETgC1PhV65tRNLWnyAha3K5vovoUF+w3Y74XGwxit2Dt4jwSrZK5gIhMZB9aj6wmva1KAzgaIv4bdUiFCUyCUG1AGaU1ooav6ycbubpZLeGNz2AMKu6uVuAvfPefwUzzvcfNhP67v5UMqQMEsiGaeqBjrvosPBmA5WDNZK/neVhbYQdle5V4V+/eYBCYirfeQX/IjY84TE5ucsP5Q+DDHAxKXMNvh52KOsnX1Zhg6q2muDuw==",t="AQAB",n="BWsEIW/l81SsdyUKS2sMhSWoXFmwvYDFZFCiLV9DjllqMzqodeKR3UP0jLiLnV/A1Jn5/NHDl/mvwHDNnjmMjRnmHbfHQQprJnXfv100W4BNIBrdUC1c4t/LCRzpmXu+vlcwbzg+TViBA/A29+hdGTTRUqMj5KjbRR1vSlsbDxAswVDgL+7iuI3qStTBusyyTYQHLRTh0kpncfdAjuMFZPuG1Dk6NLzwt4hQHRkzA/E6IoSwAfD2Ser3kyjUrFxDCrRBSSCpRg7Rt7xA7GU+h20Jq8UJrkW1JRkBFqDCYQGEgphQnBw786SD5ydAVOFelwdQNumJ9gkygHtSV3UeeQ==",r="7PWuzR5VFf/6y9daKBbG6/SQGM37RjjhhdZqc5a2+AkPgBjH/ZXMNLhX3BfwzGUWuxNGq01YLK2te0EDNSOHtwM40IQEfJ2VObZJYgSz3W6kQkmSB77AH5ZCh/9jNsOYRlgzaEb1bkaGGIHBAjPSF2vxWl6W3ceAvIaKp30852k=",i="vEbEZPxqxMp4Ow6wijyEG3cvfpsvKLq9WIroheGgxh5IWKD7JawpmZDzW+hRZMJZuhF1zdcZJwcTUYSZK2wpt0bdDSyr4UKDX30UjMFhUktKCZRtSLgoRz8c52tstohsNFwD4F9B1RtcOpCj8kBzx9dKT+JdnPIcdZYPP8OGMYM=",s="xzVkVx0A+xXQij3plXpQkV1xJulELaz0K8guhi5Wc/9qAI7U0uN0YX34nxehYLQ7f9qctra3QhhgmBX31FyiY8FZqjLSctEn+vS8jKLXc3jorrGbCtfaPLPeCucxSYD2K21LCoddHfA8G645zNgz72zX4tlSi/CE0flp55Tp9sE=",o="Jlizf235wQML4dtoEX+p2H456itpO35tOi9wlHQT7sYULhj7jfy2rFRdfIagrUj4RXFw8O+ya8SBJsU+/R0WkgGY3CoRB9woLbaoDNMGI2C6P6E/cOQxL/GmzWuPxM2cXD2xfG1qVyEvc64p9hkye61ZsVOFhYW6Tii2CmKkXkk=",u="bzhSazklCFU07z5BWoNu3ouGFYosfL/sywvYNDBP7Gg7qNT0ecQz1DQW5jJpYjzqEAd22Fr/QB0//2EO5lQRzjsTY9Y6lwnu3kJkfOpWFJPVRXCoecGGgs2XcQuWIF7DERfXO182Ij+t1ui6kN18DuYdROFjJR4gx/ZuswURfLg=",a=c(e,t),l=h(e,t,n,r,i,s,o,u),p=[{title:"RSAES-OAEP Encryption Example 10.1",message:"i7pr+CpsD4bV8XVul5VocLCJU7BrTrIFvBaU7g==",seed:"R+GrcRn+5WyV7l6q2G9A0KpjvTNH4atxGf7lbJXuXqo=",encrypted:"iXCnHvFRO1zd7U4HnjDMCLRvnKZj6OVRMZv8VZCAyxdA1T4AUORzxWzAtAAA541iVjEs1n5MIrDkymBDk3cM1oha9XCGsXeazZpW2z2+4aeaM3mv/oz3QYfEGiet415sHNnikAQ9ZmYg2uzBNUOS90h0qRAWFdUV5Tyxo1HZ0slg37Ikvyu2d6tgWRAAjgiAGK7IzlU4muAfQ4GiLpvElfm+0vch7lhlrk7t5TErhEF7RWQe16lVBva7azIxlGyyrqOhYrmQ+6JQpmPnsmEKYpSxTUP2tLzoSH5e+Y0CSaD7ZB20PWILB+7PKRueJ23hlMYmnAgQBePWSUdsljXAgA=="},{title:"RSAES-OAEP Encryption Example 10.2",message:"5q0YHwU7WKkE8kV1EDc+Vw==",seed:"bRf1tMH/rDUdGVv3sJ0J8JpAec9tF/W0wf+sNR0ZW/c=",encrypted:"I3uBbIiYuvEYFA5OtRycm8zxMuuEoZMNRsPspeKZIGhcnQkqH8XEM8iJMeL6ZKA0hJm3jj4z1Xz7ra3tqMyTiw3vGKocjsYdXchK+ar3Atj/jXkdJLeIiqfTBA+orCKoPbrBXLllt4dqkhc3lbq0Z5lTBeh6caklDnmJGIMnxkiG3vON/uVpIR6LMBg+IudMCMOv2f++RpBhhrI8iJOsPbnebdMIrxviVaVxT22GUNehadT8WrHI/qKv+p1rCpD3AAyXAhJy7KKp1l+nPCy1IY1prey+YgBxCAnlHuHv2V7q1FZTRXMJe3iKubLeiX6SfAKU1sivpoqk5ntMSMgAfw=="},{title:"RSAES-OAEP Encryption Example 10.3",message:"UQos9g6Gb6I0BVPJTqOfvCVjEeg+lEVLQSQ=",seed:"OFOHUU3szHx0DdjN+druSaHL/VQ4U4dRTezMfHQN2M0=",encrypted:"n3scq/IYyBWbaN4Xd+mKJ0bZQR10yiSYzdjV1D1K3xiH11Tvhbj59PdRQXflSxE1QMhxN0jp9/tsErIlXqSnBH2XsTX6glPwJmdgXj7gZ1Aj+wsl15PctCcZv0I/4imvBBOSEd5TRmag3oU7gmbpKQCSHi6Hp2z5H/xEHekrRZemX7Dwl6A8tzVhCBpPweKNpe34OLMrHcdyb0k/uyabEHtzoZLpiOgHRjqi7SHr2ene9PPOswH7hc87xkiKtiFOpCeCScF6asFeiUTn5sf5tuPHVGqjKskwxcm/ToW3hm7ChnQdYcPRlnHrMeLBJt6o6xdrg6+SvsnNzctLxes0gA=="},{title:"RSAES-OAEP Encryption Example 10.4",message:"vN0ZDaO30wDfmgbiLKrip18QyR/2Z7fBa96LUwZKJkmpQEXJ",seed:"XKymoPdkFhqWhPhdkrbg7zfKi2VcrKag92QWGpaE+F0=",encrypted:"KWbozLkoxbGfY0Dixr8GE/JD+MDAXIUFzm7K5AYscTvyAh9EDkLfDc/i8Y9Cjz/GXWsrRAlzO9PmLj4rECjbaNdkyzgYUiXSVV0SWmEF62nhZcScf+5QWHgsv6syu2VXdkz9nW4O3LWir2M/HqJ6kmpKVm5o7TqeYZ7GrY25FUnFDM8DpXOZqOImHVAoh8Tim9d2V9lk2D2Av6Tdsa4SIyBDj5VcX3OVoTbqdkKj5It9ANHjXaqGwqEyj7j1cQrRzrbGVbib3qzvoFvGWoo5yzr3D8J8z/UXJ4sBkumcjrphFTDe9qQcJ5FI82ZZsChJssRcZl4ApFosoljixk0WkA=="},{title:"RSAES-OAEP Encryption Example 10.5",message:"p91sfcJLRvndXx6RraTDs9+UfodyMqk=",seed:"lbyp44WYlLPdhp+n7NW7xkAb8+SVvKnjhZiUs92Gn6c=",encrypted:"D7UPhV1nPwixcgg47HSlk/8yDLEDSXxoyo6H7MMopUTYwCmAjtnpWp4oWGg0sACoUlzKpR3PN21a4xru1txalcOkceylsQI9AIFvLhZyS20HbvQeExT9zQGyJaDhygC/6gPifgELk7x5QUqsd+TL/MQdgBZqbLO0skLOqNG3KrTMmN0oeWgxgjMmWnyBH0qkUpV5SlRN2P3nIHd/DZrkDn/qJG0MpXh6AeNHhvSgv8gyDG2Vzdf04OgvZLJTJaTdqHuXz93t7+PQ+QfKOG0wCEf5gOaYpkFarorv9XPLhzuOauN+Dd2IPzgKH5+wjbTZlZzEn+xRyDXK7s6GL/XOZw=="},{title:"RSAES-OAEP Encryption Example 10.6",message:"6vGnOhsMRglTfeac2SKLvPuajKjGw++vBW/kp/RjTtALfDnsaSLXuOosBOus",seed:"n0fd9C6X7qhWqb28cU6zrCL26zKfR930LpfuqFapvbw=",encrypted:"FO6Mv81w3SW/oVGIgdfAbIOW1eK8/UFdwryWg3ek0URFK09jNQtAaxT+66Yn5EJrTWh8fgRn1spnAOUsY5eq7iGpRsPGE86MLNonOvrBIht4Z+IDum55EgmwCrlfyiGe2fX4Xv1ifCQMSHd3OJTujAosVI3vPJaSsbTW6FqOFkM5m9uPqrdd+yhQ942wN4m4d4TG/YPx5gf62fbCRHOfvA5qSpO0XGQ45u+sWBAtOfzxmaYtf7WRAlu+JvIjTp8I2lAfVEuuW9+TJattx9RXN8jaWOBsceLIOfE6bkgad50UX5PyEtapnJOG1j0bh5PZ//oKtIASarB3PwdWM1EQTQ=="}],f(a,l,"sha256",p)}function u(e){var t=i.createBuffer(e),n=t.toHex();return new BigInteger(n,16)}function a(e){var t=i.decode64(e);return u(t)}function f(e,t,n,i){n==="sha1"?n=r.sha1.create():n==="sha256"&&(n=r.sha256.create());for(var s=0;s<i.length;++s){var o=i[s];it("should test "+o.title,function(){l(e,t,n,o.message,o.seed,o.encrypted)})}}function l(t,r,s,o,u,a){var o=i.decode64(o),u=i.decode64(u),f=n.encode_rsa_oaep(t,o,{seed:u,md:s}),l=t.encrypt(f,null);e.equal(a,i.encode64(l));var c=r.decrypt(l,null),h=n.decode_rsa_oaep(r,c,{md:s});e.equal(o,h),l=t.encrypt(o,"RSA-OAEP",{md:s}),h=r.decrypt(l,"RSA-OAEP",{md:s}),e.equal(o,h)}function c(e,n){return e=a(e),n=a(n),t.setRsaPublicKey(e,n)}function h(e,n,r,i,s,o,u,f){return e=a(e),n=a(n),r=a(r),i=a(i),s=a(s),o=a(o),u=a(u),f=a(f),t.setRsaPrivateKey(e,n,r,i,s,o,u,f)}function p(){var e,t,n,r,i,s,o,u,a,f;return e="qLOyhK+OtQs4cDSoYPFGxJGfMYdjzWxVmMiuSBGh4KvEx+CwgtaTpef87Wdc9GaFEncsDLxkp0LGxjD1M8jMcvYq6DPEC/JYQumEu3i9v5fAEH1VvbZi9cTg+rmEXLUUjvc5LdOq/5OuHmtme7PUJHYW1PW6ENTP0ibeiNOfFvs=",t="AQAB",n="UzOc/befyEZqZVxzFqyoXFX9j23YmP2vEZUX709S6P2OJY35P+4YD6DkqylpPNg7FSpVPUrE0YEri5+lrw5/Vf5zBN9BVwkm8zEfFcTWWnMsSDEW7j09LQrzVJrZv3y/t4rYhPhNW+sEck3HNpsx3vN9DPU56c/N095lNynq1dE=",r="0yc35yZ//hNBstXA0VCoG1hvsxMr7S+NUmKGSpy58wrzi+RIWY1BOhcu+4AsIazxwRxSDC8mpHHcrSEurHyjnQ==",i="zIhT0dVNpjD6wAT0cfKBx7iYLYIkpJDtvrM9Pj1cyTxHZXA9HdeRZC8fEWoN2FK+JBmyr3K/6aAw6GCwKItddw==",s="DhK/FxjpzvVZm6HDiC/oBGqQh07vzo8szCDk8nQfsKM6OEiuyckwX77L0tdoGZZ9RnGsxkMeQDeWjbN4eOaVwQ==",o="lSl7D5Wi+mfQBwfWCd/U/AXIna/C721upVvsdx6jM3NNklHnkILs2oZu/vE8RZ4aYxOGt+NUyJn18RLKhdcVgw==",u="T0VsUCSTvcDtKrdWo6btTWc1Kml9QhbpMhKxJ6Y9VBHOb6mNXb79cyY+NygUJ0OBgWbtfdY2h90qjKHS9PvY4Q==",a=c(e,t),f=h(e,t,n,r,i,s,o,u),{publicKey:a,privateKey:f}}it("should detect invalid RSAES-OAEP padding",function(){var t=p(),r=i.decode64("JRTfRpV1WmeyiOr0kFw27sZv0v0="),s=n.encode_rsa_oaep(t.publicKey,"datadatadatadata",{seed:r}),o=t.publicKey.encrypt(s,null),u=o.length*8;u/=8;for(var a=8;a<u;++a){var f=a/8,l=a%8,c=o.substring(0,f),h=1<<l;c+=String.fromCharCode(o.charCodeAt(f)^h),c+=o.substring(f+1);try{var d=t.privateKey.decrypt(c,null);throw n.decode_rsa_oaep(t.privateKey,d),{message:"Expected an exception."}}catch(v){e.equal(v.message,"Invalid RSAES-OAEP padding.")}}}),it("should detect leading zero bytes",function(){var t=p(),r=i.fillString("\0",80),s=n.encode_rsa_oaep(t.publicKey,r),o=t.publicKey.encrypt(s,null),u=t.privateKey.decrypt(o,null),a=n.decode_rsa_oaep(t.privateKey,u);e.equal(r,a)}),s(),o()})}typeof define=="function"?define("test/pkcs1",["forge/pki","forge/pkcs1","forge/md","forge/util"],function(t,n,r,i){e(ASSERT,t(),n(),r(),i())}):typeof module=="object"&&module.exports&&e(require("assert"),require("../../js/pki")(),require("../../js/pkcs1")(),require("../../js/md")(),require("../../js/util")())}(),function(){function e(e,t,n,r){var i={privateKey:"-----BEGIN RSA PRIVATE KEY-----\r\nMIICXQIBAAKBgQDL0EugUiNGMWscLAVM0VoMdhDZEJOqdsUMpx9U0YZI7szokJqQ\r\nNIwokiQ6EonNnWSMlIvy46AhnlRYn+ezeTeU7eMGTkP3VF29vXBo+dLq5e+8VyAy\r\nQ3FzM1wI4ts4hRACF8w6mqygXQ7i/SDu8/rXqRGtvnM+z0MYDdKo80efzwIDAQAB\r\nAoGAIzkGONi5G+JifmXlLJdplom486p3upf4Ce2/7mqfaG9MnkyPSairKD/JXvfh\r\nNNWkkN8DKKDKBcVVElPgORYT0qwrWc7ueLBMUCbRXb1ZyfEulimG0R3kjUh7NYau\r\nDaIkVgfykXGSQMZx8FoaT6L080zd+0emKDDYRrb+/kgJNJECQQDoUZoiC2K/DWNY\r\nh3/ppZ0ane2y4SBmJUHJVMPQ2CEgxsrJTxet668ckNCKaOP/3VFPoWC41f17DvKq\r\nnoYINNntAkEA4JbZBZBVUrQFhHlrpXT4jzqtO2RlKZzEq8qmFZfEErxOT1WMyyCi\r\nlAQ5gUKardo1Kf0omC8Xq/uO9ZYdED55KwJBALs6cJ65UFaq4oLJiQPzLd7yokuE\r\ndcj8g71PLBTW6jPxIiMFNA89nz3FU9wIVp+xbMNhSoMMKqIPVPC+m0Rn260CQQDA\r\nI83fWK/mZWUjBM33a68KumRiH238v8XyQxj7+C8i6D8G2GXvkigFAehAkb7LZZd+\r\nKLuGFyPlWv3fVWHf99KpAkBQFKk3MRMl6IGJZUEFQe4l5whm8LkGU4acSqv9B3xt\r\nqROkCrsFrMPqjuuzEmyHoQZ64r2PLJg7FOuyhBnQUOt4\r\n-----END RSA PRIVATE KEY-----\r\n",publicKey:"-----BEGIN PUBLIC KEY-----\r\nMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDL0EugUiNGMWscLAVM0VoMdhDZ\r\nEJOqdsUMpx9U0YZI7szokJqQNIwokiQ6EonNnWSMlIvy46AhnlRYn+ezeTeU7eMG\r\nTkP3VF29vXBo+dLq5e+8VyAyQ3FzM1wI4ts4hRACF8w6mqygXQ7i/SDu8/rXqRGt\r\nvnM+z0MYDdKo80efzwIDAQAB\r\n-----END PUBLIC KEY-----\r\n",certificate:"-----BEGIN CERTIFICATE-----\r\nMIIDIjCCAougAwIBAgIJANE2aHSbwpaRMA0GCSqGSIb3DQEBBQUAMGoxCzAJBgNV\r\nBAYTAlVTMREwDwYDVQQIEwhWaXJnaW5pYTETMBEGA1UEBxMKQmxhY2tzYnVyZzEN\r\nMAsGA1UEChMEVGVzdDENMAsGA1UECxMEVGVzdDEVMBMGA1UEAxMMbXlzZXJ2ZXIu\r\nY29tMB4XDTEwMDYxOTE3MzYyOFoXDTExMDYxOTE3MzYyOFowajELMAkGA1UEBhMC\r\nVVMxETAPBgNVBAgTCFZpcmdpbmlhMRMwEQYDVQQHEwpCbGFja3NidXJnMQ0wCwYD\r\nVQQKEwRUZXN0MQ0wCwYDVQQLEwRUZXN0MRUwEwYDVQQDEwxteXNlcnZlci5jb20w\r\ngZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMvQS6BSI0YxaxwsBUzRWgx2ENkQ\r\nk6p2xQynH1TRhkjuzOiQmpA0jCiSJDoSic2dZIyUi/LjoCGeVFif57N5N5Tt4wZO\r\nQ/dUXb29cGj50url77xXIDJDcXMzXAji2ziFEAIXzDqarKBdDuL9IO7z+tepEa2+\r\ncz7PQxgN0qjzR5/PAgMBAAGjgc8wgcwwHQYDVR0OBBYEFPV1Y+DHXW6bA/r9sv1y\r\nNJ8jAwMAMIGcBgNVHSMEgZQwgZGAFPV1Y+DHXW6bA/r9sv1yNJ8jAwMAoW6kbDBq\r\nMQswCQYDVQQGEwJVUzERMA8GA1UECBMIVmlyZ2luaWExEzARBgNVBAcTCkJsYWNr\r\nc2J1cmcxDTALBgNVBAoTBFRlc3QxDTALBgNVBAsTBFRlc3QxFTATBgNVBAMTDG15\r\nc2VydmVyLmNvbYIJANE2aHSbwpaRMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEF\r\nBQADgYEARdH2KOlJWTC1CS2y/PAvg4uiM31PXMC1hqSdJlnLM1MY4hRfuf9VyTeX\r\nY6FdybcyDLSxKn9id+g9229ci9/s9PI+QmD5vXd8yZyScLc2JkYB4GC6+9D1+/+x\r\ns2hzMxuK6kzZlP+0l9LGcraMQPGRydjCARZZm4Uegln9rh85XFQ=\r\n-----END CERTIFICATE-----\r\n"};describe("x509",function(){it("should convert certificate to/from PEM",function(){var n=t.certificateFromPem(i.certificate);e.equal(t.certificateToPem(n),i.certificate)}),it("should verify self-signed certificate",function(){var n=t.certificateFromPem(i.certificate);e.ok(n.verify(n))}),it("should generate a self-signed certificate",function(){var n={privateKey:t.privateKeyFromPem(i.privateKey),publicKey:t.publicKeyFromPem(i.publicKey)},r=t.createCertificate();r.publicKey=n.publicKey,r.serialNumber="01",r.validity.notBefore=new Date,r.validity.notAfter=new Date,r.validity.notAfter.setFullYear(r.validity.notBefore.getFullYear()+1);var s=[{name:"commonName",value:"example.org"},{name:"countryName",value:"US"},{shortName:"ST",value:"Virginia"},{name:"localityName",value:"Blacksburg"},{name:"organizationName",value:"Test"},{shortName:"OU",value:"Test"}];r.setSubject(s),r.setIssuer(s),r.setExtensions([{name:"basicConstraints",cA:!0},{name:"keyUsage",keyCertSign:!0,digitalSignature:!0,nonRepudiation:!0,keyEncipherment:!0,dataEncipherment:!0},{name:"extKeyUsage",serverAuth:!0,clientAuth:!0,codeSigning:!0,emailProtection:!0,timeStamping:!0},{name:"nsCertType",client:!0,server:!0,email:!0,objsign:!0,sslCA:!0,emailCA:!0,objCA:!0},{name:"subjectAltName",altNames:[{type:6,value:"http://example.org/webid#me"}]},{name:"subjectKeyIdentifier"}]),r.sign(n.privateKey);var o=t.certificateToPem(r);r=t.certificateFromPem(o);var u=t.createCaStore();u.addCertificate(r),t.verifyCertificateChain(u,[r],function(t,n,i){return e.equal(t,!0),e.ok(r.verifySubjectKeyIdentifier()),!0})}),it("should verify certificate with sha1WithRSAEncryption signature",function(){var n="-----BEGIN CERTIFICATE-----\r\nMIIDZDCCAs2gAwIBAgIKQ8fjjgAAAABh3jANBgkqhkiG9w0BAQUFADBGMQswCQYD\r\nVQQGEwJVUzETMBEGA1UEChMKR29vZ2xlIEluYzEiMCAGA1UEAxMZR29vZ2xlIElu\r\ndGVybmV0IEF1dGhvcml0eTAeFw0xMjA2MjcxMzU5MTZaFw0xMzA2MDcxOTQzMjda\r\nMGcxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1N\r\nb3VudGFpbiBWaWV3MRMwEQYDVQQKEwpHb29nbGUgSW5jMRYwFAYDVQQDEw13d3cu\r\nZ29vZ2xlLmRlMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCw2Hw3vNy5QMSd\r\n0/iMCS8lwZk9lnEk2NmrJt6vGJfRGlBprtHp5lpMFMoi+x8m8EwGVxXHGp7hLyN/\r\ngXuUjL7/DY9fxxx9l77D+sDZz7jfUfWmhS03Ra1FbT6myF8miVZFChJ8XgWzioJY\r\ngyNdRUC9149yrXdPWrSmSVaT0+tUCwIDAQABo4IBNjCCATIwHQYDVR0lBBYwFAYI\r\nKwYBBQUHAwEGCCsGAQUFBwMCMB0GA1UdDgQWBBTiQGhrO3785rMPIKZ/zQEl5RyS\r\n0TAfBgNVHSMEGDAWgBS/wDDr9UMRPme6npH7/Gra42sSJDBbBgNVHR8EVDBSMFCg\r\nTqBMhkpodHRwOi8vd3d3LmdzdGF0aWMuY29tL0dvb2dsZUludGVybmV0QXV0aG9y\r\naXR5L0dvb2dsZUludGVybmV0QXV0aG9yaXR5LmNybDBmBggrBgEFBQcBAQRaMFgw\r\nVgYIKwYBBQUHMAKGSmh0dHA6Ly93d3cuZ3N0YXRpYy5jb20vR29vZ2xlSW50ZXJu\r\nZXRBdXRob3JpdHkvR29vZ2xlSW50ZXJuZXRBdXRob3JpdHkuY3J0MAwGA1UdEwEB\r\n/wQCMAAwDQYJKoZIhvcNAQEFBQADgYEAVJ0qt/MBvHEPuWHeH51756qy+lBNygLA\r\nXp5Gq+xHUTOzRty61BR05zv142hYAGWvpvnEOJ/DI7V3QlXK8a6dQ+du97obQJJx\r\n7ekqtfxVzmlSb23halYSoXmWgP8Tq0VUDsgsSLE7fS8JuO1soXUVKj1/6w189HL6\r\nLsngXwZSuL0=\r\n-----END CERTIFICATE-----\r\n",r="-----BEGIN CERTIFICATE-----\r\nMIICsDCCAhmgAwIBAgIDC2dxMA0GCSqGSIb3DQEBBQUAME4xCzAJBgNVBAYTAlVT\r\nMRAwDgYDVQQKEwdFcXVpZmF4MS0wKwYDVQQLEyRFcXVpZmF4IFNlY3VyZSBDZXJ0\r\naWZpY2F0ZSBBdXRob3JpdHkwHhcNMDkwNjA4MjA0MzI3WhcNMTMwNjA3MTk0MzI3\r\nWjBGMQswCQYDVQQGEwJVUzETMBEGA1UEChMKR29vZ2xlIEluYzEiMCAGA1UEAxMZ\r\nR29vZ2xlIEludGVybmV0IEF1dGhvcml0eTCBnzANBgkqhkiG9w0BAQEFAAOBjQAw\r\ngYkCgYEAye23pIucV+eEPkB9hPSP0XFjU5nneXQUr0SZMyCSjXvlKAy6rWxJfoNf\r\nNFlOCnowzdDXxFdF7dWq1nMmzq0yE7jXDx07393cCDaob1FEm8rWIFJztyaHNWrb\r\nqeXUWaUr/GcZOfqTGBhs3t0lig4zFEfC7wFQeeT9adGnwKziV28CAwEAAaOBozCB\r\noDAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFL/AMOv1QxE+Z7qekfv8atrjaxIk\r\nMB8GA1UdIwQYMBaAFEjmaPkr0rKV10fYIyAQTzOYkJ/UMBIGA1UdEwEB/wQIMAYB\r\nAf8CAQAwOgYDVR0fBDMwMTAvoC2gK4YpaHR0cDovL2NybC5nZW90cnVzdC5jb20v\r\nY3Jscy9zZWN1cmVjYS5jcmwwDQYJKoZIhvcNAQEFBQADgYEAuIojxkiWsRF8YHde\r\nBZqrocb6ghwYB8TrgbCoZutJqOkM0ymt9e8kTP3kS8p/XmOrmSfLnzYhLLkQYGfN\r\n0rTw8Ktx5YtaiScRhKqOv5nwnQkhClIZmloJ0pC3+gz4fniisIWvXEyZ2VxVKfml\r\nUUIuOss4jHg7y/j7lYe8vJD5UDI=\r\n-----END CERTIFICATE-----\r\n",i=t.certificateFromPem(n,!0),s=t.certificateFromPem(r);e.ok(s.verify(i))}),it("should verify certificate with sha256WithRSAEncryption signature",function(){var n="-----BEGIN CERTIFICATE-----\r\nMIIDuzCCAqOgAwIBAgIEO5vZjDANBgkqhkiG9w0BAQsFADBGMQswCQYDVQQGEwJE\r\nRTEPMA0GA1UEChMGRWxzdGVyMQswCQYDVQQLEwJDQTEZMBcGA1UEAxMQRWxzdGVy\r\nU29mdFRlc3RDQTAeFw0xMDA5MTUwNTM4MjRaFw0xMzA5MTUwNTM4MjRaMCsxFDAS\r\nBgNVBAUTCzEwMDIzMTQ5OTRDMRMwEQYDVQQDEwoxMDAyMzE0OTk0MIGfMA0GCSqG\r\nSIb3DQEBAQUAA4GNADCBiQKBgQCLPqjbwjsugzw6+qwwm/pdzDwk7ASIsBYJ17GT\r\nqyT0zCnYmdDDGWsYc+xxFVVIi8xBt6Mlq8Rwj+02UJhY9qm6zRA9MqFZC3ih+HoW\r\nxq7H8N2d10N0rX6h5PSjkF5fU5ugncZmppsRGJ9DNXgwjpf/CsH2rqThUzK4xfrq\r\njpDS/wIDAQABo4IBTjCCAUowDgYDVR0PAQH/BAQDAgUgMAwGA1UdEwEB/wQCMAAw\r\nHQYDVR0OBBYEFF1h7H37OQivS57GD8+nK6VsgMPTMIGXBgNVHR8EgY8wgYwwgYmg\r\ngYaggYOGgYBsZGFwOi8vMTkyLjE2OC42LjI0OjM4OS9sJTNkQ0ElMjBaZXJ0aWZp\r\na2F0ZSxvdSUzZENBLGNuJTNkRWxzdGVyU29mdFRlc3RDQSxkYyUzZHdpZXNlbCxk\r\nYyUzZGVsc3RlcixkYyUzZGRlPz9iYXNlPyhvYmplY3RDbGFzcz0qKTBxBgNVHSME\r\najBogBRBILMYmlZu//pj3wjDe2UPkq7jk6FKpEgwRjELMAkGA1UEBhMCREUxDzAN\r\nBgNVBAoTBkVsc3RlcjEPMA0GA1UECxMGUm9vdENBMRUwEwYDVQQDEwxFbHN0ZXJS\r\nb290Q0GCBDuayikwDQYJKoZIhvcNAQELBQADggEBAK8Z1+/VNyU5w/EiyhFH5aRE\r\nMzxo0DahqKEm4pW5haBgKubJwZGs+CrBZR70TPbZGgJd36eyMgeXb/06lBnxewii\r\nI/aY6wMTviQTpqFnz5m0Le8UhH+hY1bqNG/vf6J+1gbOSrZyhAUV+MDJbL/OkzX4\r\nvoVAfUBqSODod0f5wCW2RhvBmB9E62baP6qizdxyPA4iV16H4C0etd/7coLX6NZC\r\noz3Yu0IRTQCH+YrpfIbxGb0grNhtCTfFpa287fuzu8mIEvLNr8GibhBXmQg7iJ+y\r\nq0VIyZLY8k6jEPrUB5Iv5ouSR19Dda/2+xJPlT/bosuNcErEuk/yKAHWAzwm1wQ=\r\n-----END CERTIFICATE-----\r\n",r="-----BEGIN CERTIFICATE-----\r\nMIIESjCCAzKgAwIBAgIEO5rKKTANBgkqhkiG9w0BAQsFADBGMQswCQYDVQQGEwJE\r\nRTEPMA0GA1UEChMGRWxzdGVyMQ8wDQYDVQQLEwZSb290Q0ExFTATBgNVBAMTDEVs\r\nc3RlclJvb3RDQTAeFw0wOTA3MjgwODE5MTFaFw0xNDA3MjgwODE5MTFaMEYxCzAJ\r\nBgNVBAYTAkRFMQ8wDQYDVQQKEwZFbHN0ZXIxCzAJBgNVBAsTAkNBMRkwFwYDVQQD\r\nExBFbHN0ZXJTb2Z0VGVzdENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC\r\nAQEAv5uoKLnxXQe75iqwqgyt3H6MDAx/wvUVs26+2+yHpEUb/2gA3L8E+NChSb9E\r\naNgxxoac3Yhvxzq2mPpih3vkY7Xw512Tm8l/OPbT8kbmBJmYZneFALXHytAIZiEf\r\ne0ZYNKAlClFIgNP5bE9UjTqVEEoSiUhpTubM6c5xEYVznnwPBoYQ0ari7RTDYnME\r\nHK4vMfoeBeWHYPiEygNHnGUG8d3merRC/lQASUtL6ikmLWKCKHfyit5ACzPNKAtw\r\nIzHAzD5ek0BpcUTci8hUsKz2ZvmoZcjPyj63veQuMYS5cTMgr3bfz9uz1xuoEDsb\r\nSv9rQX9Iw3N7yMpxTDJTqGKhYwIDAQABo4IBPjCCATowDgYDVR0PAQH/BAQDAgEG\r\nMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFEEgsxiaVm7/+mPfCMN7ZQ+S\r\nruOTMIGXBgNVHR8EgY8wgYwwgYmggYaggYOGgYBsZGFwOi8vMTkyLjE2OC42LjI0\r\nOjM4OS9sJTNkQ0ElMjBaZXJ0aWZpa2F0ZSxvdSUzZFJvb3RDQSxjbiUzZEVsc3Rl\r\nclJvb3RDQSxkYyUzZHdpZXNlbCxkYyUzZGVsc3RlcixkYyUzZGRlPz9iYXNlPyhv\r\nYmplY3RDbGFzcz0qKTBbBgNVHSMEVDBSoUqkSDBGMQswCQYDVQQGEwJERTEPMA0G\r\nA1UEChMGRWxzdGVyMQ8wDQYDVQQLEwZSb290Q0ExFTATBgNVBAMTDEVsc3RlclJv\r\nb3RDQYIEO5rKADANBgkqhkiG9w0BAQsFAAOCAQEAFauDnfHSbgRmbFkpQUXM5wKi\r\nK5STAaVps201iAjacX5EsOs5L37VUMoT9G2DAE8Z6B1pIiR3zcd3UpiHnFlUTC0f\r\nZdOCXzDkOfziKY/RzuUsLNFUhBizCIA0+XcKgm3dSA5ex8fChLJddSYheSLuPua7\r\niNMuzaU2YnevbMwpdEsl55Qr/uzcc0YM/mCuM4vsNFyFml91SQyPPmdR3VvGOoGl\r\nqS1R0HSoPJUvr0N0kARwD7kO3ikcJ6FxBCsgVLZHGJC+q8PQNZmVMbfgjH4nAyP8\r\nu7Qe03v2WLW0UgKu2g0UcQXWXbovktpZoK0fUOwv3bqsZ0K1IjVvMKG8OysUvA==\r\n-----END CERTIFICATE-----\r\n",i=t.certificateFromPem(n,!0),s=t.certificateFromPem(r);e.ok(s.verify(i))}),it("should import certificate with sha256 RSASSA-PSS signature",function(){var n="-----BEGIN CERTIFICATE-----\r\nMIIERzCCAvugAwIBAgIEO50CcjBBBgkqhkiG9w0BAQowNKAPMA0GCWCGSAFlAwQC\r\nAQUAoRwwGgYJKoZIhvcNAQEIMA0GCWCGSAFlAwQCAQUAogMCASAwRjELMAkGA1UE\r\nBhMCREUxDzANBgNVBAoTBkVsc3RlcjELMAkGA1UECxMCQ0ExGTAXBgNVBAMTEEVs\r\nc3RlclNvZnRUZXN0Q0EwHhcNMTEwNzI4MTIxMzU3WhcNMTQwNzI4MTIxMzU3WjAr\r\nMRQwEgYDVQQFEwsxMDAyNzUzMzI1QzETMBEGA1UEAxMKMTAwMjc1MzMyNTCCASIw\r\nDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALHCogo7LVUkxWsMIc/0jgH2PCLt\r\nukbATPehxWBG1XUPrz53lWgFJzlZaKLlLVVnXrfULaifuOKlZP6SM1JQlL1JuYgY\r\nAdgZyHjderNIk5NsSTmefwonSn/ukri5IRTH420oHtSjxk6+/DXlWnQy5OzTN6Bq\r\njVJo8L+TTmf2jWuEam5cWa+YVP2k3tIqX5yMUDFjKO4znHdtIkHnBE0Kx03rWQRB\r\nTSYWDgDm2gttdOs9JVeuW0nnwQj27uo9gOR0iyaUjVrKLZ95p6zpXhM4uMSVRNeo\r\nLqkdqP2n+4pDXZVqLNgjkHQUS/xq9Q/kYgT2J7wkGfYxP9to7TG7vra1eOECAwEA\r\nAaOB7zCB7DAOBgNVHQ8BAf8EBAMCBSAwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQU\r\nNDJ2BZIk6ukLqkdmttH12bu2leswOgYDVR0fBDMwMTAvoC2gK4YpaHR0cDovL2Ny\r\nbC5lbHN0ZXIuZGUvRWxzdGVyU29mdFRlc3RDQS5jcmwwcQYDVR0jBGowaIAU1R9A\r\nHmpdzaxK3v+ihQsEpAFgzOKhSqRIMEYxCzAJBgNVBAYTAkRFMQ8wDQYDVQQKEwZF\r\nbHN0ZXIxDzANBgNVBAsTBlJvb3RDQTEVMBMGA1UEAxMMRWxzdGVyUm9vdENBggQ7\r\nmsqPMEEGCSqGSIb3DQEBCjA0oA8wDQYJYIZIAWUDBAIBBQChHDAaBgkqhkiG9w0B\r\nAQgwDQYJYIZIAWUDBAIBBQCiAwIBIAOCAQEAJBYNRZpe+z3yPPLV539Yci6OfjVg\r\nvs1e3rvSvcpFaqRJ8vZ8WNx3uuRQZ6B4Z3YEc00UJAOl3wU6KhamyryK2YvCrPg+\r\nTS5QDXNaO2z/rAnY1wWSlwBPlhqpMRrNv9cRXBcgK5YxprjytCVYN0UHdintgYxG\r\nfg7QYiFb00UXxAza1AFrpG+RqySFfO1scmu4kgpeb6A3USnQ0r6rZz6dt6NqgZZ6\r\noUpDOCvnS9XSOWuvJirV8hIU0KAagguTbwfTqt9nt0wDlwZpemsJZ4Vvnvy8d9Jf\r\nzA68EWHbZLr2QP9hb3sHCWJgplMsTJnUwRfi2hf5KNtP8Xg5DSLMfTEbhw==\r\n-----END CERTIFICATE-----\r\n",r=t.certificateFromPem(n,!0);e.equal(r.signatureOid,t.oids["RSASSA-PSS"]),e.equal(r.signatureParameters.hash.algorithmOid,t.oids.sha256),e.equal(r.signatureParameters.mgf.algorithmOid,t.oids.mgf1),e.equal(r.signatureParameters.mgf.hash.algorithmOid,t.oids.sha256),e.equal(r.siginfo.algorithmOid,t.oids["RSASSA-PSS"]),e.equal(r.siginfo.parameters.hash.algorithmOid,t.oids.sha256),e.equal(r.siginfo.parameters.mgf.algorithmOid,t.oids.mgf1),e.equal(r.siginfo.parameters.mgf.hash.algorithmOid,t.oids.sha256)}),it("should export certificate with sha256 RSASSA-PSS signature",function(){var n="-----BEGIN CERTIFICATE-----\r\nMIIERzCCAvugAwIBAgIEO50CcjBBBgkqhkiG9w0BAQowNKAPMA0GCWCGSAFlAwQC\r\nAQUAoRwwGgYJKoZIhvcNAQEIMA0GCWCGSAFlAwQCAQUAogMCASAwRjELMAkGA1UE\r\nBhMCREUxDzANBgNVBAoTBkVsc3RlcjELMAkGA1UECxMCQ0ExGTAXBgNVBAMTEEVs\r\nc3RlclNvZnRUZXN0Q0EwHhcNMTEwNzI4MTIxMzU3WhcNMTQwNzI4MTIxMzU3WjAr\r\nMRQwEgYDVQQFEwsxMDAyNzUzMzI1QzETMBEGA1UEAxMKMTAwMjc1MzMyNTCCASIw\r\nDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALHCogo7LVUkxWsMIc/0jgH2PCLt\r\nukbATPehxWBG1XUPrz53lWgFJzlZaKLlLVVnXrfULaifuOKlZP6SM1JQlL1JuYgY\r\nAdgZyHjderNIk5NsSTmefwonSn/ukri5IRTH420oHtSjxk6+/DXlWnQy5OzTN6Bq\r\njVJo8L+TTmf2jWuEam5cWa+YVP2k3tIqX5yMUDFjKO4znHdtIkHnBE0Kx03rWQRB\r\nTSYWDgDm2gttdOs9JVeuW0nnwQj27uo9gOR0iyaUjVrKLZ95p6zpXhM4uMSVRNeo\r\nLqkdqP2n+4pDXZVqLNgjkHQUS/xq9Q/kYgT2J7wkGfYxP9to7TG7vra1eOECAwEA\r\nAaOB7zCB7DAOBgNVHQ8BAf8EBAMCBSAwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQU\r\nNDJ2BZIk6ukLqkdmttH12bu2leswOgYDVR0fBDMwMTAvoC2gK4YpaHR0cDovL2Ny\r\nbC5lbHN0ZXIuZGUvRWxzdGVyU29mdFRlc3RDQS5jcmwwcQYDVR0jBGowaIAU1R9A\r\nHmpdzaxK3v+ihQsEpAFgzOKhSqRIMEYxCzAJBgNVBAYTAkRFMQ8wDQYDVQQKEwZF\r\nbHN0ZXIxDzANBgNVBAsTBlJvb3RDQTEVMBMGA1UEAxMMRWxzdGVyUm9vdENBggQ7\r\nmsqPMEEGCSqGSIb3DQEBCjA0oA8wDQYJYIZIAWUDBAIBBQChHDAaBgkqhkiG9w0B\r\nAQgwDQYJYIZIAWUDBAIBBQCiAwIBIAOCAQEAJBYNRZpe+z3yPPLV539Yci6OfjVg\r\nvs1e3rvSvcpFaqRJ8vZ8WNx3uuRQZ6B4Z3YEc00UJAOl3wU6KhamyryK2YvCrPg+\r\nTS5QDXNaO2z/rAnY1wWSlwBPlhqpMRrNv9cRXBcgK5YxprjytCVYN0UHdintgYxG\r\nfg7QYiFb00UXxAza1AFrpG+RqySFfO1scmu4kgpeb6A3USnQ0r6rZz6dt6NqgZZ6\r\noUpDOCvnS9XSOWuvJirV8hIU0KAagguTbwfTqt9nt0wDlwZpemsJZ4Vvnvy8d9Jf\r\nzA68EWHbZLr2QP9hb3sHCWJgplMsTJnUwRfi2hf5KNtP8Xg5DSLMfTEbhw==\r\n-----END CERTIFICATE-----\r\n",r=t.certificateFromPem(n,!0);e.equal(t.certificateToPem(r),n)}),it("should verify certificate with sha256 RSASSA-PSS signature",function(){var n="-----BEGIN CERTIFICATE-----\r\nMIIERzCCAvugAwIBAgIEO50CcjBBBgkqhkiG9w0BAQowNKAPMA0GCWCGSAFlAwQC\r\nAQUAoRwwGgYJKoZIhvcNAQEIMA0GCWCGSAFlAwQCAQUAogMCASAwRjELMAkGA1UE\r\nBhMCREUxDzANBgNVBAoTBkVsc3RlcjELMAkGA1UECxMCQ0ExGTAXBgNVBAMTEEVs\r\nc3RlclNvZnRUZXN0Q0EwHhcNMTEwNzI4MTIxMzU3WhcNMTQwNzI4MTIxMzU3WjAr\r\nMRQwEgYDVQQFEwsxMDAyNzUzMzI1QzETMBEGA1UEAxMKMTAwMjc1MzMyNTCCASIw\r\nDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALHCogo7LVUkxWsMIc/0jgH2PCLt\r\nukbATPehxWBG1XUPrz53lWgFJzlZaKLlLVVnXrfULaifuOKlZP6SM1JQlL1JuYgY\r\nAdgZyHjderNIk5NsSTmefwonSn/ukri5IRTH420oHtSjxk6+/DXlWnQy5OzTN6Bq\r\njVJo8L+TTmf2jWuEam5cWa+YVP2k3tIqX5yMUDFjKO4znHdtIkHnBE0Kx03rWQRB\r\nTSYWDgDm2gttdOs9JVeuW0nnwQj27uo9gOR0iyaUjVrKLZ95p6zpXhM4uMSVRNeo\r\nLqkdqP2n+4pDXZVqLNgjkHQUS/xq9Q/kYgT2J7wkGfYxP9to7TG7vra1eOECAwEA\r\nAaOB7zCB7DAOBgNVHQ8BAf8EBAMCBSAwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQU\r\nNDJ2BZIk6ukLqkdmttH12bu2leswOgYDVR0fBDMwMTAvoC2gK4YpaHR0cDovL2Ny\r\nbC5lbHN0ZXIuZGUvRWxzdGVyU29mdFRlc3RDQS5jcmwwcQYDVR0jBGowaIAU1R9A\r\nHmpdzaxK3v+ihQsEpAFgzOKhSqRIMEYxCzAJBgNVBAYTAkRFMQ8wDQYDVQQKEwZF\r\nbHN0ZXIxDzANBgNVBAsTBlJvb3RDQTEVMBMGA1UEAxMMRWxzdGVyUm9vdENBggQ7\r\nmsqPMEEGCSqGSIb3DQEBCjA0oA8wDQYJYIZIAWUDBAIBBQChHDAaBgkqhkiG9w0B\r\nAQgwDQYJYIZIAWUDBAIBBQCiAwIBIAOCAQEAJBYNRZpe+z3yPPLV539Yci6OfjVg\r\nvs1e3rvSvcpFaqRJ8vZ8WNx3uuRQZ6B4Z3YEc00UJAOl3wU6KhamyryK2YvCrPg+\r\nTS5QDXNaO2z/rAnY1wWSlwBPlhqpMRrNv9cRXBcgK5YxprjytCVYN0UHdintgYxG\r\nfg7QYiFb00UXxAza1AFrpG+RqySFfO1scmu4kgpeb6A3USnQ0r6rZz6dt6NqgZZ6\r\noUpDOCvnS9XSOWuvJirV8hIU0KAagguTbwfTqt9nt0wDlwZpemsJZ4Vvnvy8d9Jf\r\nzA68EWHbZLr2QP9hb3sHCWJgplMsTJnUwRfi2hf5KNtP8Xg5DSLMfTEbhw==\r\n-----END CERTIFICATE-----\r\n",r="-----BEGIN CERTIFICATE-----\r\nMIIEZDCCAxigAwIBAgIEO5rKjzBBBgkqhkiG9w0BAQowNKAPMA0GCWCGSAFlAwQC\r\nAQUAoRwwGgYJKoZIhvcNAQEIMA0GCWCGSAFlAwQCAQUAogMCASAwRjELMAkGA1UE\r\nBhMCREUxDzANBgNVBAoTBkVsc3RlcjEPMA0GA1UECxMGUm9vdENBMRUwEwYDVQQD\r\nEwxFbHN0ZXJSb290Q0EwHhcNMTEwNzI4MTExNzI4WhcNMTYwNzI4MTExNzI4WjBG\r\nMQswCQYDVQQGEwJERTEPMA0GA1UEChMGRWxzdGVyMQswCQYDVQQLEwJDQTEZMBcG\r\nA1UEAxMQRWxzdGVyU29mdFRlc3RDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC\r\nAQoCggEBAMFpz3sXnXq4ZUBdYdpG5DJVfITLXYwXPfEJzr1pLRfJ2eMPn7k3B/2g\r\nbvuH30zKmDRjlfV51sFw4l1l+cQugzy5FEOrfE6g7IvhpBUf9SQujVWtE3BoSRR5\r\npSGbIWC7sm2SG0drpoCRpL0xmWZlAUS5mz7hBecJC/kKkKeOxUg5h492XQgWd0ow\r\n6GlyQBxJCmxgQBMnLS0stecs234hR5gvTHic50Ey+gRMPsTyco2Fm0FqvXtBuOsj\r\nzAW7Nk2hnM6awFHVMDBLm+ClE1ww0dLW0ujkdoGsTEbvmM/w8MBI6WAiWaanjK/x\r\nlStmQeUVXKd+AfuzT/FIPrwANcC1qGUCAwEAAaOB8TCB7jAOBgNVHQ8BAf8EBAMC\r\nAQYwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQU1R9AHmpdzaxK3v+ihQsE\r\npAFgzOIwNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL2NybC5lbHN0ZXIuZGUvRWxz\r\ndGVyUm9vdENBLmNybDBxBgNVHSMEajBogBS3zfTokckL2H/fTojW02K+metEcaFK\r\npEgwRjELMAkGA1UEBhMCREUxDzANBgNVBAoTBkVsc3RlcjEPMA0GA1UECxMGUm9v\r\ndENBMRUwEwYDVQQDEwxFbHN0ZXJSb290Q0GCBDuaylowQQYJKoZIhvcNAQEKMDSg\r\nDzANBglghkgBZQMEAgEFAKEcMBoGCSqGSIb3DQEBCDANBglghkgBZQMEAgEFAKID\r\nAgEgA4IBAQBjT107fBmSfQNUYCpXIlaS/pogPoCahuC1g8QDtq6IEVXoEgXCzfVN\r\nJYHyYOQOraP4O2LEcXpo/oc0MMpVF06QLKG/KieUE0mrZnsCJ3GLSJkM8tI8bRHj\r\n8tAhlViMacUqnKKufCs/rIN25JB57+sCyFqjtRbSt88e+xqFJ5I79Btp/bNtoj2G\r\nOJGl997EPua9/yJuvdA9W67WO/KwEh+FqylB1pAapccOHqttwu4QJIc/XJfG5rrf\r\n8QZz8HIuOcroA4zIrprQ1nJRCuMII04ueDtBVz1eIEmqNEUkr09JdK8M0LKH0lMK\r\nYsgjai/P2mPVVwhVw6dHzUVRLXh3xIQr\r\n-----END CERTIFICATE-----\r\n",i=t.certificateFromPem(n,!0),s=t.certificateFromPem(r);e.ok(s.verify(i))})})}typeof define=="function"?define("test/x509",["forge/pki","forge/md","forge/util"],function(t,n,r){e(ASSERT,t(),n(),r())}):typeof module=="object"&&module.exports&&e(require("assert"),require("../../js/pki")(),require("../../js/md")(),require("../../js/util")())}(),function(){function e(e,t){var n={privateKey:"-----BEGIN RSA PRIVATE KEY-----\r\nMIICXQIBAAKBgQDL0EugUiNGMWscLAVM0VoMdhDZEJOqdsUMpx9U0YZI7szokJqQ\r\nNIwokiQ6EonNnWSMlIvy46AhnlRYn+ezeTeU7eMGTkP3VF29vXBo+dLq5e+8VyAy\r\nQ3FzM1wI4ts4hRACF8w6mqygXQ7i/SDu8/rXqRGtvnM+z0MYDdKo80efzwIDAQAB\r\nAoGAIzkGONi5G+JifmXlLJdplom486p3upf4Ce2/7mqfaG9MnkyPSairKD/JXvfh\r\nNNWkkN8DKKDKBcVVElPgORYT0qwrWc7ueLBMUCbRXb1ZyfEulimG0R3kjUh7NYau\r\nDaIkVgfykXGSQMZx8FoaT6L080zd+0emKDDYRrb+/kgJNJECQQDoUZoiC2K/DWNY\r\nh3/ppZ0ane2y4SBmJUHJVMPQ2CEgxsrJTxet668ckNCKaOP/3VFPoWC41f17DvKq\r\nnoYINNntAkEA4JbZBZBVUrQFhHlrpXT4jzqtO2RlKZzEq8qmFZfEErxOT1WMyyCi\r\nlAQ5gUKardo1Kf0omC8Xq/uO9ZYdED55KwJBALs6cJ65UFaq4oLJiQPzLd7yokuE\r\ndcj8g71PLBTW6jPxIiMFNA89nz3FU9wIVp+xbMNhSoMMKqIPVPC+m0Rn260CQQDA\r\nI83fWK/mZWUjBM33a68KumRiH238v8XyQxj7+C8i6D8G2GXvkigFAehAkb7LZZd+\r\nKLuGFyPlWv3fVWHf99KpAkBQFKk3MRMl6IGJZUEFQe4l5whm8LkGU4acSqv9B3xt\r\nqROkCrsFrMPqjuuzEmyHoQZ64r2PLJg7FOuyhBnQUOt4\r\n-----END RSA PRIVATE KEY-----\r\n",publicKey:"-----BEGIN PUBLIC KEY-----\r\nMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDL0EugUiNGMWscLAVM0VoMdhDZ\r\nEJOqdsUMpx9U0YZI7szokJqQNIwokiQ6EonNnWSMlIvy46AhnlRYn+ezeTeU7eMG\r\nTkP3VF29vXBo+dLq5e+8VyAyQ3FzM1wI4ts4hRACF8w6mqygXQ7i/SDu8/rXqRGt\r\nvnM+z0MYDdKo80efzwIDAQAB\r\n-----END PUBLIC KEY-----\r\n"};describe("csr",function(){it("should generate a certification request",function(){var r={privateKey:t.privateKeyFromPem(n.privateKey),publicKey:t.publicKeyFromPem(n.publicKey)},i=t.createCertificationRequest();i.publicKey=r.publicKey,i.setSubject([{name:"commonName",value:"example.org"},{name:"countryName",value:"US"},{shortName:"ST",value:"Virginia"},{name:"localityName",value:"Blacksburg"},{name:"organizationName",value:"Test"},{shortName:"OU",value:"Test"}]),i.setAttributes([{name:"challengePassword",value:"password"},{name:"unstructuredName",value:"My company"}]),i.sign(r.privateKey);var s=t.certificationRequestToPem(i);i=t.certificationRequestFromPem(s),e.ok(i.verify())})})}typeof define=="function"?define("test/csr",["forge/pki"],function(t){e(ASSERT,t())}):typeof module=="object"&&module.exports&&e(require("assert"),require("../../js/pki")())}(),function(){function e(e,t,n){describe("aes",function(){it("should encrypt a single block with a 128-bit key",function(){var r=[66051,67438087,134810123,202182159],i=[1122867,1146447479,2291772091,3437096703],s=[],o=t._expandKey(r,!1);t._updateBlock(o,i,s,!1);var u=n.createBuffer();u.putInt32(s[0]),u.putInt32(s[1]),u.putInt32(s[2]),u.putInt32(s[3]),e.equal(u.toHex(),"69c4e0d86a7b0430d8cdb78070b4c55a")}),it("should decrypt a single block with a 128-bit key",function(){var r=[66051,67438087,134810123,202182159],i=[1774510296,1786446896,3637360512,1890895194],s=[],o=t._expandKey(r,!0);t._updateBlock(o,i,s,!0);var u=n.createBuffer();u.putInt32(s[0]),u.putInt32(s[1]),u.putInt32(s[2]),u.putInt32(s[3]),e.equal(u.toHex(),"00112233445566778899aabbccddeeff")}),it("should encrypt a single block with a 192-bit key",function(){var r=[66051,67438087,134810123,202182159,269554195,336926231],i=[1122867,1146447479,2291772091,3437096703],s=[],o=t._expandKey(r,!1);t._updateBlock(o,i,s,!1);var u=n.createBuffer();u.putInt32(s[0]),u.putInt32(s[1]),u.putInt32(s[2]),u.putInt32(s[3]),e.equal(u.toHex(),"dda97ca4864cdfe06eaf70a0ec0d7191")}),it("should decrypt a single block with a 192-bit key",function(){var r=[66051,67438087,134810123,202182159,269554195,336926231],i=[3718872228,2253184992,1856991392,3960304017],s=[],o=t._expandKey(r,!0);t._updateBlock(o,i,s,!0);var u=n.createBuffer();u.putInt32(s[0]),u.putInt32(s[1]),u.putInt32(s[2]),u.putInt32(s[3]),e.equal(u.toHex(),"00112233445566778899aabbccddeeff")}),it("should encrypt a single block with a 256-bit key",function(){var r=[66051,67438087,134810123,202182159,269554195,336926231,404298267,471670303],i=[1122867,1146447479,2291772091,3437096703],s=[],o=t._expandKey(r,!1);t._updateBlock(o,i,s,!1);var u=n.createBuffer();u.putInt32(s[0]),u.putInt32(s[1]),u.putInt32(s[2]),u.putInt32(s[3]),e.equal(u.toHex(),"8ea2b7ca516745bfeafc49904b496089")}),it("should decrypt a single block with a 256-bit key",function(){var r=[66051,67438087,134810123,202182159,269554195,336926231,404298267,471670303],i=[2393028554,1365722559,3942402448,1263100041],s=[],o=t._expandKey(r,!0);t._updateBlock(o,i,s,!0);var u=n.createBuffer();u.putInt32(s[0]),u.putInt32(s[1]),u.putInt32(s[2]),u.putInt32(s[3]),e.equal(u.toHex(),"00112233445566778899aabbccddeeff")}),function(){var r=["06a9214036b8a15b512e03d534120006","c286696d887c9aa0611bbb3e2025a45a","6c3ea0477630ce21a2ce334aa746c2cd","56e47a38c5598974bc46903dba290349"],i=["3dafba429d9eb430b422da802c9fac41","562e17996d093d28ddb3ba695a2e6f58","c782dc4c098c66cbd9cd27d825682c81","8ce82eefbea0da3c44699ed7db51b7d9"],s=["Single block msg","000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f","This is a 48-byte message (exactly 3 AES blocks)","a0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedf"],o=["e353779c1079aeb82708942dbe77181a","d296cd94c2cccf8a3a863028b5e1dc0a7586602d253cfff91b8266bea6d61ab1","d0a02b3836451753d493665d33f0e8862dea54cdb293abc7506939276772f8d5021c19216bad525c8579695d83ba2684","c30e32ffedc0774e6aff6af0869f71aa0f3af07a9a31a9c684db207eb0ef8e4e35907aa632c3ffdf868bb7b29d3d46ad83ce9f9a102ee99d49a53e87f4c3da55"];for(var u=0;u<r.length;++u)(function(u){var a=n.hexToBytes(r[u]),f=n.hexToBytes(i[u]),l=u&1?n.hexToBytes(s[u]):s[u],c=n.hexToBytes(o[u]);it("should aes-128-cbc encrypt: "+s[u],function(){var r=t.createEncryptionCipher(a,"CBC");r.start(f),r.update(n.createBuffer(l)),r.finish(function(){return!0}),e.equal(r.output.toHex(),o[u])}),it("should aes-128-cbc decrypt: "+o[u],function(){var r=t.createDecryptionCipher(a,"CBC");r.start(f),r.update(n.createBuffer(c)),r.finish(function(){return!0});var i=u&1?r.output.toHex():r.output.bytes();e.equal(i,s[u])})})(u)}(),function(){var r=["00000000000000000000000000000000","2b7e151628aed2a6abf7158809cf4f3c","2b7e151628aed2a6abf7158809cf4f3c","2b7e151628aed2a6abf7158809cf4f3c","2b7e151628aed2a6abf7158809cf4f3c","00000000000000000000000000000000"],i=["80000000000000000000000000000000","000102030405060708090a0b0c0d0e0f","3B3FD92EB72DAD20333449F8E83CFB4A","C8A64537A0B3A93FCDE3CDAD9F1CE58B","26751F67A3CBB140B1808CF187A4F4DF","60f9ff04fac1a25657bf5b36b5efaf75"],s=["00000000000000000000000000000000","6bc1bee22e409f96e93d7e117393172a","ae2d8a571e03ac9c9eb76fac45af8e51","30c81c46a35ce411e5fbc1191a0a52ef","f69f2445df4f9b17ad2b417be66c3710","This is a 48-byte message (exactly 3 AES blocks)"],o=["3ad78e726c1ec02b7ebfe92b23d9ec34","3b3fd92eb72dad20333449f8e83cfb4a","c8a64537a0b3a93fcde3cdad9f1ce58b","26751f67a3cbb140b1808cf187a4f4df","c04b05357c5d1c0eeac4c66f9ff7f2e6","52396a2ba1ba420c5e5b699a814944d8f4e7fbf984a038319fbc0b4ee45cfa6f07b2564beab5b5e92dbd44cb345f49b4"];for(var u=0;u<r.length;++u)(function(u){var a=n.hexToBytes(r[u]),f=n.hexToBytes(i[u]),l=u!==5?n.hexToBytes(s[u]):s[u],c=n.hexToBytes(o[u]);it("should aes-128-cfb encrypt: "+s[u],function(){var r=t.createEncryptionCipher(a,"CFB");r.start(f),r.update(n.createBuffer(l)),r.finish(),e.equal(r.output.toHex(),o[u])}),it("should aes-128-cfb decrypt: "+o[u],function(){var r=t.createDecryptionCipher(a,"CFB");r.start(f),r.update(n.createBuffer(c)),r.finish();var i=u!==5?r.output.toHex():r.output.getBytes();e.equal(i,s[u])})})(u)}(),function(){var r=["00000000000000000000000000000000","00000000000000000000000000000000"],i=["80000000000000000000000000000000","c8ca0d6a35dbeac776e911ee16bea7d3"],s=["00000000000000000000000000000000","This is a 48-byte message (exactly 3 AES blocks)"],o=["3ad78e726c1ec02b7ebfe92b23d9ec34","39c0190727a76b2a90963426f63689cfcdb8a2be8e20c5e877a81a724e3611f62ecc386f2e941b2441c838906002be19"];for(var u=0;u<r.length;++u)(function(u){var a=n.hexToBytes(r[u]),f=n.hexToBytes(i[u]),l=u!==1?n.hexToBytes(s[u]):s[u],c=n.hexToBytes(o[u]);it("should aes-128-ofb encrypt: "+s[u],function(){var r=t.createEncryptionCipher(a,"OFB");r.start(f),r.update(n.createBuffer(l)),r.finish(),e.equal(r.output.toHex(),o[u])}),it("should aes-128-ofb decrypt: "+o[u],function(){var r=t.createDecryptionCipher(a,"OFB");r.start(f),r.update(n.createBuffer(c)),r.finish();var i=u!==1?r.output.toHex():r.output.getBytes();e.equal(i,s[u])})})(u)}(),function(){var r=["2b7e151628aed2a6abf7158809cf4f3c","00000000000000000000000000000000"],i=["f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff","650cdb80ff9fc758342d2bd99ee2abcf"],s=["6bc1bee22e409f96e93d7e117393172a","This is a 48-byte message (exactly 3 AES blocks)"],o=["874d6191b620e3261bef6864990db6ce","5ede11d00e9a76ec1d5e7e811ea3dd1ce09ee941210f825d35718d3282796f1c07c3f1cb424f2b365766ab5229f5b5a4"];for(var u=0;u<r.length;++u)(function(u){var a=n.hexToBytes(r[u]),f=n.hexToBytes(i[u]),l=u!==1?n.hexToBytes(s[u]):s[u],c=n.hexToBytes(o[u]);it("should aes-128-ctr encrypt: "+s[u],function(){var r=t.createEncryptionCipher(a,"CTR");r.start(f),r.update(n.createBuffer(l)),r.finish(),e.equal(r.output.toHex(),o[u])}),it("should aes-128-ctr decrypt: "+o[u],function(){var r=t.createDecryptionCipher(a,"CTR");r.start(f),r.update(n.createBuffer(c)),r.finish();var i=u!==1?r.output.toHex():r.output.getBytes();e.equal(i,s[u])})})(u)}(),function(){var r=["861009ec4d599fab1f40abc76e6f89880cff5833c79c548c99f9045f191cd90b"],i=["d927ad81199aa7dcadfdb4e47b6dc694"],s=["MY-DATA-AND-HERE-IS-MORE-DATA"],o=["80eb666a9fc9e263faf71e87ffc94451d7d8df7cfcf2606470351dd5ac"];for(var u=0;u<r.length;++u)(function(u){var a=n.hexToBytes(r[u]),f=n.hexToBytes(i[u]),l=s[u],c=n.hexToBytes(o[u]);it("should aes-256-cfb encrypt: "+s[u],function(){var r=t.createEncryptionCipher(a,"CFB");r.start(f),r.update(n.createBuffer(l)),r.finish(),e.equal(r.output.toHex(),o[u])}),it("should aes-256-cfb decrypt: "+o[u],function(){var r=t.createDecryptionCipher(a,"CFB");r.start(f),r.update(n.createBuffer(c)),r.finish();var i=r.output.getBytes();e.equal(i,s[u])})})(u)}()})}typeof define=="function"?define("test/aes",["forge/aes","forge/util"],function(t,n){e(ASSERT,t(),n())}):typeof module=="object"&&module.exports&&e(require("assert"),require("../../js/aes")(),require("../../js/util")())}(),function(){function e(e,t,n){describe("rc2",function(){it("should expand a 128-bit key",function(){var r=n.hexToBytes("88bca90e90875a7f0f79c384627bafb2"),i="71ab26462f0b9333609d4476e48ab72438c2194b70a47085d84b6af1dc72119023b94fe80aee2b6b45f27f923d9be1570da3ce8b16ad7f78db166ffbc28a836a4392cf0b748085dae4b69bdc2a4679cdfc09d84317016987e0c5b765c91dc612b1f44d7921b3e2c46447508bd2ac02e119e0f42a89c719675da320cf3e8958cd";e.equal(t.expandKey(r).toHex(),i)}),it("should expand a 40-bit key",function(){var r=n.hexToBytes("88bca90e90"),i="af136d2243b94a0878d7a604f8d6d9fd64a698fd6ebc613e641f0d1612055ef6cb55966db8f32bfd9246dae99880be8a91433adf54ea546d9daad62db7a55f6c7790aa87ba67de0e9ea9128dfc7ccdddd7c47c33d2bb7f823729977f083b5dc1f5bb09000b98e12cdaaf22f80dcc88c37d2c2fd80402f8a30a9e41d356669471";e.equal(t.expandKey(r,40).toHex(),i)}),it("should rc2-ecb encrypt zeros",function(){var r=n.hexToBytes("88bca90e90875a7f0f79c384627bafb2"),i=(new n.createBuffer).fillWithByte(0,8),s=t.startEncrypting(r,null,null);s.update(i),s.finish(),e.equal(s.output.toHex(),"2269552ab0f85ca6e35b3b2ce4e02191")}),it("should rc2-ecb encrypt: vegan",function(){var r=n.hexToBytes("88bca90e90875a7f0f79c384627bafb2"),i=new n.createBuffer("vegan"),s=t.startEncrypting(r,null,null);s.update(i),s.finish(),e.equal(s.output.toHex(),"2194adaf4d517e3a")}),it("should rc2-ecb decrypt: 2194adaf4d517e3a",function(){var r=n.hexToBytes("88bca90e90875a7f0f79c384627bafb2"),i=new n.createBuffer(n.hexToBytes("2194adaf4d517e3a")),s=t.startDecrypting(r,null,null);s.update(i),s.finish(),e.equal(s.output.getBytes(),"vegan")}),it("should rc2-cbc encrypt: revolution",function(){var r=n.hexToBytes("88bca90e90875a7f0f79c384627bafb2"),i=new n.createBuffer(n.hexToBytes("0123456789abcdef")),s=new n.createBuffer("revolution"),o=t.startEncrypting(r,i,null);o.update(s),o.finish(),e.equal(o.output.toHex(),"50cfd16e0fd7f20b17a622eb2a469b7e")}),it("should rc2-cbc decrypt: 50cfd16e0fd7f20b17a622eb2a469b7e",function(){var r=n.hexToBytes("88bca90e90875a7f0f79c384627bafb2"),i=new n.createBuffer(n.hexToBytes("0123456789abcdef")),s=new n.createBuffer(n.hexToBytes("50cfd16e0fd7f20b17a622eb2a469b7e")),o=t.startDecrypting(r,i,null);o.update(s),o.finish(),e.equal(o.output,"revolution")})})}typeof define=="function"?define("test/rc2",["forge/rc2","forge/util"],function(t,n){e(ASSERT,t(),n())}):typeof module=="object"&&module.exports&&e(require("assert"),require("../../js/rc2")(),require("../../js/util")())}(),function(){function e(e,t,n){describe("des",function(){it("should des-ecb encrypt: foobar",function(){var r=new n.createBuffer(n.hexToBytes("a1c06b381adf3651")),i=t.startEncrypting(r,null,null);i.update(n.createBuffer("foobar")),i.finish(),e.equal(i.output.toHex(),"b705ffcf3dff06b3")}),it("should des-ecb decrypt: b705ffcf3dff06b3",function(){var r=new n.createBuffer(n.hexToBytes("a1c06b381adf3651")),i=t.startDecrypting(r,null,null);i.update(n.createBuffer(n.hexToBytes("b705ffcf3dff06b3"))),i.finish(),e.equal(i.output.getBytes(),"foobar")}),it("should des-cbc encrypt: foobar",function(){var r=new n.createBuffer(n.hexToBytes("a1c06b381adf3651")),i=new n.createBuffer(n.hexToBytes("818bcf76efc59662")),s=t.startEncrypting(r,i,null);s.update(n.createBuffer("foobar")),s.finish(),e.equal(s.output.toHex(),"3261e5839a990454")}),it("should des-cbc decrypt: 3261e5839a990454",function(){var r=new n.createBuffer(n.hexToBytes("a1c06b381adf3651")),i=new n.createBuffer(n.hexToBytes("818bcf76efc59662")),s=t.startDecrypting(r,i,null);s.update(n.createBuffer(n.hexToBytes("3261e5839a990454"))),s.finish(),e.equal(s.output.getBytes(),"foobar")}),it("should 3des-ecb encrypt: foobar",function(){var r=new n.createBuffer(n.hexToBytes("a1c06b381adf36517e84575552777779da5e3d9f994b05b5")),i=t.startEncrypting(r,null,null);i.update(n.createBuffer("foobar")),i.finish(),e.equal(i.output.toHex(),"fce8b1ee8c6440d1")}),it("should 3des-ecb decrypt: fce8b1ee8c6440d1",function(){var r=new n.createBuffer(n.hexToBytes("a1c06b381adf36517e84575552777779da5e3d9f994b05b5")),i=t.startDecrypting(r,null,null);i.update(n.createBuffer(n.hexToBytes("fce8b1ee8c6440d1"))),i.finish(),e.equal(i.output.getBytes(),"foobar")}),it('should 3des-cbc encrypt "foobar", restart, and encrypt "foobar,,"',function(){var r=new n.createBuffer(n.hexToBytes("a1c06b381adf36517e84575552777779da5e3d9f994b05b5")),i=new n.createBuffer(n.hexToBytes("818bcf76efc59662")),s=t.startEncrypting(r,i.copy(),null);s.update(n.createBuffer("foobar")),s.finish(),e.equal(s.output.toHex(),"209225f7687ca0b2"),s.start(i.copy()),s.update(n.createBuffer("foobar,,")),s.finish(),e.equal(s.output.toHex(),"57156174c48dfc37293831bf192a6742")}),it('should 3des-cbc decrypt "209225f7687ca0b2", restart, and decrypt "57156174c48dfc37293831bf192a6742,,"',function(){var r=new n.createBuffer(n.hexToBytes("a1c06b381adf36517e84575552777779da5e3d9f994b05b5")),i=new n.createBuffer(n.hexToBytes("818bcf76efc59662")),s=t.startDecrypting(r,i.copy(),null);s.update(n.createBuffer(n.hexToBytes("209225f7687ca0b2"))),s.finish(),e.equal(s.output.getBytes(),"foobar"),s.start(i.copy()),s.update(n.createBuffer(n.hexToBytes("57156174c48dfc37293831bf192a6742"))),s.finish(),e.equal(s.output.getBytes(),"foobar,,")})})}typeof define=="function"?define("test/des",["forge/des","forge/util"],function(t,n){e(ASSERT,t(),n())}):typeof module=="object"&&module.exports&&e(require("assert"),require("../../js/des")(),require("../../js/util")())}(),function(){function e(e){var t=e.asn1,n=e.pkcs7=e.pkcs7||{};n.messageFromPem=function(r){var i=e.pem.decode(r)[0];if(i.type!=="PKCS7")throw{message:'Could not convert PKCS#7 message from PEM; PEM header type is not "PKCS#7".',headerType:i.type};if(i.procType&&i.procType.type==="ENCRYPTED")throw{message:"Could not convert PKCS#7 message from PEM; PEM is encrypted."};var s=t.fromDer(i.body);return n.messageFromAsn1(s)},n.messageToPem=function(n,r){var i={type:"PKCS7",body:t.toDer(n.toAsn1()).getBytes()};return e.pem.encode(i,{maxline:r})},n.messageFromAsn1=function(r){var i={},s=[];if(!t.validate(r,n.asn1.contentInfoValidator,i,s))throw{message:"Cannot read PKCS#7 message. ASN.1 object is not an PKCS#7 ContentInfo.",errors:s};var o=t.derToOid(i.contentType),u;switch(o){case e.pki.oids.envelopedData:u=n.createEnvelopedData();break;case e.pki.oids.encryptedData:u=n.createEncryptedData();break;case e.pki.oids.signedData:u=n.createSignedData();break;default:throw{message:"Cannot read PKCS#7 message. ContentType with OID "+o+" is not (yet) supported."}}return u.fromAsn1(i.content.value[0]),u};var r=function(r){var i={},s=[];if(!t.validate(r,n.asn1.recipientInfoValidator,i,s))throw{message:"Cannot read PKCS#7 message. ASN.1 object is not an PKCS#7 EnvelopedData.",errors:s};return{version:i.version.charCodeAt(0),issuer:e.pki.RDNAttributesAsArray(i.issuer),serialNumber:e.util.createBuffer(i.serial).toHex(),encContent:{algorithm:t.derToOid(i.encAlgorithm),parameter:i.encParameter.value,content:i.encKey}}},i=function(n){return t.create(t.Class.UNIVERSAL,t.Type.SEQUENCE,!0,[t.create(t.Class.UNIVERSAL,t.Type.INTEGER,!1,String.fromCharCode(n.version)),t.create(t.Class.UNIVERSAL,t.Type.SEQUENCE,!0,[e.pki.distinguishedNameToAsn1({attributes:n.issuer}),t.create(t.Class.UNIVERSAL,t.Type.INTEGER,!1,e.util.hexToBytes(n.serialNumber))]),t.create(t.Class.UNIVERSAL,t.Type.SEQUENCE,!0,[t.create(t.Class.UNIVERSAL,t.Type.OID,!1,t.oidToDer(n.encContent.algorithm).getBytes()),t.create(t.Class.UNIVERSAL,t.Type.NULL,!1,"")]),t.create(t.Class.UNIVERSAL,t.Type.OCTETSTRING,!1,n.encContent.content)])},s=function(e){var t=[];for(var n=0;n<e.length;n++)t.push(r(e[n]));return t},o=function(e){var t=[];for(var n=0;n<e.length;n++)t.push(i(e[n]));return t},u=function(n){return[t.create(t.Class.UNIVERSAL,t.Type.OID,!1,t.oidToDer(e.pki.oids.data).getBytes()),t.create(t.Class.UNIVERSAL,t.Type.SEQUENCE,!0,[t.create(t.Class.UNIVERSAL,t.Type.OID,!1,t.oidToDer(n.algorithm).getBytes()),t.create(t.Class.UNIVERSAL,t.Type.OCTETSTRING,!1,n.parameter.getBytes())]),t.create(t.Class.CONTEXT_SPECIFIC,0,!0,[t.create(t.Class.UNIVERSAL,t.Type.OCTETSTRING,!1,n.content.getBytes())])]},a=function(n,r,i){var s={},o=[];if(!t.validate(r,i,s,o))throw{message:"Cannot read PKCS#7 message. ASN.1 object is not an PKCS#7 EnvelopedData.",errors:o};var u=t.derToOid(s.contentType);if(u!==e.pki.oids.data)throw{message:"Unsupported PKCS#7 message. Only contentType Data supported within EnvelopedData."};if(s.encContent){var a="";if(e.util.isArray(s.encContent))for(var f=0;f<s.encContent.length;++f){if(s.encContent[f].type!==t.Type.OCTETSTRING)throw{message:"Malformed PKCS#7 message, expecting encrypted content constructed of only OCTET STRING objects."};a+=s.encContent[f].value}else a=s.encContent;n.encContent={algorithm:t.derToOid(s.encAlgorithm),parameter:e.util.createBuffer(s.encParameter.value),content:e.util.createBuffer(a)}}if(s.content){var a="";if(e.util.isArray(s.content))for(var f=0;f<s.content.length;++f){if(s.content[f].type!==t.Type.OCTETSTRING)throw{message:"Malformed PKCS#7 message, expecting content constructed of only OCTET STRING objects."};a+=s.content[f].value}else a=s.content;n.content=e.util.createBuffer(a)}return n.version=s.version.charCodeAt(0),n.rawCapture=s,s},f=function(t){if(t.encContent.key===undefined)throw{message:"Symmetric key not available."};if(t.content===undefined){var n;switch(t.encContent.algorithm){case e.pki.oids["aes128-CBC"]:case e.pki.oids["aes192-CBC"]:case e.pki.oids["aes256-CBC"]:n=e.aes.createDecryptionCipher(t.encContent.key);break;case e.pki.oids["des-EDE3-CBC"]:n=e.des.createDecryptionCipher(t.encContent.key);break;default:throw{message:"Unsupported symmetric cipher, OID "+t.encContent.algorithm}}n.start(t.encContent.parameter),n.update(t.encContent.content);if(!n.finish())throw{message:"Symmetric decryption failed."};t.content=n.output}};n.createSignedData=function(){var t=null;return t={type:e.pki.oids.signedData,version:1,fromAsn1:function(e){a(t,e,n.asn1.signedDataValidator)}},t},n.createEncryptedData=function(){var t=null;return t={type:e.pki.oids.encryptedData,version:0,encContent:{algorithm:e.pki.oids["aes256-CBC"]},fromAsn1:function(e){a(t,e,n.asn1.encryptedDataValidator)},decrypt:function(e){e!==undefined&&(t.encContent.key=e),f(t)}},t},n.createEnvelopedData=function(){var r=null;return r={type:e.pki.oids.envelopedData,version:0,recipients:[],encContent:{algorithm:e.pki.oids["aes256-CBC"]},fromAsn1:function(e){var t=a(r,e,n.asn1.envelopedDataValidator);r.recipients=s(t.recipientInfos.value)},toAsn1:function(){return t.create(t.Class.UNIVERSAL,t.Type.SEQUENCE,!0,[t.create(t.Class.UNIVERSAL,t.Type.OID,!1,t.oidToDer(r.type).getBytes()),t.create(t.Class.CONTEXT_SPECIFIC,0,!0,[t.create(t.Class.UNIVERSAL,t.Type.SEQUENCE,!0,[t.create(t.Class.UNIVERSAL,t.Type.INTEGER,!1,String.fromCharCode(r.version)),t.create(t.Class.UNIVERSAL,t.Type.SET,!0,o(r.recipients)),t.create(t.Class.UNIVERSAL,t.Type.SEQUENCE,!0,u(r.encContent))])])])},findRecipient:function(e){var t=e.issuer.attributes;for(var n=0;n<r.recipients.length;++n){var i=r.recipients[n],s=i.issuer;if(i.serialNumber!==e.serialNumber)continue;if(s.length!==t.length)continue;var o=!0;for(var u=0;u<t.length;++u)if(s[u].type!==t[u].type||s[u].value!==t[u].value){o=!1;break}if(o)return i}return null},decrypt:function(t,n){if(r.encContent.key===undefined&&t!==undefined&&n!==undefined)switch(t.encContent.algorithm){case e.pki.oids.rsaEncryption:var i=n.decrypt(t.encContent.content);r.encContent.key=e.util.createBuffer(i);break;default:throw{message:"Unsupported asymmetric cipher, OID "+t.encContent.algorithm}}f(r)},addRecipient:function(t){r.recipients.push({version:0,issuer:t.subject.attributes,serialNumber:t.serialNumber,encContent:{algorithm:e.pki.oids.rsaEncryption,key:t.publicKey}})},encrypt:function(t,n){if(r.encContent.content===undefined){n=n||r.encContent.algorithm,t=t||r.encContent.key;var i,s,o;switch(n){case e.pki.oids["aes128-CBC"]:i=16,s=16,o=e.aes.createEncryptionCipher;break;case e.pki.oids["aes192-CBC"]:i=24,s=16,o=e.aes.createEncryptionCipher;break;case e.pki.oids["aes256-CBC"]:i=32,s=16,o=e.aes.createEncryptionCipher;break;case e.pki.oids["des-EDE3-CBC"]:i=24,s=8,o=e.des.createEncryptionCipher;break;default:throw{message:"Unsupported symmetric cipher, OID "+n}}if(t===undefined)t=e.util.createBuffer(e.random.getBytes(i));else if(t.length()!=i)throw{message:"Symmetric key has wrong length, got "+t.length()+" bytes, expected "+i};r.encContent.algorithm=n,r.encContent.key=t,r.encContent.parameter=e.util.createBuffer(e.random.getBytes(s));var u=o(t);u.start(r.encContent.parameter.copy()),u.update(r.content);if(!u.finish())throw{message:"Symmetric encryption failed."};r.encContent.content=u.output}for(var a=0;a<r.recipients.length;a++){var f=r.recipients[a];if(f.encContent.content!==undefined)continue;switch(f.encContent.algorithm){case e.pki.oids.rsaEncryption:f.encContent.content=f.encContent.key.encrypt(r.encContent.key.data);break;default:throw{message:"Unsupported asymmetric cipher, OID "+f.encContent.algorithm}}}}},r}}var t="pkcs7";if(typeof define!="function"){if(typeof module!="object"||!module.exports)return typeof forge=="undefined"&&(forge={}),e(forge);var n=!0;define=function(e,t){t(require,module)}}var r,i=function(n,i){i.exports=function(i){var s=r.map(function(e){return n(e)}).concat(e);i=i||{},i.defined=i.defined||{};if(i.defined[t])return i[t];i.defined[t]=!0;for(var o=0;o<s.length;++o)s[o](i);return i[t]}},s=define;define=function(e,t){return r=typeof e=="string"?t.slice(2):e.slice(2),n?(delete define,s.apply(null,Array.prototype.slice.call(arguments,0))):(define=s,define.apply(null,Array.prototype.slice.call(arguments,0)))},define("forge/pkcs7",["require","module","./aes","./asn1","./des","./pem","./pkcs7asn1","./pki","./random","./util"],function(){i.apply(null,Array.prototype.slice.call(arguments,0))})}(),function(){function e(e,t,n,r,i,s){var o={p7:"-----BEGIN PKCS7-----\r\nMIICTgYJKoZIhvcNAQcDoIICPzCCAjsCAQAxggHGMIIBwgIBADCBqTCBmzELMAkG\r\nA1UEBhMCREUxEjAQBgNVBAgMCUZyYW5jb25pYTEQMA4GA1UEBwwHQW5zYmFjaDEV\r\nMBMGA1UECgwMU3RlZmFuIFNpZWdsMRIwEAYDVQQLDAlHZWllcmxlaW4xFjAUBgNV\r\nBAMMDUdlaWVybGVpbiBERVYxIzAhBgkqhkiG9w0BCQEWFHN0ZXNpZUBicm9rZW5w\r\naXBlLmRlAgkA1FQcQNg14vMwDQYJKoZIhvcNAQEBBQAEggEAJhWQz5SniCd1w3A8\r\nuKVZEfc8Tp21I7FMfFqou+UOVsZCq7kcEa9uv2DIj3o7zD8wbLK1fuyFi4SJxTwx\r\nkR0a6V4bbonIpXPPJ1f615dc4LydAi2tv5w14LJ1Js5XCgGVnkAmQHDaW3EHXB7X\r\nT4w9PR3+tcS/5YAnWaM6Es38zCKHd7TnHpuakplIkwSK9rBFAyA1g/IyTPI+ktrE\r\nEHcVuJcz/7eTlF6wJEa2HL8F1TVWuL0p/0GsJP/8y0MYGdCdtr+TIVo//3YGhoBl\r\nN4tnheFT/jRAzfCZtflDdgAukW24CekrJ1sG2M42p5cKQ5rGFQtzNy/n8EjtUutO\r\nHD5YITBsBgkqhkiG9w0BBwEwHQYJYIZIAWUDBAEqBBBmlpfy3WrYj3uWW7+xNEiH\r\ngEAm2mfSF5xFPLEqqFkvKTM4w8PfhnF0ehmfQNApvoWQRQanNWLCT+Q9GHx6DCFj\r\nTUHl+53x88BrCl1E7FhYPs92\r\n-----END PKCS7-----\r\n",certificate:"-----BEGIN CERTIFICATE-----\r\nMIIDtDCCApwCCQDUVBxA2DXi8zANBgkqhkiG9w0BAQUFADCBmzELMAkGA1UEBhMC\r\nREUxEjAQBgNVBAgMCUZyYW5jb25pYTEQMA4GA1UEBwwHQW5zYmFjaDEVMBMGA1UE\r\nCgwMU3RlZmFuIFNpZWdsMRIwEAYDVQQLDAlHZWllcmxlaW4xFjAUBgNVBAMMDUdl\r\naWVybGVpbiBERVYxIzAhBgkqhkiG9w0BCQEWFHN0ZXNpZUBicm9rZW5waXBlLmRl\r\nMB4XDTEyMDMxODIyNTc0M1oXDTEzMDMxODIyNTc0M1owgZsxCzAJBgNVBAYTAkRF\r\nMRIwEAYDVQQIDAlGcmFuY29uaWExEDAOBgNVBAcMB0Fuc2JhY2gxFTATBgNVBAoM\r\nDFN0ZWZhbiBTaWVnbDESMBAGA1UECwwJR2VpZXJsZWluMRYwFAYDVQQDDA1HZWll\r\ncmxlaW4gREVWMSMwIQYJKoZIhvcNAQkBFhRzdGVzaWVAYnJva2VucGlwZS5kZTCC\r\nASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMsAbQ4fWevHqP1K1y/ewpMS\r\n3vYovBto7IsKBq0v3NmC2kPf3NhyaSKfjOOS5uAPONLffLck+iGdOLLFia6OSpM6\r\n0tyQIV9lHoRh7fOEYORab0Z+aBUZcEGT9yotBOraX1YbKc5f9XO+80eG4XYvb5ua\r\n1NHrxWqe4w2p3zGJCKO+wHpvGkbKz0nfu36jwWz5aihfHi9hp/xs8mfH86mIKiD7\r\nf2X2KeZ1PK9RvppA0X3lLb2VLOqMt+FHWicyZ/wjhQZ4oW55ln2yYJUQ+adlgaYn\r\nPrtnsxmbTxM+99oF0F2/HmGrNs8nLZSva1Vy+hmjmWz6/O8ZxhiIj7oBRqYcAocC\r\nAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAvfvtu31GFBO5+mFjPAoR4BlzKq/H3EPO\r\nqS8cm/TjHgDRALwSnwKYCFs/bXqE4iOTD6otV4TusX3EPbqL2vzZQEcZn6paU/oZ\r\nZVXwQqMqY5tf2teQiNxqxNmSIEPRHOr2QVBVIx2YF4Po89KGUqJ9u/3/10lDqRwp\r\nsReijr5UKv5aygEcnwcW8+Ne4rTx934UDsutKG20dr5trZfWQRVS9fS9CFwJehEX\r\nHAMUc/0++80NhfQthmWZWlWM1R3dr4TrIPtWdn5z0MtGeDvqBk7HjGrhcVS6kAsy\r\nZ9y/lfLPjBuxlQAHztEJCWgI4TW3/RLhgfg2gI1noM2n84Cdmisfkg==\r\n-----END CERTIFICATE-----\r\n",privateKey:"-----BEGIN RSA PRIVATE KEY-----\r\nMIIEowIBAAKCAQEAywBtDh9Z68eo/UrXL97CkxLe9ii8G2jsiwoGrS/c2YLaQ9/c\r\n2HJpIp+M45Lm4A840t98tyT6IZ04ssWJro5KkzrS3JAhX2UehGHt84Rg5FpvRn5o\r\nFRlwQZP3Ki0E6tpfVhspzl/1c77zR4bhdi9vm5rU0evFap7jDanfMYkIo77Aem8a\r\nRsrPSd+7fqPBbPlqKF8eL2Gn/GzyZ8fzqYgqIPt/ZfYp5nU8r1G+mkDRfeUtvZUs\r\n6oy34UdaJzJn/COFBnihbnmWfbJglRD5p2WBpic+u2ezGZtPEz732gXQXb8eYas2\r\nzyctlK9rVXL6GaOZbPr87xnGGIiPugFGphwChwIDAQABAoIBAAjMA+3QvfzRsikH\r\nzTtt09C7yJ2yNjSZ32ZHEPMAV/m1CfBXCyL2EkhF0b0q6IZdIoFA3g6xs4UxYvuc\r\nQ9Mkp2ap7elQ9aFEqIXkGIOtAOXkZV4QrEH90DeHSfax7LygqfD5TF59Gg3iAHjh\r\nB3Qvqg58LyzJosx0BjLZYaqr3Yv67GkqyflpF/roPGdClHpahAi5PBkHiNhNTAUU\r\nLJRGvMegXGZkUKgGMAiGCk0N96OZwrinMKO6YKGdtgwVWC2wbJY0trElaiwXozSt\r\nNmP6KTQp94C7rcVO6v1lZiOfhBe5Kc8QHUU+GYydgdjqm6Rdow/yLHOALAVtXSeb\r\nU+tPfcECgYEA6Qi+qF+gtPincEDBxRtoKwAlRkALt8kly8bYiGcUmd116k/5bmPw\r\nd0tBUOQbqRa1obYC88goOVzp9LInAcBSSrexhVaPAF4nrkwYXMOq+76MiH17WUfQ\r\nMgVM2IB48PBjNk1s3Crj6j1cxxkctqmCnVaI9HlU2PPZ3xjaklfv/NsCgYEA3wH8\r\nmehUhiAp7vuhd+hfomFw74cqgHC9v0saiYGckpMafh9MJGc4U5GrN1kYeb/CFkSx\r\n1hOytD3YBKoaKKoYagaMQcjxf6HnEF0f/5OiQkUQpWmgC9lNnE4XTWjnwqaTS5L9\r\nD+H50SiI3VjHymGXTRJeKpAIwV74AxxrnVofqsUCgYAwmL1B2adm9g/c7fQ6yatg\r\nhEhBrSuEaTMzmsUfNPfr2m4zrffjWH4WMqBtYRSPn4fDMHTPJ+eThtfXSqutxtCi\r\nekpP9ywdNIVr6LyP49Ita6Bc+mYVyU8Wj1pmL+yIumjGM0FHbL5Y4/EMKCV/xjvR\r\n2fD3orHaCIhf6QvzxtjqTwKBgFm6UemXKlMhI94tTsWRMNGEBU3LA9XUBvSuAkpr\r\nZRUwrQssCpXnFinBxbMqXQe3mR8emrM5D8En1P/jdU0BS3t1kP9zG4AwI2lZHuPV\r\nggbKBS2Y9zVtRKXsYcHawM13+nIA/WNjmAGJHrB45UJPy/HNvye+9lbfoEiYKdCR\r\nD4bFAoGBAIm9jcZkIwLa9kLAWH995YYYSGRY4KC29XZr2io2mog+BAjhFt1sqebt\r\nR8sRHNiIP2mcUECMOcaS+tcayi+8KTHWxIEed9qDmFu6XBbePfe/L6yxPSagcixH\r\nBK0KuK/fgTPvZCmIs8hUIC+AxhXKnqn4fIWoO54xLsALc0gEjs2d\r\n-----END RSA PRIVATE KEY-----\r\n",encryptedData:"-----BEGIN PKCS7-----\r\nMIGHBgkqhkiG9w0BBwagejB4AgEAMHMGCSqGSIb3DQEHATAUBggqhkiG9w0DBwQI\r\nupMFou5X3DWAUAqObuHSlewM0ZtHzWk9MAmtYb7MSb//OBMKVfLCdbmrS5BpKm9J\r\ngzwiDR5Od7xgfkqasLS2lOdKAvJ5jZjjTpAyrjBKpShqK9gtXDuO0zH+\r\n-----END PKCS7-----\r\n",p7IndefiniteLength:"-----BEGIN PKCS7-----\r\nMIAGCSqGSIb3DQEHA6CAMIACAQAxggHGMIIBwgIBADCBqTCBmzELMAkGA1UEBhMC\r\nREUxEjAQBgNVBAgMCUZyYW5jb25pYTEQMA4GA1UEBwwHQW5zYmFjaDEVMBMGA1UE\r\nCgwMU3RlZmFuIFNpZWdsMRIwEAYDVQQLDAlHZWllcmxlaW4xFjAUBgNVBAMMDUdl\r\naWVybGVpbiBERVYxIzAhBgkqhkiG9w0BCQEWFHN0ZXNpZUBicm9rZW5waXBlLmRl\r\nAgkA1FQcQNg14vMwDQYJKoZIhvcNAQEBBQAEggEAlWCH+E25c4jfff+m0eAxxMmE\r\nWWaftdsk4ZpAVAr7HsvxJ35bj1mhwTh7rBTg929JBKt6ZaQ4I800jCNxD2O40V6z\r\nlB7JNRqzgBwfeuU2nV6FB7v1984NBi1jQx6EfxOcusE6RL/63HqJdFbmq3Tl55gF\r\ndm3JdjmHbCXqwPhuwOXU4yhkpV1RJcrYhPLe3OrLAH7ZfoE0nPJPOX9HPTZ6ReES\r\nNToS7I9D9k7rCa8fAP7pgjO96GJGBtCHG1VXB9NX4w+xRDbgVPOeHXqqxwZhqpW2\r\nusBU4+B+MnFLjquOPoySXFfdJFwTP61TPClUdyIne5FFP6EYf98mdtnkjxHo1TCA\r\nBgkqhkiG9w0BBwEwFAYIKoZIhvcNAwcECFNtpqBmU3M9oIAESM+yyQLkreETS0Kc\r\no01yl6dqqNBczH5FNTK88ypz38/jzjo47+DURlvGzjHJibiDsCz9KyiVmgbRrtvH\r\n08rfnMbrU+grCkkx9wQI1GnLrYhr87oAAAAAAAAAAAAA\r\n-----END PKCS7-----\r\n",p73des:"-----BEGIN PKCS7-----\r\nMIICTQYJKoZIhvcNAQcDoIICPjCCAjoCAQAxggHGMIIBwgIBADCBqTCBmzELMAkG\r\nA1UEBhMCREUxEjAQBgNVBAgMCUZyYW5jb25pYTEQMA4GA1UEBwwHQW5zYmFjaDEV\r\nMBMGA1UECgwMU3RlZmFuIFNpZWdsMRIwEAYDVQQLDAlHZWllcmxlaW4xFjAUBgNV\r\nBAMMDUdlaWVybGVpbiBERVYxIzAhBgkqhkiG9w0BCQEWFHN0ZXNpZUBicm9rZW5w\r\naXBlLmRlAgkA1FQcQNg14vMwDQYJKoZIhvcNAQEBBQAEggEAS6K+sQvdKcK6YafJ\r\nmaDPjBzyjf5jtBgVrFgBXTCRIp/Z2zAXa70skfxhbwTgmilYTacA7jPGRrnLmvBc\r\nBjhyCKM3dRUyYgh1K1ka0w1prvLmRk6Onf5df1ZQn3AJMIujJZcCOhbV1ByLInve\r\nxn02KNHstGmdHM/JGyPCp+iYGprhUozVSpNCKS+R33EbsT0sAxamfqdAblT9+5Qj\r\n4CABvW11a1clPV7STwBbAKbZaLs8mDeoWP0yHvBtJ7qzZdSgJJA2oU7SDv4icwEe\r\nAhccbe2HWkLRw8G5YG9XcWx5PnQQhhnXMxkLoSMIYxItyL/cRORbpDohd+otAo66\r\nWLH1ODBrBgkqhkiG9w0BBwEwFAYIKoZIhvcNAwcECD5EWJMv1fd7gEj1w3WM1KsM\r\nL8GDk9JoqA8t9v3oXCT0nAMXoNpHZMnv+0UHHVljlSXBTQxwUP5VMY/ddquJ5O3N\r\nrDEqqJuHB+KPIsW1kxrdplU=\r\n-----END PKCS7-----\r\n"};describe("pkcs7",function(){it("should import message from PEM",function(){var r=t.messageFromPem(o.p7);e.equal(r.type,n.oids.envelopedData),e.equal(r.version,0),e.equal(r.recipients.length,1),e.equal(r.recipients[0].version,0),e.equal(r.recipients[0].serialNumber,"00d4541c40d835e2f3"),e.equal(r.recipients[0].issuer.length,7),e.equal(r.recipients[0].issuer[0].type,"2.5.4.6"),e.equal(r.recipients[0].issuer[0].value,"DE"),e.equal(r.recipients[0].issuer[1].type,"2.5.4.8"),e.equal(r.recipients[0].issuer[1].value,"Franconia"),e.equal(r.recipients[0].issuer[2].type,"2.5.4.7"),e.equal(r.recipients[0].issuer[2].value,"Ansbach"),e.equal(r.recipients[0].issuer[3].type,"2.5.4.10"),e.equal(r.recipients[0].issuer[3].value,"Stefan Siegl"),e.equal(r.recipients[0].issuer[4].type,"2.5.4.11"),e.equal(r.recipients[0].issuer[4].value,"Geierlein"),e.equal(r.recipients[0].issuer[5].type,"2.5.4.3"),e.equal(r.recipients[0].issuer[5].value,"Geierlein DEV"),e.equal(r.recipients[0].issuer[6].type,"1.2.840.113549.1.9.1"),e.equal(r.recipients[0].issuer[6].value,"stesie@brokenpipe.de"),e.equal(r.recipients[0].encContent.algorithm,n.oids.rsaEncryption),e.equal(r.recipients[0].encContent.content.length,256),e.equal(r.encContent.algorithm,n.oids["aes256-CBC"]),e.equal(r.encContent.parameter.data.length,16)}),it("should import indefinite length message from PEM",function(){e.doesNotThrow(function(){var r=t.messageFromPem(o.p7IndefiniteLength);e.equal(r.type,n.oids.envelopedData),e.equal(r.encContent.parameter.toHex(),"536da6a06653733d"),e.equal(r.encContent.content.length(),80)})}),it("should find recipient by serial number",function(){var r=t.messageFromPem(o.p7),i=n.certificateFromPem(o.certificate),s=r.findRecipient(i);e.equal(s.serialNumber,"00d4541c40d835e2f3"),i.serialNumber="1234567890abcdef42",s=r.findRecipient(i),e.equal(s,null)}),it("should aes-decrypt message",function(){var r=t.messageFromPem(o.p7),i=n.privateKeyFromPem(o.privateKey);r.decrypt(r.recipients[0],i),e.equal(r.encContent.key.data.length,32),e.equal(r.content,"Today is Boomtime, the 9th day of Discord in the YOLD 3178\r\n")}),it("should 3des-decrypt message",function(){var r=t.messageFromPem(o.p73des),i=n.privateKeyFromPem(o.privateKey);r.decrypt(r.recipients[0],i),e.equal(r.encContent.key.data.length,24),e.equal(r.content,"Today is Prickle-Prickle, the 16th day of Discord in the YOLD 3178\r\n")}),it("should add a recipient",function(){var r=t.createEnvelopedData();e.equal(r.recipients.length,0);var i=n.certificateFromPem(o.certificate);r.addRecipient(i),e.equal(r.recipients.length,1),e.deepEqual(r.recipients[0].serialNumber,i.serialNumber),e.deepEqual(r.recipients[0].issuer,i.subject.attributes),e.deepEqual(r.recipients[0].encContent.key,i.publicKey)}),it("should aes-encrypt a message",function(){var i=t.createEnvelopedData(),u=n.certificateFromPem(o.certificate),a=n.privateKeyFromPem(o.privateKey);i.addRecipient(u),i.content=s.createBuffer("Just a little test"),e.equal(i.encContent.algorithm,n.oids["aes256-CBC"]),i.encrypt(),e.equal(i.encContent.key.data.length,32),e.equal(i.encContent.parameter.data.length,16),e.equal(i.encContent.content.data.length,32),e.equal(i.recipients[0].encContent.content.length,256),i.encContent.key.read=0,i.encContent.parameter.read=0;var f=a.decrypt(i.recipients[0].encContent.content);e.equal(f,i.encContent.key.data);var l=r.createDecryptionCipher(f);l.start(i.encContent.parameter),l.update(i.encContent.content),l.finish(),e.equal(l.output,"Just a little test")}),it("should 3des-ede-encrypt a message",function(){var r=t.createEnvelopedData(),u=n.certificateFromPem(o.certificate),a=n.privateKeyFromPem(o.privateKey);r.addRecipient(u),r.content=s.createBuffer("Just a little test"),r.encContent.algorithm=n.oids["des-EDE3-CBC"],r.encrypt(),e.equal(r.encContent.key.data.length,24),e.equal(r.encContent.parameter.data.length,8),e.equal(r.encContent.content.data.length,24),e.equal(r.recipients[0].encContent.content.length,256),r.encContent.key.read=0,r.encContent.parameter.read=0;var f=a.decrypt(r.recipients[0].encContent.content);e.equal(f,r.encContent.key.data);var l=i.createDecryptionCipher(f);l.start(r.encContent.parameter),l.update(r.encContent.content),l.finish(),e.equal(l.output,"Just a little test")}),it("should export message to PEM",function(){var r=t.createEnvelopedData();r.addRecipient(n.certificateFromPem(o.certificate)),r.content=s.createBuffer("Just a little test"),r.encrypt();var i=t.messageToPem(r);r=t.messageFromPem(i),r.decrypt(r.recipients[0],n.privateKeyFromPem(o.privateKey)),e.equal(r.content,"Just a little test")}),it("should decrypt encrypted data from PEM",function(){var r="1f8b08000000000000000b2e494d4bcc5308ce4c4dcfd15130b0b430d4b7343732b03437d05170cc2b4e4a4cced051b034343532d25170492d2d294ecec849cc4b0100bf52f02437000000",i="b96e4a4c0a3555d31e1b295647cc5cfe74081918cb7f797b";i=s.createBuffer(s.hexToBytes(i)),e.doesNotThrow(function(){var u=t.messageFromPem(o.encryptedData);e.equal(u.type,n.oids.encryptedData),e.equal(u.encContent.algorithm,n.oids["des-EDE3-CBC"]),e.equal(u.encContent.parameter.toHex(),"ba9305a2ee57dc35"),e.equal(u.encContent.content.length(),80),u.decrypt(i),e.equal(u.content.getBytes(),s.hexToBytes(r))})})})}typeof define=="function"?define("test/pkcs7",["forge/pkcs7","forge/pki","forge/aes","forge/des","forge/util"],function(t,n,r,i,s){e(ASSERT,t(),n(),r(),i(),s())}):typeof module=="object"&&module.exports&&e(require("assert"),require("../../js/pkcs7")(),require("../../js/pki")(),require("../../js/aes")(),require("../../js/des")(),require("../../js/util")())}(),function(){function e(e){var t=function(t,n,r,i){var s=e.util.createBuffer(),o=t.length>>1,u=o+(t.length&1),a=t.substr(0,u),f=t.substr(o,u),l=e.util.createBuffer(),c=e.hmac.create();r=n+r;var h=Math.ceil(i/16),p=Math.ceil(i/20);c.start("MD5",a);var d=e.util.createBuffer();l.putBytes(r);for(var v=0;v<h;++v)c.start(null,null),c.update(l.getBytes()),l.putBuffer(c.digest()),c.start(null,null),c.update(l.bytes()+r),d.putBuffer(c.digest());c.start("SHA1",f);var m=e.util.createBuffer();l.clear(),l.putBytes(r);for(var v=0;v<p;++v)c.start(null,null),c.update(l.getBytes()),l.putBuffer(c.digest()),c.start(null,null),c.update(l.bytes()+r),m.putBuffer(c.digest());return s.putBytes(e.util.xorBytes(d.getBytes(),m.getBytes(),i)),s},n=function(e,t,n,r){},r=function(t,n,r){var i=e.hmac.create();i.start("SHA1",t);var s=e.util.createBuffer();return s.putInt32(n[0]),s.putInt32(n[1]),s.putByte(r.type),s.putByte(r.version.major),s.putByte(r.version.minor),s.putInt16(r.length),s.putBytes(r.fragment.bytes()),i.update(s.getBytes()),i.digest().getBytes()},i=function(t,n,r){var i=!1;try{var s=t.deflate(n.fragment.getBytes());n.fragment=e.util.createBuffer(s),n.length=s.length,i=!0}catch(o){}return i},s=function(t,n,r){var i=!1;try{var s=t.inflate(n.fragment.getBytes());n.fragment=e.util.createBuffer(s),n.length=s.length,i=!0}catch(o){}return i},o=function(t,n){var r=0;switch(n){case 1:r=t.getByte();break;case 2:r=t.getInt16();break;case 3:r=t.getInt24();break;case 4:r=t.getInt32()}return e.util.createBuffer(t.getBytes(r))},u=function(e,t,n){e.putInt(n.length(),t<<3),e.putBuffer(n)},a={};a.Version={major:3,minor:1},a.MaxFragment=15360,a.ConnectionEnd={server:0,client:1},a.PRFAlgorithm={tls_prf_sha256:0},a.BulkCipherAlgorithm={none:null,rc4:0,des3:1,aes:2},a.CipherType={stream:0,block:1,aead:2},a.MACAlgorithm={none:null,hmac_md5:0,hmac_sha1:1,hmac_sha256:2,hmac_sha384:3,hmac_sha512:4},a.CompressionMethod={none:0,deflate:1},a.ContentType={change_cipher_spec:20,alert:21,handshake:22,application_data:23},a.HandshakeType={hello_request:0,client_hello:1,server_hello:2,certificate:11,server_key_exchange:12,certificate_request:13,server_hello_done:14,certificate_verify:15,client_key_exchange:16,finished:20},a.Alert={},a.Alert.Level={warning:1,fatal:2},a.Alert.Description={close_notify:0,unexpected_message:10,bad_record_mac:20,decryption_failed:21,record_overflow:22,decompression_failure:30,handshake_failure:40,bad_certificate:42,unsupported_certificate:43,certificate_revoked:44,certificate_expired:45,certificate_unknown:46,illegal_parameter:47,unknown_ca:48,access_denied:49,decode_error:50,decrypt_error:51,export_restriction:60,protocol_version:70,insufficient_security:71,internal_error:80,user_canceled:90,no_renegotiation:100},a.CipherSuites={},a.getCipherSuite=function(e){var t=null;for(var n in a.CipherSuites){var r=a.CipherSuites[n];if(r.id[0]===e.charCodeAt(0)&&r.id[1]===e.charCodeAt(1)){t=r;break}}return t},a.handleUnexpected=function(e,t){var n=!e.open&&e.entity===a.ConnectionEnd.client;n||e.error(e,{message:"Unexpected message. Received TLS record out of order.",send:!0,alert:{level:a.Alert.Level.fatal,description:a.Alert.Description.unexpected_message}})},a.handleHelloRequest=function(e,t,n){!e.handshaking&&e.handshakes>0&&(a.queue(e,a.createAlert({level:a.Alert.Level.warning,description:a.Alert.Description.no_renegotiation})),a.flush(e)),e.process()},a.parseHelloMessage=function(t,n,r){var i=null,s=t.entity===a.ConnectionEnd.client;if(r<38)t.error(t,{message:s?"Invalid ServerHello message. Message too short.":"Invalid ClientHello message. Message too short.",send:!0,alert:{level:a.Alert.Level.fatal,description:a.Alert.Description.illegal_parameter}});else{var u=n.fragment,f=u.length();i={version:{major:u.getByte(),minor:u.getByte()},random:e.util.createBuffer(u.getBytes(32)),session_id:o(u,1),extensions:[]},s?(i.cipher_suite=u.getBytes(2),i.compression_method=u.getByte()):(i.cipher_suites=o(u,2),i.compression_methods=o(u,1)),f=r-(f-u.length());if(f>0){var l=o(u,2);while(l.length()>0)i.extensions.push({type:[l.getByte(),l.getByte()],data:o(l,2)});if(!s)for(var c=0;c<i.extensions.length;++c){var h=i.extensions[c];if(h.type[0]===0&&h.type[1]===0){var p=o(h.data,2);while(p.length()>0){var d=p.getByte();if(d!==0)break;t.session.serverNameList.push(o(p,2).getBytes())}}}}(i.version.major!==a.Version.major||i.version.minor!==a.Version.minor)&&t.error(t,{message:"Incompatible TLS version.",send:!0,alert:{level:a.Alert.Level.fatal,description:a.Alert.Description.protocol_version}});if(s)t.session.cipherSuite=a.getCipherSuite(i.cipher_suite);else{var v=e.util.createBuffer(i.cipher_suites.bytes());while(v.length()>0){t.session.cipherSuite=a.getCipherSuite(v.getBytes(2));if(t.session.cipherSuite!==null)break}}if(t.session.cipherSuite===null)return t.error(t,{message:"No cipher suites in common.",send:!0,alert:{level:a.Alert.Level.fatal,description:a.Alert.Description.handshake_failure},cipherSuite:e.util.bytesToHex(i.cipher_suite)});s?t.session.compressionMethod=i.compression_method:t.session.compressionMethod=a.CompressionMethod.none}return i},a.createSecurityParameters=function(e,t){var n=e.entity===a.ConnectionEnd.client,r=t.random.bytes(),i=n?e.session.sp.client_random:r,s=n?r:a.createRandom().getBytes();e.session.sp={entity:e.entity,prf_algorithm:a.PRFAlgorithm.tls_prf_sha256,bulk_cipher_algorithm:null,cipher_type:null,enc_key_length:null,block_length:null,fixed_iv_length:null,record_iv_length:null,mac_algorithm:null,mac_length:null,mac_key_length:null,compression_algorithm:e.session.compressionMethod,pre_master_secret:null,master_secret:null,client_random:i,server_random:s}},a.handleServerHello=function(e,t,n){var r=a.parseHelloMessage(e,t,n);if(!e.fail){var i=r.session_id.bytes();i===e.session.id?(e.expect=d,e.session.resuming=!0,e.session.sp.server_random=r.random.bytes()):(e.expect=l,e.session.resuming=!1,a.createSecurityParameters(e,r)),e.session.id=i,e.process()}},a.handleClientHello=function(t,n,r){var i=a.parseHelloMessage(t,n,r);if(!t.fail){var s=i.session_id.bytes(),o=null;t.sessionCache&&(o=t.sessionCache.getSession(s),o===null&&(s="")),s.length===0&&(s=e.random.getBytes(32)),t.session.id=s,t.session.clientHelloVersion=i.version,t.session.sp=o?o.sp:{},o!==null?(t.expect=S,t.session.resuming=!0,t.session.sp.client_random=i.random.bytes()):(t.expect=t.verifyClient!==!1?b:w,t.session.resuming=!1,a.createSecurityParameters(t,i)),t.open=!0,a.queue(t,a.createRecord({type:a.ContentType.handshake,data:a.createServerHello(t)})),t.session.resuming?(a.queue(t,a.createRecord({type:a.ContentType.change_cipher_spec,data:a.createChangeCipherSpec()})),t.state.pending=a.createConnectionState(t),t.state.current.write=t.state.pending.write,a.queue(t,a.createRecord({type:a.ContentType.handshake,data:a.createFinished(t)}))):(a.queue(t,a.createRecord({type:a.ContentType.handshake,data:a.createCertificate(t)})),t.fail||(a.queue(t,a.createRecord({type:a.ContentType.handshake,data:a.createServerKeyExchange(t)})),t.verifyClient!==!1&&a.queue(t,a.createRecord({type:a.ContentType.handshake,data:a.createCertificateRequest(t)})),a.queue(t,a.createRecord({type:a.ContentType.handshake,data:a.createServerHelloDone(t)})))),a.flush(t),t.process()}},a.handleCertificate=function(t,n,r){if(r<3)t.error(t,{message:"Invalid Certificate message. Message too short.",send:!0,alert:{level:a.Alert.Level.fatal,description:a.Alert.Description.illegal_parameter}});else{var i=n.fragment,s={certificate_list:o(i,3)},u,f,l=[];try{while(s.certificate_list.length()>0)u=o(s.certificate_list,3),f=e.asn1.fromDer(u),u=e.pki.certificateFromAsn1(f,!0),l.push(u)}catch(h){t.error(t,{message:"Could not parse certificate list.",cause:h,send:!0,alert:{level:a.Alert.Level.fatal,description:a.Alert.Description.bad_certificate}})}if(!t.fail){var p=t.entity===a.ConnectionEnd.client;!p&&t.verifyClient!==!0||l.length!==0?l.length===0?t.expect=p?c:w:(p?t.session.serverCertificate=l[0]:t.session.clientCertificate=l[0],a.verifyCertificateChain(t,l)&&(t.expect=p?c:w)):t.error(t,{message:p?"No server certificate provided.":"No client certificate provided.",send:!0,alert:{level:a.Alert.Level.fatal,description:a.Alert.Description.illegal_parameter}}),t.process()}}},a.handleServerKeyExchange=function(e,t,n){n>0?e.error(e,{message:"Invalid key parameters. Only RSA is supported.",send:!0,alert:{level:a.Alert.Level.fatal,description:a.Alert.Description.unsupported_certificate}}):(e.expect=h,e.process())},a.handleClientKeyExchange=function(t,n,r){if(r<48)t.error(t,{message:"Invalid key parameters. Only RSA is supported.",send:!0,alert:{level:a.Alert.Level.fatal,description:a.Alert.Description.unsupported_certificate}});else{var i=n.fragment,s={enc_pre_master_secret:o(i,2).getBytes()},u=null;if(t.getPrivateKey)try{u=t.getPrivateKey(t,t.session.serverCertificate),u=e.pki.privateKeyFromPem(u)}catch(f){t.error(t,{message:"Could not get private key.",cause:f,send:!0,alert:{level:a.Alert.Level.fatal,description:a.Alert.Description.internal_error}})}if(u===null)t.error(t,{message:"No private key set.",send:!0,alert:{level:a.Alert.Level.fatal,description:a.Alert.Description.internal_error}});else try{var l=t.session.sp;l.pre_master_secret=u.decrypt(s.enc_pre_master_secret);var c=t.session.clientHelloVersion;if(c.major!==l.pre_master_secret.charCodeAt(0)||c.minor!==l.pre_master_secret.charCodeAt(1))throw{message:"TLS version rollback attack detected."}}catch(f){l.pre_master_secret=e.random.getBytes(48)}}t.fail||(t.expect=S,t.session.clientCertificate!==null&&(t.expect=E),t.process())},a.handleCertificateRequest=function(e,t,n){if(n<3)e.error(e,{message:"Invalid CertificateRequest. Message too short.",send:!0,alert:{level:a.Alert.Level.fatal,description:a.Alert.Description.illegal_parameter}});else{var r=t.fragment,i={certificate_types:o(r,1),certificate_authorities:o(r,2)};e.session.certificateRequest=i,e.expect=p,e.process()}},a.handleCertificateVerify=function(t,n,r){if(r<2)t.error(t,{message:"Invalid CertificateVerify. Message too short.",send:!0,alert:{level:a.Alert.Level.fatal,description:a.Alert.Description.illegal_parameter}});else{var i=n.fragment;i.read-=4;var s=i.bytes();i.read+=4;var u={signature:o(i,2).getBytes()},f=e.util.createBuffer();f.putBuffer(t.session.md5.digest()),f.putBuffer(t.session.sha1.digest()),f=f.getBytes();try{var l=t.session.clientCertificate;if(!l.publicKey.verify(f,u.signature,"NONE"))throw{message:"CertificateVerify signature does not match."};t.session.md5.update(s),t.session.sha1.update(s)}catch(c){t.error(t,{message:"Bad signature in CertificateVerify.",send:!0,alert:{level:a.Alert.Level.fatal,description:a.Alert.Description.handshake_failure}})}t.fail||(t.expect=S,t.process())}},a.handleServerHelloDone=function(t,n,r){if(r>0)t.error(t,{message:"Invalid ServerHelloDone message. Invalid length.",send:!0,alert:{level:a.Alert.Level.fatal,description:a.Alert.Description.record_overflow}});else if(t.serverCertificate===null){var i={message:"No server certificate provided. Not enough security.",send:!0,alert:{level:a.Alert.Level.fatal,description:a.Alert.Description.insufficient_security}},s=t.verify(t,i.alert.description,depth,[]);if(s===!0)i=null;else{if(s||s===0)typeof s=="object"&&!e.util.isArray(s)?(s.message&&(i.message=s.message),s.alert&&(i.alert.description=s.alert)):typeof s=="number"&&(i.alert.description=s);t.error(t,i)}}!t.fail&&t.session.certificateRequest!==null&&(n=a.createRecord({type:a.ContentType.handshake,data:a.createCertificate(t)}),a.queue(t,n));if(!t.fail){n=a.createRecord({type:a.ContentType.handshake,data:a.createClientKeyExchange(t)}),a.queue(t,n),t.expect=g;var o=function(e,t){e.session.certificateRequest!==null&&e.session.clientCertificate!==null&&a.queue(e,a.createRecord({type:a.ContentType.handshake,data:a.createCertificateVerify(e,t)})),a.queue(e,a.createRecord({type:a.ContentType.change_cipher_spec,data:a.createChangeCipherSpec()})),e.state.pending=a.createConnectionState(e),e.state.current.write=e.state.pending.write,a.queue(e,a.createRecord({type:a.ContentType.handshake,data:a.createFinished(e)})),e.expect=d,a.flush(e),e.process()};t.session.certificateRequest===null||t.session.clientCertificate===null?o(t,null):a.getClientSignature(t,o)}},a.handleChangeCipherSpec=function(e,t){if(t.fragment.getByte()!==1)e.error(e,{message:"Invalid ChangeCipherSpec message received.",send:!0,alert:{level:a.Alert.Level.fatal,description:a.Alert.Description.illegal_parameter}});else{var n=e.entity===a.ConnectionEnd.client;if(e.session.resuming&&n||!e.session.resuming&&!n)e.state.pending=a.createConnectionState(e);e.state.current.read=e.state.pending.read;if(!e.session.resuming&&n||e.session.resuming&&!n)e.state.pending=null;e.expect=n?v:x,e.process()}},a.handleFinished=function(n,r,i){var s=r.fragment;s.read-=4;var o=s.bytes();s.read+=4;var u=r.fragment.getBytes();s=e.util.createBuffer(),s.putBuffer(n.session.md5.digest()),s.putBuffer(n.session.sha1.digest());var f=n.entity===a.ConnectionEnd.client,l=f?"server finished":"client finished",c=n.session.sp,h=12,p=t;s=p(c.master_secret,l,s.getBytes(),h);if(s.getBytes()!==u)n.error(n,{message:"Invalid verify_data in Finished message.",send:!0,alert:{level:a.Alert.Level.fatal,description:a.Alert.Description.decrypt_error}});else{n.session.md5.update(o),n.session.sha1.update(o);if(n.session.resuming&&f||!n.session.resuming&&!f)a.queue(n,a.createRecord({type:a.ContentType.change_cipher_spec,data:a.createChangeCipherSpec()})),n.state.current.write=n.state.pending.write,n.state.pending=null,a.queue(n,a.createRecord({type:a.ContentType.handshake,data:a.createFinished(n)}));n.expect=f?m:T,n.handshaking=!1,++n.handshakes,n.peerCertificate=f?n.session.serverCertificate:n.session.clientCertificate,n.sessionCache?(n.session={id:n.session.id,sp:n.session.sp},n.session.sp.keys=null):n.session=null,a.flush(n),n.isConnected=!0,n.connected(n),n.process()}},a.handleAlert=function(e,t){var n=t.fragment,r={level:n.getByte(),description:n.getByte()},i;switch(r.description){case a.Alert.Description.close_notify:i="Connection closed.";break;case a.Alert.Description.unexpected_message:i="Unexpected message.";break;case a.Alert.Description.bad_record_mac:i="Bad record MAC.";break;case a.Alert.Description.decryption_failed:i="Decryption failed.";break;case a.Alert.Description.record_overflow:i="Record overflow.";break;case a.Alert.Description.decompression_failure:i="Decompression failed.";break;case a.Alert.Description.handshake_failure:i="Handshake failure.";break;case a.Alert.Description.bad_certificate:i="Bad certificate.";break;case a.Alert.Description.unsupported_certificate:i="Unsupported certificate.";break;case a.Alert.Description.certificate_revoked:i="Certificate revoked.";break;case a.Alert.Description.certificate_expired:i="Certificate expired.";break;case a.Alert.Description.certificate_unknown:i="Certificate unknown.";break;case a.Alert.Description.illegal_parameter:i="Illegal parameter.";break;case a.Alert.Description.unknown_ca:i="Unknown certificate authority.";break;case a.Alert.Description.access_denied:i="Access denied.";break;case a.Alert.Description.decode_error:i="Decode error.";break;case a.Alert.Description.decrypt_error:i="Decrypt error.";break;case a.Alert.Description.export_restriction:i="Export restriction.";break;case a.Alert.Description.protocol_version:i="Unsupported protocol version.";break;case a.Alert.Description.insufficient_security:i="Insufficient security.";break;case a.Alert.Description.internal_error:i="Internal error.";break;case a.Alert.Description.user_canceled:i="User canceled.";break;case a.Alert.Description.no_renegotiation:i="Renegotiation not supported.";break;default:i="Unknown error."}r.description===a.Alert.Description.close_notify?e.close():(e.error(e,{message:i,send:!1,origin:e.entity===a.ConnectionEnd.client?"server":"client",alert:r}),e.process())},a.handleHandshake=function(t,n){var r=n.fragment,i=r.getByte(),s=r.getInt24();if(s>r.length())t.fragmented=n,n.fragment=e.util.createBuffer(),r.read-=4,t.process();else{t.fragmented=null,r.read-=4;var o=r.bytes(s+4);r.read+=4,i in I[t.entity][t.expect]?(t.entity===a.ConnectionEnd.server&&!t.open&&!t.fail&&(t.handshaking=!0,t.session={serverNameList:[],cipherSuite:null,compressionMethod:null,serverCertificate:null,clientCertificate:null,md5:e.md.md5.create(),sha1:e.md.sha1.create()}),i!==a.HandshakeType.hello_request&&i!==a.HandshakeType.certificate_verify&&i!==a.HandshakeType.finished&&(t.session.md5.update(o),t.session.sha1.update(o)),I[t.entity][t.expect][i](t,n,s)):a.handleUnexpected(t,n)}},a.handleApplicationData=function(e,t){e.data.putBuffer(t.fragment),e.dataReady(e),e.process()};var f=0,l=1,c=2,h=3,p=4,d=5,v=6,m=7,g=8,y=0,b=1,w=2,E=3,S=4,x=5,T=6,N=7,C=a.handleUnexpected,k=a.handleChangeCipherSpec,L=a.handleAlert,A=a.handleHandshake,O=a.handleApplicationData,M=[];M[a.ConnectionEnd.client]=[[C,L,A,C],[C,L,A,C],[C,L,A,C],[C,L,A,C],[C,L,A,C],[k,L,C,C],[C,L,A,C],[C,L,A,O],[C,L,A,C]],M[a.ConnectionEnd.server]=[[C,L,A,C],[C,L,A,C],[C,L,A,C],[C,L,A,C],[k,L,C,C],[C,L,A,C],[C,L,A,O],[C,L,A,C]];var _=a.handleHelloRequest,D=a.handleServerHello,P=a.handleCertificate,H=a.handleServerKeyExchange,B=a.handleCertificateRequest,j=a.handleServerHelloDone,F=a.handleFinished,I=[];I[a.ConnectionEnd.client]=[[C,C,D,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C],[_,C,C,C,C,C,C,C,C,C,C,P,H,B,j,C,C,C,C,C,C],[_,C,C,C,C,C,C,C,C,C,C,C,H,B,j,C,C,C,C,C,C],[_,C,C,C,C,C,C,C,C,C,C,C,C,B,j,C,C,C,C,C,C],[_,C,C,C,C,C,C,C,C,C,C,C,C,C,j,C,C,C,C,C,C],[_,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C],[_,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,F],[_,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C],[_,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C]];var q=a.handleClientHello,R=a.handleClientKeyExchange,U=a.handleCertificateVerify;I[a.ConnectionEnd.server]=[[C,q,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C],[C,C,C,C,C,C,C,C,C,C,C,P,C,C,C,C,C,C,C,C,C],[C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,R,C,C,C,C],[C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,U,C,C,C,C,C],[C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C],[C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,F],[C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C],[C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C]],a.generateKeys=function(e,n){var r=t,i=n.client_random+n.server_random;e.session.resuming||(n.master_secret=r(n.pre_master_secret,"master secret",i,48).bytes(),n.pre_master_secret=null),i=n.server_random+n.client_random;var s=2*n.mac_key_length+2*n.enc_key_length+2*n.fixed_iv_length,o=r(n.master_secret,"key expansion",i,s);return{client_write_MAC_key:o.getBytes(n.mac_key_length),server_write_MAC_key:o.getBytes(n.mac_key_length),client_write_key:o.getBytes(n.enc_key_length),server_write_key:o.getBytes(n.enc_key_length),client_write_IV:o.getBytes(n.fixed_iv_length),server_write_IV:o.getBytes(n.fixed_iv_length)}},a.createConnectionState=function(e){var t=e.entity===a.ConnectionEnd.client,n=function(){var e={sequenceNumber:[0,0],macKey:null,macLength:0,macFunction:null,cipherState:null,cipherFunction:function(e){return!0},compressionState:null,compressFunction:function(e){return!0},updateSequenceNumber:function(){e.sequenceNumber[1]===4294967295?(e.sequenceNumber[1]=0,++e.sequenceNumber[0]):++e.sequenceNumber[1]}};return e},r={read:n(),write:n()};r.read.update=function(e,t){return r.read.cipherFunction(t,r.read)?r.read.compressFunction(e,t,r.read)||e.error(e,{message:"Could not decompress record.",send:!0,alert:{level:a.Alert.Level.fatal,description:a.Alert.Description.decompression_failure}}):e.error(e,{message:"Could not decrypt record or bad MAC.",send:!0,alert:{level:a.Alert.Level.fatal,description:a.Alert.Description.bad_record_mac}}),!e.fail},r.write.update=function(e,t){return r.write.compressFunction(e,t,r.write)?r.write.cipherFunction(t,r.write)||e.error(e,{message:"Could not encrypt record.",send:!1,alert:{level:a.Alert.Level.fatal,description:a.Alert.Description.internal_error}}):e.error(e,{message:"Could not compress record.",send:!1,alert:{level:a.Alert.Level.fatal,description:a.Alert.Description.internal_error}}),!e.fail};if(e.session){var o=e.session.sp;e.session.cipherSuite.initSecurityParameters(o),o.keys=a.generateKeys(e,o),r.read.macKey=t?o.keys.server_write_MAC_key:o.keys.client_write_MAC_key,r.write.macKey=t?o.keys.client_write_MAC_key:o.keys.server_write_MAC_key,e.session.cipherSuite.initConnectionState(r,e,o);switch(o.compression_algorithm){case a.CompressionMethod.none:break;case a.CompressionMethod.deflate:r.read.compressFunction=s,r.write.compressFunction=i;break;default:throw{message:"Unsupported compression algorithm."}}}return r},a.createRandom=function(){var t=new Date,n=+t+t.getTimezoneOffset()*6e4,r=e.util.createBuffer();return r.putInt32(n),r.putBytes(e.random.getBytes(28)),r},a.createRecord=function(e){if(!e.data)return null;var t={type:e.type,version:{major:a.Version.major,minor:a.Version.minor},length:e.data.length(),fragment:e.data};return t},a.createAlert=function(t){var n=e.util.createBuffer();return n.putByte(t.level),n.putByte(t.description),a.createRecord({type:a.ContentType.alert,data:n})},a.createClientHello=function(t){var n=e.util.createBuffer();for(var r=0;r<t.cipherSuites.length;++r){var i=t.cipherSuites[r];n.putByte(i.id[0]),n.putByte(i.id[1])}var s=n.length(),o=e.util.createBuffer();o.putByte(a.CompressionMethod.none);var f=o.length(),l=e.util.createBuffer();if(t.virtualHost){var c=e.util.createBuffer();c.putByte(0),c.putByte(0);var h=e.util.createBuffer();h.putByte(0),u(h,2,e.util.createBuffer(t.virtualHost));var p=e.util.createBuffer();u(p,2,h),u(c,2,p),l.putBuffer(c)}var d=l.length();d>0&&(d+=2);var v=t.session.id,m=v.length+1+2+4+28+2+s+1+f+d,g=e.util.createBuffer();return g.putByte(a.HandshakeType.client_hello),g.putInt24(m),g.putByte(a.Version.major),g.putByte(a.Version.minor),g.putBytes(t.session.sp.client_random),u(g,1,e.util.createBuffer(v)),u(g,2,n),u(g,1,o),d>0&&u(g,2,l),g},a.createServerHello=function(t){var n=t.session.id,r=n.length+1+2+4+28+2+1,i=e.util.createBuffer();return i.putByte(a.HandshakeType.server_hello),i.putInt24(r),i.putByte(a.Version.major),i.putByte(a.Version.minor),i.putBytes(t.session.sp.server_random),u(i,1,e.util.createBuffer(n)),i.putByte(t.session.cipherSuite.id[0]),i.putByte(t.session.cipherSuite.id[1]),i.putByte(t.session.compressionMethod),i},a.createCertificate=function(t){var n=t.entity===a.ConnectionEnd.client,r=null;t.getCertificate&&(r=t.getCertificate(t,n?t.session.certificateRequest:t.session.serverNameList));var i=e.util.createBuffer();if(r!==null)try{e.util.isArray(r)||(r=[r]);var s=null;for(var o=0;o<r.length;++o){var f=e.pem.decode(r[o])[0];if(f.type!=="CERTIFICATE"&&f.type!=="X509 CERTIFICATE"&&f.type!=="TRUSTED CERTIFICATE")throw{message:'Could not convert certificate from PEM; PEM header type is not "CERTIFICATE", "X509 CERTIFICATE", or "TRUSTED CERTIFICATE".',headerType:f.type};if(f.procType&&f.procType.type==="ENCRYPTED")throw{message:"Could not convert certificate from PEM; PEM is encrypted."};var l=e.util.createBuffer(f.body);s===null&&(s=e.asn1.fromDer(l.bytes(),!1));var c=e.util.createBuffer();u(c,3,l),i.putBuffer(c)}r=e.pki.certificateFromAsn1(s),n?t.session.clientCertificate=r:t.session.serverCertificate=r}catch(h){return t.error(t,{message:"Could not send certificate list.",cause:h,send:!0,alert:{level:a.Alert.Level.fatal,description:a.Alert.Description.bad_certificate}})}var p=3+i.length(),d=e.util.createBuffer();return d.putByte(a.HandshakeType.certificate),d.putInt24(p),u(d,3,i),d},a.createClientKeyExchange=function(t){var n=e.util.createBuffer();n.putByte(a.Version.major),n.putByte(a.Version.minor),n.putBytes(e.random.getBytes(46));var r=t.session.sp;r.pre_master_secret=n.getBytes();var i=t.session.serverCertificate.publicKey;n=i.encrypt(r.pre_master_secret);var s=n.length+2,o=e.util.createBuffer();return o.putByte(a.HandshakeType.client_key_exchange),o.putInt24(s),o.putInt16(n.length),o.putBytes(n),o},a.createServerKeyExchange=function(t){var n=0,r=e.util.createBuffer();return n>0&&(r.putByte(a.HandshakeType.server_key_exchange),r.putInt24(n)),r},a.getClientSignature=function(t,n){var r=e.util.createBuffer();r.putBuffer(t.session.md5.digest()),r.putBuffer(t.session.sha1.digest()),r=r.getBytes(),t.getSignature=t.getSignature||function(t,n,r){var i=null;if(t.getPrivateKey)try{i=t.getPrivateKey(t,t.session.clientCertificate),i=e.pki.privateKeyFromPem(i)}catch(s){t.error(t,{message:"Could not get private key.",cause:s,send:!0,alert:{level:a.Alert.Level.fatal,description:a.Alert.Description.internal_error}})}i===null?t.error(t,{message:"No private key set.",send:!0,alert:{level:a.Alert.Level.fatal,description:a.Alert.Description.internal_error}}):n=i.sign(n,null),r(t,n)},t.getSignature(t,r,n)},a.createCertificateVerify=function(t,n){var r=n.length+2,i=e.util.createBuffer();return i.putByte(a.HandshakeType.certificate_verify),i.putInt24(r),i.putInt16(n.length),i.putBytes(n),i},a.createCertificateRequest=function(t){var n=e.util.createBuffer();n.putByte(1);var r=e.util.createBuffer();for(var i in t.caStore.certs){var s=t.caStore.certs[i],o=e.pki.distinguishedNameToAsn1(s.subject);r.putBuffer(e.asn1.toDer(o))}var f=1+n.length()+2+r.length(),l=e.util.createBuffer();return l.putByte(a.HandshakeType.certificate_request),l.putInt24(f),u(l,1,n),u(l,2,r),l},a.createServerHelloDone=function(t){var n=e.util.createBuffer();return n.putByte(a.HandshakeType.server_hello_done),n.putInt24(0),n},a.createChangeCipherSpec=function(){var t=e.util.createBuffer();return t.putByte(1),t},a.createFinished=function(n){var r=e.util.createBuffer();r.putBuffer(n.session.md5.digest()),r.putBuffer(n.session.sha1.digest());var i=n.entity===a.ConnectionEnd.client,s=n.session.sp,o=12,u=t,f=i?"client finished":"server finished";r=u(s.master_secret,f,r.getBytes(),o);var l=e.util.createBuffer();return l.putByte(a.HandshakeType.finished),l.putInt24(r.length()),l.putBuffer(r),l},a.queue=function(t,n){if(!n)return;if(n.type===a.ContentType.handshake){var r=n.fragment.bytes();t.session.md5.update(r),t.session.sha1.update(r),r=null}var i;if(n.fragment.length()<=a.MaxFragment)i=[n];else{i=[];var s=n.fragment.bytes();while(s.length>a.MaxFragment)i.push(a.createRecord({type:n.type,data:e.util.createBuffer(s.slice(0,a.MaxFragment))})),s=s.slice(a.MaxFragment);s.length>0&&i.push(a.createRecord({type:n.type,data:e.util.createBuffer(s)}))}for(var o=0;o<i.length&&!t.fail;++o){var u=i[o],f=t.state.current.write;f.update(t,u)&&t.records.push(u)}},a.flush=function(e){for(var t=0;t<e.records.length;++t){var n=e.records[t];e.tlsData.putByte(n.type),e.tlsData.putByte(n.version.major),e.tlsData.putByte(n.version.minor),e.tlsData.putInt16(n.fragment.length()),e.tlsData.putBuffer(e.records[t].fragment)}return e.records=[],e.tlsDataReady(e)};var z=function(t){switch(t){case!0:return!0;case e.pki.certificateError.bad_certificate:return a.Alert.Description.bad_certificate;case e.pki.certificateError.unsupported_certificate:return a.Alert.Description.unsupported_certificate;case e.pki.certificateError.certificate_revoked:return a.Alert.Description.certificate_revoked;case e.pki.certificateError.certificate_expired:return a.Alert.Description.certificate_expired;case e.pki.certificateError.certificate_unknown:return a.Alert.Description.certificate_unknown;case e.pki.certificateError.unknown_ca:return a.Alert.Description.unknown_ca;default:return a.Alert.Description.bad_certificate}},W=function(t){switch(t){case!0:return!0;case a.Alert.Description.bad_certificate:return e.pki.certificateError.bad_certificate;case a.Alert.Description.unsupported_certificate:return e.pki.certificateError.unsupported_certificate;case a.Alert.Description.certificate_revoked:return e.pki.certificateError.certificate_revoked;case a.Alert.Description.certificate_expired:return e.pki.certificateError.certificate_expired;case a.Alert.Description.certificate_unknown:return e.pki.certificateError.certificate_unknown;case a.Alert.Description.unknown_ca:return e.pki.certificateError.unknown_ca;default:return e.pki.certificateError.bad_certificate}};a.verifyCertificateChain=function(t,n){try{e.pki.verifyCertificateChain(t.caStore,n,function(r,i,s){var o=z(r),u=t.verify(t,r,i,s);if(u!==!0){if(typeof u=="object"&&!e.util.isArray(u)){var f={message:"The application rejected the certificate.",send:!0,alert:{level:a.Alert.Level.fatal,description:a.Alert.Description.bad_certificate}};throw u.message&&(f.message=u.message),u.alert&&(f.alert.description=u.alert),f}u!==r&&(u=W(u))}return u})}catch(r){if(typeof r!="object"||e.util.isArray(r))r={send:!0,alert:{level:a.Alert.Level.fatal,description:z(r)}};"send"in r||(r.send=!0),"alert"in r||(r.alert={level:a.Alert.Level.fatal,description:z(r.error)}),t.error(t,r)}return!t.fail},a.createSessionCache=function(t,n){var r=null;if(t&&t.getSession&&t.setSession&&t.order)r=t;else{r={},r.cache=t||{},r.capacity=Math.max(n||100,1),r.order=[];for(var i in t)r.order.length<=n?r.order.push(i):delete t[i];r.getSession=function(t){var n=null,i=null;t?i=e.util.bytesToHex(t):r.order.length>0&&(i=r.order[0]);if(i!==null&&i in r.cache){n=r.cache[i],delete r.cache[i];for(var s in r.order)if(r.order[s]===i){r.order.splice(s,1);break}}return n},r.setSession=function(t,n){if(r.order.length===r.capacity){var i=r.order.shift();delete r.cache[i]}var i=e.util.bytesToHex(t);r.order.push(i),r.cache[i]=n}}return r},a.createConnection=function(t){var n=null;t.caStore?e.util.isArray(t.caStore)?n=e.pki.createCaStore(t.caStore):n=t.caStore:n=e.pki.createCaStore();var r=t.cipherSuites||null;if(r===null){r=[];for(var i in a.CipherSuites)r.push(a.CipherSuites[i])}var s=t.server||!1?a.ConnectionEnd.server:a.ConnectionEnd.client,o=t.sessionCache?a.createSessionCache(t.sessionCache):null,u={entity:s,sessionId:t.sessionId,caStore:n,sessionCache:o,cipherSuites:r,connected:t.connected,virtualHost:t.virtualHost||null,verifyClient:t.verifyClient||!1,verify:t.verify||function(e,t,n,r){return t},getCertificate:t.getCertificate||null,getPrivateKey:t.getPrivateKey||null,getSignature:t.getSignature||null,input:e.util.createBuffer(),tlsData:e.util.createBuffer(),data:e.util.createBuffer(),tlsDataReady:t.tlsDataReady,dataReady:t.dataReady,closed:t.closed,error:function(e,n){n.origin=n.origin||(e.entity===a.ConnectionEnd.client?"client":"server"),n.send&&(a.queue(e,a.createAlert(n.alert)),a.flush(e));var r=n.fatal!==!1;r&&(e.fail=!0),t.error(e,n),r&&e.close(!1)},deflate:t.deflate||null,inflate:t.inflate||null};u.reset=function(e){u.record=null,u.session=null,u.peerCertificate=null,u.state={pending:null,current:null},u.expect=u.entity===a.ConnectionEnd.client?f:y,u.fragmented=null,u.records=[],u.open=!1,u.handshakes=0,u.handshaking=!1,u.isConnected=!1,u.fail=!e&&typeof e!="undefined",u.input.clear(),u.tlsData.clear(),u.data.clear(),u.state.current=a.createConnectionState(u)},u.reset();var l=function(e,t){var n=t.type-a.ContentType.change_cipher_spec,r=M[e.entity][e.expect];n in r?r[n](e,t):a.handleUnexpected(e,t)},c=function(t){var n=0,r=t.input,i=r.length();return i<5?n=5-i:(t.record={type:r.getByte(),version:{major:r.getByte(),minor:r.getByte()},length:r.getInt16(),fragment:e.util.createBuffer(),ready:!1},(t.record.version.major!==a.Version.major||t.record.version.minor!==a.Version.minor)&&t.error(t,{message:"Incompatible TLS version.",send:!0,alert:{level:a.Alert.Level.fatal,description:a.Alert.Description.protocol_version}})),n},h=function(e){var t=0,n=e.input,r=n.length();if(r<e.record.length)t=e.record.length-r;else{e.record.fragment.putBytes(n.getBytes(e.record.length));var i=e.state.current.read;i.update(e,e.record)&&(e.fragmented!==null&&(e.fragmented.type===e.record.type?(e.fragmented.fragment.putBuffer(e.record.fragment),e.record=e.fragmented):e.error(e,{message:"Invalid fragmented record.",send:!0,alert:{level:a.Alert.Level.fatal,description:a.Alert.Description.unexpected_message}})),e.record.ready=!0)}return t};return u.handshake=function(t){if(u.entity!==a.ConnectionEnd.client)u.error(u,{message:"Cannot initiate handshake as a server.",fatal:!1});else if(u.handshaking)u.error(u,{message:"Handshake already in progress.",fatal:!1});else{u.fail&&!u.open&&u.handshakes===0&&(u.fail=!1),u.handshaking=!0,t=t||"";var n=null;t.length>0&&(u.sessionCache&&(n=u.sessionCache.getSession(t)),n===null&&(t="")),t.length===0&&u.sessionCache&&(n=u.sessionCache.getSession(),n!==null&&(t=n.id)),u.session={id:t,cipherSuite:null,compressionMethod:null,serverCertificate:null,certificateRequest:null,clientCertificate:null,sp:n?n.sp:{},md5:e.md.md5.create(),sha1:e.md.sha1.create()},u.session.sp.client_random=a.createRandom().getBytes(),u.open=!0,a.queue(u,a.createRecord({type:a.ContentType.handshake,data:a.createClientHello(u)})),a.flush(u)}},u.process=function(e){var t=0;return e&&u.input.putBytes(e),u.fail||(u.record!==null&&u.record.ready&&u.record.fragment.isEmpty()&&(u.record=null),u.record===null&&(t=c(u)),!u.fail&&u.record!==null&&!u.record.ready&&(t=h(u)),!u.fail&&u.record!==null&&u.record.ready&&l(u,u.record)),t},u.prepare=function(t){return a.queue(u,a.createRecord({type:a.ContentType.application_data,data:e.util.createBuffer(t)})),a.flush(u)},u.close=function(e){!u.fail&&u.sessionCache&&u.session&&u.sessionCache.setSession(u.session.id,u.session);if(u.open){u.open=!1,u.input.clear();if(u.isConnected||u.handshaking)u.isConnected=u.handshaking=!1,a.queue(u,a.createAlert({level:a.Alert.Level.warning,description:a.Alert.Description.close_notify})),a.flush(u);u.closed(u)}u.reset(e)},u},e.tls=e.tls||{};for(var X in a)typeof a[X]!="function"&&(e.tls[X]=a[X]);e.tls.prf_tls1=t,e.tls.hmac_sha1=r,e.tls.createSessionCache=a.createSessionCache,e.tls.createConnection=a.createConnection}var t="tls";if(typeof define!="function"){if(typeof module!="object"||!module.exports)return typeof forge=="undefined"&&(forge={}),e(forge);var n=!0;define=function(e,t){t(require,module)}}var r,i=function(n,i){i.exports=function(i){var s=r.map(function(e){return n(e)}).concat(e);i=i||{},i.defined=i.defined||{};if(i.defined[t])return i[t];i.defined[t]=!0;for(var o=0;o<s.length;++o)s[o](i);return i[t]}},s=define;define=function(e,t){return r=typeof e=="string"?t.slice(2):e.slice(2),n?(delete define,s.apply(null,Array.prototype.slice.call(arguments,0))):(define=s,define.apply(null,Array.prototype.slice.call(arguments,0)))},define("forge/tls",["require","module","./asn1","./hmac","./md","./pem","./pki","./random","./util"],function(){i.apply(null,Array.prototype.slice.call(arguments,0))})}(),function(){function e(e){function n(n,i,s){var u=i.entity===e.tls.ConnectionEnd.client;n.read.cipherState={init:!1,cipher:e.aes.createDecryptionCipher(u?s.keys.server_write_key:s.keys.client_write_key),iv:u?s.keys.server_write_IV:s.keys.client_write_IV},n.write.cipherState={init:!1,cipher:e.aes.createEncryptionCipher(u?s.keys.client_write_key:s.keys.server_write_key),iv:u?s.keys.client_write_IV:s.keys.server_write_IV},n.read.cipherFunction=o,n.write.cipherFunction=r,n.read.macLength=n.write.macLength=s.mac_length,n.read.macFunction=n.write.macFunction=t.hmac_sha1}function r(t,n){var r=!1,s=n.macFunction(n.macKey,n.sequenceNumber,t);t.fragment.putBytes(s),n.updateSequenceNumber();var o;t.version.minor>1?o=e.random.getBytes(16):o=n.cipherState.init?null:n.cipherState.iv,n.cipherState.init=!0;var u=n.cipherState.cipher;return u.start(o),t.version.minor>1&&u.output.putBytes(o),u.update(t.fragment),u.finish(i)&&(t.fragment=u.output,t.length=t.fragment.length(),r=!0),r}function i(e,t,n){if(!n){var r=e-t.length()%e;t.fillWithByte(r-1,r)}return!0}function s(e,t,n){var r=!0;if(n){var i=t.length(),s=t.last();for(var o=i-1-s;o<i-1;++o)r=r&&t.at(o)==s;r&&t.truncate(s+1)}return r}function o(t,n){var r=!1,i=n.cipherState.init?null:n.cipherState.iv;n.cipherState.init=!0;var o=n.cipherState.cipher;o.start(i),o.update(t.fragment),r=o.finish(s);var u=n.macLength,a="";for(var f=0;f<u;++f)a+=String.fromCharCode(0);var l=o.output.length();l>=u?(t.fragment=o.output.getBytes(l-u),a=o.output.getBytes(u)):t.fragment=o.output.getBytes(),t.fragment=e.util.createBuffer(t.fragment),t.length=t.fragment.length();var c=n.macFunction(n.macKey,n.sequenceNumber,t);return n.updateSequenceNumber(),r=c===a&&r,r}var t=e.tls;t.CipherSuites.TLS_RSA_WITH_AES_128_CBC_SHA={id:[0,47],name:"TLS_RSA_WITH_AES_128_CBC_SHA",initSecurityParameters:function(e){e.bulk_cipher_algorithm=t.BulkCipherAlgorithm.aes,e.cipher_type=t.CipherType.block,e.enc_key_length=16,e.block_length=16,e.fixed_iv_length=16,e.record_iv_length=16,e.mac_algorithm=t.MACAlgorithm.hmac_sha1,e.mac_length=20,e.mac_key_length=20},initConnectionState:n},t.CipherSuites.TLS_RSA_WITH_AES_256_CBC_SHA={id:[0,53],name:"TLS_RSA_WITH_AES_256_CBC_SHA",initSecurityParameters:function(e){e.bulk_cipher_algorithm=t.BulkCipherAlgorithm.aes,e.cipher_type=t.CipherType.block,e.enc_key_length=32,e.block_length=16,e.fixed_iv_length=16,e.record_iv_length=16,e.mac_algorithm=t.MACAlgorithm.hmac_sha1,e.mac_length=20,e.mac_key_length=20},initConnectionState:n}}var t="aesCipherSuites";if(typeof define!="function"){if(typeof module!="object"||!module.exports)return typeof forge=="undefined"&&(forge={}),e(forge);var n=!0;define=function(e,t){t(require,module)}}var r,i=function(n,i){i.exports=function(i){var s=r.map(function(e){return n(e)}).concat(e);i=i||{},i.defined=i.defined||{};if(i.defined[t])return i[t];i.defined[t]=!0;for(var o=0;o<s.length;++o)s[o](i);return i[t]}},s=define;define=function(e,t){return r=typeof e=="string"?t.slice(2):e.slice(2),n?(delete define,s.apply(null,Array.prototype.slice.call(arguments,0))):(define=s,define.apply(null,Array.prototype.slice.call(arguments,0)))},define("forge/aesCipherSuites",["require","module","./aes","./tls"],function(){i.apply(null,Array.prototype.slice.call(arguments,0))})}(),function(){function e(e){e.debug=e.debug||{},e.debug.storage={},e.debug.get=function(t,n){var r;return typeof t=="undefined"?r=e.debug.storage:t in e.debug.storage&&(typeof n=="undefined"?r=e.debug.storage[t]:r=e.debug.storage[t][n]),r},e.debug.set=function(t,n,r){t in e.debug.storage||(e.debug.storage[t]={}),e.debug.storage[t][n]=r},e.debug.clear=function(t,n){typeof t=="undefined"?e.debug.storage={}:t in e.debug.storage&&(typeof n=="undefined"?delete e.debug.storage[t]:delete e.debug.storage[t][n])}}var t="debug";if(typeof define!="function"){if(typeof module!="object"||!module.exports)return typeof forge=="undefined"&&(forge={}),e(forge);var n=!0;define=function(e,t){t(require,module)}}var r,i=function(n,i){i.exports=function(i){var s=r.map(function(e){return n(e)}).concat(e);i=i||{},i.defined=i.defined||{};if(i.defined[t])return i[t];i.defined[t]=!0;for(var o=0;o<s.length;++o)s[o](i);return i[t]}},s=define;define=function(e,t){return r=typeof e=="string"?t.slice(2):e.slice(2),n?(delete define,s.apply(null,Array.prototype.slice.call(arguments,0))):(define=s,define.apply(null,Array.prototype.slice.call(arguments,0)))},define("forge/debug",["require","module"],function(){i.apply(null,Array.prototype.slice.call(arguments,0))})}(),function(){function e(e){e.log=e.log||{},e.log.levels=["none","error","warning","info","debug","verbose","max"];var t={},n=[],r=null;e.log.LEVEL_LOCKED=2,e.log.NO_LEVEL_CHECK=4,e.log.INTERPOLATE=8;for(var i=0;i<e.log.levels.length;++i){var s=e.log.levels[i];t[s]={index:i,name:s.toUpperCase()}}e.log.logMessage=function(r){var i=t[r.level].index;for(var s=0;s<n.length;++s){var o=n[s];if(o.flags&e.log.NO_LEVEL_CHECK)o.f(r);else{var u=t[o.level].index;i<=u&&o.f(o,r)}}},e.log.prepareStandard=function(e){"standard"in e||(e.standard=t[e.level].name+" ["+e.category+"] "+e.message)},e.log.prepareFull=function(t){if(!("full"in t)){var n=[t.message];n=n.concat([]||t.arguments),t.full=e.util.format.apply(this,n)}},e.log.prepareStandardFull=function(t){"standardFull"in t||(e.log.prepareStandard(t),t.standardFull=t.standard)};var o=["error","warning","info","debug","verbose"];for(var i=0;i<o.length;++i)(function(t){e.log[t]=function(n,r){var i=Array.prototype.slice.call(arguments).slice(2),s={timestamp:new Date,level:t,category:n,message:r,arguments:i};e.log.logMessage(s)}})(o[i]);e.log.makeLogger=function(t){var n={flags:0,f:t};return e.log.setLevel(n,"none"),n},e.log.setLevel=function(t,n){var r=!1;if(t&&!(t.flags&e.log.LEVEL_LOCKED))for(var i=0;i<e.log.levels.length;++i){var s=e.log.levels[i];if(n==s){t.level=n,r=!0;break}}return r},e.log.lock=function(t,n){typeof n=="undefined"||n?t.flags|=e.log.LEVEL_LOCKED:t.flags&=~e.log.LEVEL_LOCKED},e.log.addLogger=function(e){n.push(e)};if(typeof console!="undefined"&&"log"in console){var u;if(console.error&&console.warn&&console.info&&console.debug){var a={error:console.error,warning:console.warn,info:console.info,debug:console.debug,verbose:console.debug},f=function(t,n){e.log.prepareStandard(n);var r=a[n.level],i=[n.standard];i=i.concat(n.arguments.slice()),r.apply(console,i)};u=e.log.makeLogger(f)}else{var f=function(t,n){e.log.prepareStandardFull(n),console.log(n.standardFull)};u=e.log.makeLogger(f)}e.log.setLevel(u,"debug"),e.log.addLogger(u),r=u}else console={log:function(){}};if(r!==null){var l=e.util.getQueryVariables();"console.level"in l&&e.log.setLevel(r,l["console.level"].slice(-1)[0]);if("console.lock"in l){var c=l["console.lock"].slice(-1)[0];c=="true"&&e.log.lock(r)}}e.log.consoleLogger=r}var t="log";if(typeof define!="function"){if(typeof module!="object"||!module.exports)return typeof forge=="undefined"&&(forge={}),e(forge);var n=!0;define=function(e,t){t(require,module)}}var r,i=function(n,i){i.exports=function(i){var s=r.map(function(e){return n(e)}).concat(e);i=i||{},i.defined=i.defined||{};if(i.defined[t])return i[t];i.defined[t]=!0;for(var o=0;o<s.length;++o)s[o](i);return i[t]}},s=define;define=function(e,t){return r=typeof e=="string"?t.slice(2):e.slice(2),n?(delete define,s.apply(null,Array.prototype.slice.call(arguments,0))):(define=s,define.apply(null,Array.prototype.slice.call(arguments,0)))},define("forge/log",["require","module","./util"],function(){i.apply(null,Array.prototype.slice.call(arguments,0))})}(),function(){function e(e){var t="forge.task",n=0,r={},i=0;e.debug.set(t,"tasks",r);var s={};e.debug.set(t,"queues",s);var o="?",u=30,a=20,f="ready",l="running",c="blocked",h="sleeping",p="done",d="error",v="stop",m="start",g="block",y="unblock",b="sleep",w="wakeup",E="cancel",S="fail",x={};x[f]={},x[f][v]=f,x[f][m]=l,x[f][E]=p,x[f][S]=d,x[l]={},x[l][v]=f,x[l][m]=l,x[l][g]=c,x[l][y]=l,x[l][b]=h,x[l][w]=l,x[l][E]=p,x[l][S]=d,x[c]={},x[c][v]=c,x[c][m]=c,x[c][g]=c,x[c][y]=c,x[c][b]=c,x[c][w]=c,x[c][E]=p,x[c][S]=d,x[h]={},x[h][v]=h,x[h][m]=h,x[h][g]=h,x[h][y]=h,x[h][b]=h,x[h][w]=h,x[h][E]=p,x[h][S]=d,x[p]={},x[p][v]=p,x[p][m]=p,x[p][g]=p,x[p][y]=p,x[p][b]=p,x[p][w]=p,x[p][E]=p,x[p][S]=d,x[d]={},x[d][v]=d,x[d][m]=d,x[d][g]=d,x[d][y]=d,x[d][b]=d,x[d][w]=d,x[d][E]=d,x[d][S]=d;var T=function(s){this.id=-1,this.name=s.name||o,this.parent=s.parent||null,this.run=s.run,this.subtasks=[],this.error=!1,this.state=f,this.blocks=0,this.timeoutId=null,this.swapTime=null,this.userData=null,this.id=i++,r[this.id]=this,n>=1&&e.log.verbose(t,"[%s][%s] init",this.id,this.name,this)};T.prototype.debug=function(n){n=n||"",e.log.debug(t,n,"[%s][%s] task:",this.id,this.name,this,"subtasks:",this.subtasks.length,"queue:",s)},T.prototype.next=function(e,t){typeof e=="function"&&(t=e,e=this.name);var n=new T({run:t,name:e,parent:this});return n.state=l,n.type=this.type,n.successCallback=this.successCallback||null,n.failureCallback=this.failureCallback||null,this.subtasks.push(n),this},T.prototype.parallel=function(t,n){return e.util.isArray(t)&&(n=t,t=this.name),this.next(t,function(r){var i=r;i.block(n.length);var s=function(t,r){e.task.start({type:t,run:function(e){n[r](e)},success:function(e){i.unblock()},failure:function(e){i.unblock()}})};for(var o=0;o<n.length;o++){var u=t+"__parallel-"+r.id+"-"+o,a=o;s(u,a)}})},T.prototype.stop=function(){this.state=x[this.state][v]},T.prototype.start=function(){this.error=!1,this.state=x[this.state][m],this.state===l&&(this.start=new Date,this.run(this),C(this,0))},T.prototype.block=function(e){e=typeof e=="undefined"?1:e,this.blocks+=e,this.blocks>0&&(this.state=x[this.state][g])},T.prototype.unblock=function(e){return e=typeof e=="undefined"?1:e,this.blocks-=e,this.blocks===0&&this.state!==p&&(this.state=l,C(this,0)),this.blocks},T.prototype.sleep=function(e){e=typeof e=="undefined"?0:e,this.state=x[this.state][b];var t=this;this.timeoutId=setTimeout(function(){t.timeoutId=null,t.state=l,C(t,0)},e)},T.prototype.wait=function(e){e.wait(this)},T.prototype.wakeup=function(){this.state===h&&(cancelTimeout(this.timeoutId),this.timeoutId=null,this.state=l,C(this,0))},T.prototype.cancel=function(){this.state=x[this.state][E],this.permitsNeeded=0,this.timeoutId!==null&&(cancelTimeout(this.timeoutId),this.timeoutId=null),this.subtasks=[]},T.prototype.fail=function(e){this.error=!0,k(this,!0);if(e)e.error=this.error,e.swapTime=this.swapTime,e.userData=this.userData,C(e,0);else{if(this.parent!==null){var t=this.parent;while(t.parent!==null)t.error=this.error,t.swapTime=this.swapTime,t.userData=this.userData,t=t.parent;k(t,!0)}this.failureCallback&&this.failureCallback(this)}};var N=function(e){e.error=!1,e.state=x[e.state][m],setTimeout(function(){e.state===l&&(e.swapTime=+(new Date),e.run(e),C(e,0))},0)},C=function(e,t){var n=t>u||+(new Date)-e.swapTime>a,r=function(t){t++;if(e.state===l){n&&(e.swapTime=+(new Date));if(e.subtasks.length>0){var r=e.subtasks.shift();r.error=e.error,r.swapTime=e.swapTime,r.userData=e.userData,r.run(r),r.error||C(r,t)}else k(e),e.error||e.parent!==null&&(e.parent.error=e.error,e.parent.swapTime=e.swapTime,e.parent.userData=e.userData,C(e.parent,t))}};n?setTimeout(r,0):r(t)},k=function(i,o){i.state=p,delete r[i.id],n>=1&&e.log.verbose(t,"[%s][%s] finish",i.id,i.name,i),i.parent===null&&(i.type in s?s[i.type].length===0?e.log.error(t,"[%s][%s] task queue empty [%s]",i.id,i.name,i.type):s[i.type][0]!==i?e.log.error(t,"[%s][%s] task not first in queue [%s]",i.id,i.name,i.type):(s[i.type].shift(),s[i.type].length===0?(n>=1&&e.log.verbose(t,"[%s][%s] delete queue [%s]",i.id,i.name,i.type),delete s[i.type]):(n>=1&&e.log.verbose(t,"[%s][%s] queue start next [%s] remain:%s",i.id,i.name,i.type,s[i.type].length),s[i.type][0].start())):e.log.error(t,"[%s][%s] task queue missing [%s]",i.id,i.name,i.type),o||(i.error&&i.failureCallback?i.failureCallback(i):!i.error&&i.successCallback&&i.successCallback(i)))};e.task=e.task||{},e.task.start=function(r){var i=new T({run:r.run,name:r.name||o});i.type=r.type,i.successCallback=r.success||null,i.failureCallback=r.failure||null,i.type in s?s[r.type].push(i):(n>=1&&e.log.verbose(t,"[%s][%s] create queue [%s]",i.id,i.name,i.type),s[i.type]=[i],N(i))},e.task.cancel=function(e){e in s&&(s[e]=[s[e][0]])},e.task.createCondition=function(){var e={tasks:{}};return e.wait=function(t){t.id in e.tasks||(t.block(),e.tasks[t.id]=t)},e.notify=function(){var t=e.tasks;e.tasks={};for(var n in t)t[n].unblock()},e}}var t="task";if(typeof define!="function"){if(typeof module!="object"||!module.exports)return typeof forge=="undefined"&&(forge={}),e(forge);var n=!0;define=function(e,t){t(require,module)}}var r,i=function(n,i){i.exports=function(i){var s=r.map(function(e){return n(e)}).concat(e);i=i||{},i.defined=i.defined||{};if(i.defined[t])return i[t];i.defined[t]=!0;for(var o=0;o<s.length;++o)s[o](i);return i[t]}},s=define;define=function(e,t){return r=typeof e=="string"?t.slice(2):e.slice(2),n?(delete define,s.apply(null,Array.prototype.slice.call(arguments,0))):(define=s,define.apply(null,Array.prototype.slice.call(arguments,0)))},define("forge/task",["require","module","./debug","./log","./util"],function(){i.apply(null,Array.prototype.slice.call(arguments,0))})}(),function(){var e="forge";if(typeof define!="function"){if(typeof module!="object"||!module.exports){typeof forge=="undefined"&&(forge={disableNativeCode:!1});return}var t=!0;define=function(e,t){t(require,module)}}var n,r=function(t,r){r.exports=function(r){var i=n.map(function(e){return t(e)});r=r||{},r.defined=r.defined||{};if(r.defined[e])return r[e];r.defined[e]=!0;for(var s=0;s<i.length;++s)i[s](r);return r},r.exports.disableNativeCode=!1,r.exports(r.exports)},i=define;define=function(e,r){return n=typeof e=="string"?r.slice(2):e.slice(2),t?(delete define,i.apply(null,Array.prototype.slice.call(arguments,0))):(define=i,define.apply(null,Array.prototype.slice.call(arguments,0)))},define("forge/forge",["require","module","./aes","./aesCipherSuites","./asn1","./debug","./des","./hmac","./log","./pbkdf2","./pem","./pkcs7","./pkcs1","./pkcs12","./pki","./prng","./pss","./random","./rc2","./task","./tls","./util","./md","./mgf1"],function(){r.apply(null,Array.prototype.slice.call(arguments,0))})}(),function(){function e(e,t){describe("tls",function(){it("should test TLS 1.0 PRF",function(){var n=t.util.createBuffer().fillWithByte(171,48).getBytes(),r=t.util.createBuffer().fillWithByte(205,64).getBytes(),i=t.tls.prf_tls1(n,"PRF Testvector",r,104),s="d3d4d1e349b5d515044666d51de32bab258cb521b6b053463e354832fd976754443bcf9a296519bc289abcbc1187e4ebd31e602353776c408aafb74cbc85eff69255f9788faa184cbb957a9819d84a5d7eb006eb459d3ae8de9810454b8b2d8f1afbc655a8c9a013";e.equal(i.toHex(),s)}),it("should establish a TLS connection and transfer data",function(n){function s(e,n){var r=t.pki.rsa.generateKeyPair(512),i=t.pki.createCertificate();i.publicKey=r.publicKey,i.serialNumber="01",i.validity.notBefore=new Date,i.validity.notAfter=new Date,i.validity.notAfter.setFullYear(i.validity.notBefore.getFullYear()+1);var s=[{name:"commonName",value:e},{name:"countryName",value:"US"},{shortName:"ST",value:"Virginia"},{name:"localityName",value:"Blacksburg"},{name:"organizationName",value:"Test"},{shortName:"OU",value:"Test"}];i.setSubject(s),i.setIssuer(s),i.setExtensions([{name:"basicConstraints",cA:!0},{name:"keyUsage",keyCertSign:!0,digitalSignature:!0,nonRepudiation:!0,keyEncipherment:!0,dataEncipherment:!0},{name:"subjectAltName",altNames:[{type:6,value:"https://myuri.com/webid#me"}]}]),i.sign(r.privateKey),n[e]={cert:t.pki.certificateToPem(i),privateKey:t.pki.privateKeyToPem(r.privateKey)}}var r={},i={};s("server",i),s("client",i),i.client.connection={},i.server.connection={},r.client=t.tls.createConnection({server:!1,caStore:[i.server.cert],sessionCache:{},cipherSuites:[t.tls.CipherSuites.TLS_RSA_WITH_AES_128_CBC_SHA,t.tls.CipherSuites.TLS_RSA_WITH_AES_256_CBC_SHA],virtualHost:"server",verify:function(e,t,n,r){return i.client.connection.commonName=r[0].subject.getField("CN").value,i.client.connection.certVerified=t,!0},connected:function(e){e.prepare("Hello Server")},getCertificate:function(e,t){return i.client.cert},getPrivateKey:function(e,t){return i.client.privateKey},tlsDataReady:function(e){r.server.process(e.tlsData.getBytes())},dataReady:function(e){i.client.connection.data=e.data.getBytes(),e.close()},closed:function(t){e.equal(i.client.connection.commonName,"server"),e.equal(i.client.connection.certVerified,!0),e.equal(i.client.connection.data,"Hello Client"),n()},error:function(t,n){e.equal(n.message,undefined)}}),r.server=t.tls.createConnection({server:!0,caStore:[i.client.cert],sessionCache:{},cipherSuites:[t.tls.CipherSuites.TLS_RSA_WITH_AES_128_CBC_SHA,t.tls.CipherSuites.TLS_RSA_WITH_AES_256_CBC_SHA],connected:function(e){},verifyClient:!0,verify:function(e,t,n,r){return i.server.connection.commonName=r[0].subject.getField("CN").value,i.server.connection.certVerified=t,!0},getCertificate:function(e,t){return i.server.connection.certHint=t[0],i.server.cert},getPrivateKey:function(e,t){return i.server.privateKey},tlsDataReady:function(e){r.client.process(e.tlsData.getBytes())},dataReady:function(e){i.server.connection.data=e.data.getBytes(),e.prepare("Hello Client"),e.close()},closed:function(t){e.equal(i.server.connection.certHint,"server"),e.equal(i.server.connection.commonName,"client"),e.equal(i.server.connection.certVerified,!0),e.equal(i.server.connection.data,"Hello Server")},error:function(t,n){e.equal(n.message,undefined)}}),r.client.handshake()})})}typeof define=="function"?define("test/tls",["forge/forge"],function(t){e(ASSERT,t)}):typeof module=="object"&&module.exports&&e(require("assert"),require("../../js/forge"))}();var ASSERT=chai.assert;mocha.setup({ui:"bdd"}),requirejs.config({paths:{forge:"forge",test:"test"}}),requirejs(["test/util","test/md5","test/sha1","test/sha256","test/hmac","test/pbkdf2","test/mgf1","test/random","test/asn1","test/pem","test/rsa","test/pkcs1","test/x509","test/csr","test/aes","test/rc2","test/des","test/pkcs7","test/tls"],function(){mocha.run()}),define("ui/test.js",function(){});
\ No newline at end of file diff --git a/alarm/node_modules/node-forge/package.json b/alarm/node_modules/node-forge/package.json deleted file mode 100644 index 4d7fbdf..0000000 --- a/alarm/node_modules/node-forge/package.json +++ /dev/null @@ -1,86 +0,0 @@ -{ - "name": "node-forge", - "version": "0.6.33", - "description": "JavaScript implementations of network transports, cryptography, ciphers, PKI, message digests, and various utilities.", - "homepage": "http://github.com/digitalbazaar/forge", - "author": { - "name": "Digital Bazaar, Inc.", - "email": "support@digitalbazaar.com", - "url": "http://digitalbazaar.com/" - }, - "contributors": [ - { - "name": "Dave Longley", - "email": "dlongley@digitalbazaar.com" - }, - { - "name": "Stefan Siegl", - "email": "stesie@brokenpipe.de" - }, - { - "name": "Christoph Dorn", - "email": "christoph@christophdorn.com" - } - ], - "devDependencies": { - "almond": "~0.2.6", - "jscs": "^1.8.1", - "requirejs": "~2.1.8" - }, - "repository": { - "type": "git", - "url": "http://github.com/digitalbazaar/forge" - }, - "bugs": { - "url": "https://github.com/digitalbazaar/forge/issues", - "email": "support@digitalbazaar.com" - }, - "licenses": [ - { - "type": "BSD", - "url": "https://github.com/digitalbazaar/forge/raw/master/LICENSE" - } - ], - "main": "js/forge.js", - "engines": { - "node": "*" - }, - "keywords": [ - "aes", - "asn", - "asn.1", - "cbc", - "crypto", - "cryptography", - "csr", - "des", - "gcm", - "hmac", - "http", - "https", - "md5", - "network", - "pkcs", - "pki", - "prng", - "rc2", - "rsa", - "sha1", - "sha256", - "sha384", - "sha512", - "ssh", - "tls", - "x.509", - "x509" - ], - "scripts": { - "bundle": "r.js -o minify.js optimize=none out=js/forge.bundle.js", - "minify": "r.js -o minify.js", - "jscs": "jscs *.js js/*.js minify.js nodejs/*.js nodejs/test/*.js nodejs/ui/*.js tests/*.js", - "jshint": "jshint *.js js/*.js minify.js nodejs/*.js nodejs/test/*.js nodejs/ui/*.js tests/*.js" - }, - "jspm": { - "format": "amd" - } -} diff --git a/alarm/node_modules/node-forge/setup/configure.ac b/alarm/node_modules/node-forge/setup/configure.ac deleted file mode 100644 index 0d94441..0000000 --- a/alarm/node_modules/node-forge/setup/configure.ac +++ /dev/null @@ -1,202 +0,0 @@ -# Configure script for Digital Bazaar Bitmunk product line -# Usage: Run ./configure once -# Author: Manu Sporny - -AC_PREREQ([2.60]) -AC_INIT([forge],[0.1.0],[support@digitalbazaar.com]) -AC_CONFIG_AUX_DIR(setup) - -# Setup standard build environment variables -# FIXME: allow changing via configure option -FORGE_DIR=`(cd ${srcdir} && pwd)` -AC_SUBST(FORGE_DIR) -DATE_YMD=`date +%Y%m%d` -PACKAGE_DATE_VERSION=${PACKAGE_VERSION}-${DATE_YMD} -AC_SUBST(DATE_RFC_2822) -AC_SUBST(PACKAGE_DATE_VERSION) - -dnl ----------------- docs ----------------- - -AC_ARG_ENABLE([docs], - AS_HELP_STRING([--enable-docs], [build documentation [no]]), - [ - case "${enableval}" in - yes) BUILD_DOCS=yes ;; - no) BUILD_DOCS=no ;; - *) AC_MSG_ERROR(bad value ${enableval} for --enable-docs) ;; - esac - ], [BUILD_DOCS=no]) dnl Default value - -AC_SUBST(BUILD_DOCS) - -dnl ----------------- tests ----------------- - -AC_ARG_ENABLE([tests], - AC_HELP_STRING([--disable-tests], [disable building test apps [no]]), - [ - case "${enableval}" in - yes) BUILD_TESTS=yes ;; - no) BUILD_TESTS=no ;; - *) AC_MSG_ERROR(bad value ${enableval} for --disable-tests) ;; - esac - ], [BUILD_TESTS=no]) dnl Default value - -AC_SUBST(BUILD_TESTS) - -dnl ----------------- build flash ----------------- - -AC_ARG_ENABLE([flash], - AC_HELP_STRING([--disable-flash], [disable building Flash [no]]), - [ - case "${enableval}" in - yes) BUILD_FLASH=yes ;; - no) BUILD_FLASH=no ;; - *) AC_MSG_ERROR(bad value ${enableval} for --disable-flash) ;; - esac - ], [BUILD_FLASH=yes]) dnl Default value - -AC_ARG_ENABLE([pre-built-flash], - AC_HELP_STRING([--disable-pre-built-flash], - [disable use of pre-built Flash [no]]), - [ - case "${enableval}" in - yes) USE_PRE_BUILT_FLASH=yes ;; - no) USE_PRE_BUILT_FLASH=no ;; - *) AC_MSG_ERROR(bad value ${enableval} for --disable-flash) ;; - esac - ], [USE_PRE_BUILT_FLASH=yes]) dnl Default value - -AC_SUBST(BUILD_FLASH) -AC_SUBST(USE_PRE_BUILT_FLASH) - -dnl ----------------- mxmlc ----------------- - -AC_ARG_WITH([mxmlc], - AC_HELP_STRING([--with-mxmlc=PATH], - [use PATH for mxmlc]), - [ - case "${withval}" in - yes|no) AC_MSG_ERROR(bad value ${withval} for --with-mxmlc) ;; - *) MXMLC="${withval}" ;; - esac - if test "x$MXMLC" = x -o ! -x "$MXMLC"; then - AC_MSG_ERROR([mxmlc not found at "$MXMLC"]) - fi - ]) - -if test "$BUILD_FLASH" = "yes" ; then - dnl Need to try to find mxmlc - if test "x$MXMLC" = x; then - AC_CHECK_PROGS(MXMLC, mxmlc /usr/lib/flex3/bin/mxmlc,, $PATH /) - fi - dnl Check that mxmlc was found - if test "x$MXMLC" = x; then - if test "$USE_PRE_BUILT_FLASH" = "yes"; then - dnl Check pre-built SWF is present - if test -r "$FORGE_DIR/swf/SocketPool.swf"; then - AC_MSG_NOTICE([Using pre-built Flash]) - BUILD_FLASH=no - else - AC_MSG_ERROR([mxmlc and pre-built Flash not found]) - fi - else - AC_MSG_ERROR([mxmlc not found, try --with-mxmlc]) - fi - fi -fi - -AC_SUBST(MXMLC) - -dnl ----------------- mxmlc debug ----------------- - -AC_ARG_ENABLE([mxmlc-debug], - AC_HELP_STRING([--enable-mxmlc-debug], [enable mxmlc debug mode [no]]), - [ - case "${enableval}" in - yes) MXMLC_DEBUG_MODE=yes ;; - no) MXMLC_DEBUG_MODE=no ;; - *) AC_MSG_ERROR(bad value ${enableval} for --enable-mxmlc-debug) ;; - esac - ], [MXMLC_DEBUG_MODE=no]) dnl Default value - -AC_SUBST(MXMLC_DEBUG_MODE) - -dnl ----------------- end of options ----------------- - -echo -e "\n--------- Configuring Build Environment -----------" - -PKG_PROG_PKG_CONFIG - -# Checking for standard build tools -AC_PROG_CPP -AC_PROG_INSTALL -AS_PATH_PYTHON([2.7]) - -if test "x$PYTHON" != x; then - save_CPPFLAGS="$CPPFLAGS" - AC_CHECK_PROGS([PYTHON_CONFIG], [python-config]) - if test "x$PYTHON_CONFIG" != x; then - CPPFLAGS="$CPPFLAGS `$PYTHON_CONFIG --cflags`" - fi - AC_CHECK_HEADERS([Python.h], - [BUILD_PYTHON_MODULES=yes], - [BUILD_PYTHON_MODULES=no - AC_MSG_WARN([Python.h not found, SSL bindings will not be build.])]) - CPPFLAGS="$save_CPPFLAGS" -else - AC_MSG_WARN([Need at least Python 2.7 to build SSL bindings.]) -fi - -AC_SUBST(BUILD_PYTHON_MODULES) - -dnl ---------------------------------- - -dnl NOTE: -dnl This code was used previously to autogenerate the .gitignore file but due -dnl to the current more common use of just the js files, it's likely people -dnl who checkout the code will never run the build scripts. The files are now -dnl just hardcoded into .gitignore and should be updated by hand as needed. -dnl -dnl # Generating files -dnl AC_CONFIG_FILES([ -dnl .gitignore -dnl Makefile -dnl ]) -dnl -dnl # add newlines to internal output file list -dnl CONFIGURE_GENERATED_FILES="`echo $ac_config_files | tr ' ' '\n'`" -dnl AC_SUBST(CONFIGURE_GENERATED_FILES) - -AC_OUTPUT - -# Dump the build configuration - -echo -e "\n--------- Forge Build Environment -----------" -echo "Forge Version : $PACKAGE_NAME $PACKAGE_DATE_VERSION" - -if test "x$BUILD_FLASH" = "xyes" ; then - echo "Adobe Flash : Flash building enabled" - echo "MXMLC : $MXMLC" - echo "MXMLC Debug flags : $MXMLC_DEBUG_MODE" -else - echo "Adobe Flash : using pre-built Flash" -fi - -if test "x$BUILD_PYTHON_MODULES" = "xyes" ; then - echo "Python : $PYTHON (version $PYTHON_VERSION)" -else - echo "Python : development environment not found" -fi - -if test "x$BUILD_DOCS" = "xyes"; then - echo "Documentation : enabled" -else - echo "Documentation : disabled (use --enable-docs to enable)" -fi - -if test "x$BUILD_TESTS" = "xyes"; then - echo "Tests : enabled" -else - echo "Tests : disabled (use --enable-tests to enable)" -fi - diff --git a/alarm/node_modules/node-forge/setup/install-sh b/alarm/node_modules/node-forge/setup/install-sh deleted file mode 100755 index d4744f0..0000000 --- a/alarm/node_modules/node-forge/setup/install-sh +++ /dev/null @@ -1,269 +0,0 @@ -#!/bin/sh -# -# install - install a program, script, or datafile -# -# This originates from X11R5 (mit/util/scripts/install.sh), which was -# later released in X11R6 (xc/config/util/install.sh) with the -# following copyright and license. -# -# Copyright (C) 1994 X Consortium -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to -# deal in the Software without restriction, including without limitation the -# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -# sell copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN -# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- -# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# -# Except as contained in this notice, the name of the X Consortium shall not -# be used in advertising or otherwise to promote the sale, use or other deal- -# ings in this Software without prior written authorization from the X Consor- -# tium. -# -# -# FSF changes to this file are in the public domain. -# -# Calling this script install-sh is preferred over install.sh, to prevent -# `make' implicit rules from creating a file called install from it -# when there is no Makefile. -# -# This script is compatible with the BSD install script, but was written -# from scratch. It can only install one file at a time, a restriction -# shared with many OS's install programs. - - -# set DOITPROG to echo to test this script - -# Don't use :- since 4.3BSD and earlier shells don't like it. -doit="${DOITPROG-}" - - -# put in absolute paths if you don't have them in your path; or use env. vars. - -mvprog="${MVPROG-mv}" -cpprog="${CPPROG-cp}" -chmodprog="${CHMODPROG-chmod}" -chownprog="${CHOWNPROG-chown}" -chgrpprog="${CHGRPPROG-chgrp}" -stripprog="${STRIPPROG-strip}" -rmprog="${RMPROG-rm}" -mkdirprog="${MKDIRPROG-mkdir}" - -transformbasename="" -transform_arg="" -instcmd="$mvprog" -chmodcmd="$chmodprog 0755" -chowncmd="" -chgrpcmd="" -stripcmd="" -rmcmd="$rmprog -f" -mvcmd="$mvprog" -src="" -dst="" -dir_arg="" - -while [ x"$1" != x ]; do - case $1 in - -c) instcmd="$cpprog" - shift - continue;; - - -d) dir_arg=true - shift - continue;; - - -m) chmodcmd="$chmodprog $2" - shift - shift - continue;; - - -o) chowncmd="$chownprog $2" - shift - shift - continue;; - - -g) chgrpcmd="$chgrpprog $2" - shift - shift - continue;; - - -s) stripcmd="$stripprog" - shift - continue;; - - -t=*) transformarg=`echo $1 | sed 's/-t=//'` - shift - continue;; - - -b=*) transformbasename=`echo $1 | sed 's/-b=//'` - shift - continue;; - - *) if [ x"$src" = x ] - then - src=$1 - else - # this colon is to work around a 386BSD /bin/sh bug - : - dst=$1 - fi - shift - continue;; - esac -done - -if [ x"$src" = x ] -then - echo "install: no input file specified" - exit 1 -else - true -fi - -if [ x"$dir_arg" != x ]; then - dst=$src - src="" - - if [ -d $dst ]; then - instcmd=: - chmodcmd="" - else - instcmd=mkdir - fi -else - -# Waiting for this to be detected by the "$instcmd $src $dsttmp" command -# might cause directories to be created, which would be especially bad -# if $src (and thus $dsttmp) contains '*'. - - if [ -f $src -o -d $src ] - then - true - else - echo "install: $src does not exist" - exit 1 - fi - - if [ x"$dst" = x ] - then - echo "install: no destination specified" - exit 1 - else - true - fi - -# If destination is a directory, append the input filename; if your system -# does not like double slashes in filenames, you may need to add some logic - - if [ -d $dst ] - then - dst="$dst"/`basename $src` - else - true - fi -fi - -## this sed command emulates the dirname command -dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` - -# Make sure that the destination directory exists. -# this part is taken from Noah Friedman's mkinstalldirs script - -# Skip lots of stat calls in the usual case. -if [ ! -d "$dstdir" ]; then -defaultIFS=' -' -IFS="${IFS-${defaultIFS}}" - -oIFS="${IFS}" -# Some sh's can't handle IFS=/ for some reason. -IFS='%' -set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` -IFS="${oIFS}" - -pathcomp='' - -while [ $# -ne 0 ] ; do - pathcomp="${pathcomp}${1}" - shift - - if [ ! -d "${pathcomp}" ] ; - then - $mkdirprog "${pathcomp}" - else - true - fi - - pathcomp="${pathcomp}/" -done -fi - -if [ x"$dir_arg" != x ] -then - $doit $instcmd $dst && - - if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && - if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && - if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && - if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi -else - -# If we're going to rename the final executable, determine the name now. - - if [ x"$transformarg" = x ] - then - dstfile=`basename $dst` - else - dstfile=`basename $dst $transformbasename | - sed $transformarg`$transformbasename - fi - -# don't allow the sed command to completely eliminate the filename - - if [ x"$dstfile" = x ] - then - dstfile=`basename $dst` - else - true - fi - -# Make a temp file name in the proper directory. - - dsttmp=$dstdir/#inst.$$# - -# Move or copy the file name to the temp name - - $doit $instcmd $src $dsttmp && - - trap "rm -f ${dsttmp}" 0 && - -# and set any options; do chmod last to preserve setuid bits - -# If any of these fail, we abort the whole thing. If we want to -# ignore errors from any of these, just make sure not to ignore -# errors from the above "$doit $instcmd $src $dsttmp" command. - - if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && - if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && - if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && - if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && - -# Now rename the file to the real destination. - - $doit $rmcmd -f $dstdir/$dstfile && - $doit $mvcmd $dsttmp $dstdir/$dstfile - -fi && - - -exit 0 diff --git a/alarm/node_modules/node-forge/setup/m4/as-python.m4 b/alarm/node_modules/node-forge/setup/m4/as-python.m4 deleted file mode 100644 index 84d4e36..0000000 --- a/alarm/node_modules/node-forge/setup/m4/as-python.m4 +++ /dev/null @@ -1,156 +0,0 @@ -## ------------------------ -## Python file handling -## From Andrew Dalke -## Updated by James Henstridge -## Updated by Andy Wingo to loop through possible pythons -## ------------------------ - -# AS_PATH_PYTHON([MINIMUM-VERSION]) - -# Adds support for distributing Python modules and packages. To -# install modules, copy them to $(pythondir), using the python_PYTHON -# automake variable. To install a package with the same name as the -# automake package, install to $(pkgpythondir), or use the -# pkgpython_PYTHON automake variable. - -# The variables $(pyexecdir) and $(pkgpyexecdir) are provided as -# locations to install python extension modules (shared libraries). -# Another macro is required to find the appropriate flags to compile -# extension modules. - -# If your package is configured with a different prefix to python, -# users will have to add the install directory to the PYTHONPATH -# environment variable, or create a .pth file (see the python -# documentation for details). - -# If the MINIMUM-VERSION argument is passed, AS_PATH_PYTHON will -# cause an error if the version of python installed on the system -# doesn't meet the requirement. MINIMUM-VERSION should consist of -# numbers and dots only. - -# Updated to loop over all possible python binaries by Andy Wingo -# <wingo@pobox.com> -# Updated to only warn and unset PYTHON if no good one is found - -AC_DEFUN([AS_PATH_PYTHON], - [ - dnl Find a version of Python. I could check for python versions 1.4 - dnl or earlier, but the default installation locations changed from - dnl $prefix/lib/site-python in 1.4 to $prefix/lib/python1.5/site-packages - dnl in 1.5, and I don't want to maintain that logic. - - dnl should we do the version check? - PYTHON_CANDIDATES="$PYTHON python python2 \ - python2.7 python2.6 pyton2.5 python2.4 python2.3 \ - python2.2 python2.1 python2.0 \ - python1.6 python1.5" - dnl Declare PYTHON as a special var - AC_ARG_VAR([PYTHON], [path to Python interpreter]) - ifelse([$1],[], - [AC_PATH_PROG(PYTHON, $PYTHON_CANDIDATES)], - [ - AC_MSG_NOTICE(Looking for Python version >= $1) - changequote(<<, >>)dnl - prog=" -import sys, string -minver = '$1' -# split string by '.' and convert to numeric -minver_info = map(string.atoi, string.split(minver, '.')) -# we can now do comparisons on the two lists: -if sys.version_info >= tuple(minver_info): - sys.exit(0) -else: - sys.exit(1)" - changequote([, ])dnl - - python_good=false - for python_candidate in $PYTHON_CANDIDATES; do - unset PYTHON - AC_PATH_PROG(PYTHON, $python_candidate) 1> /dev/null 2> /dev/null - - if test "x$PYTHON" = "x"; then continue; fi - - if $PYTHON -c "$prog" 1>&AC_FD_CC 2>&AC_FD_CC; then - AC_MSG_CHECKING(["$PYTHON":]) - AC_MSG_RESULT([okay]) - python_good=true - break; - else - dnl clear the cache val - unset ac_cv_path_PYTHON - fi - done - ]) - - if test "$python_good" != "true"; then - AC_MSG_WARN([No suitable version of python found]) - PYTHON= - else - - AC_MSG_CHECKING([local Python configuration]) - - dnl Query Python for its version number. Getting [:3] seems to be - dnl the best way to do this; it's what "site.py" does in the standard - dnl library. Need to change quote character because of [:3] - - AC_SUBST(PYTHON_VERSION) - changequote(<<, >>)dnl - PYTHON_VERSION=`$PYTHON -c "import sys; print sys.version[:3]"` - changequote([, ])dnl - - - dnl Use the values of $prefix and $exec_prefix for the corresponding - dnl values of PYTHON_PREFIX and PYTHON_EXEC_PREFIX. These are made - dnl distinct variables so they can be overridden if need be. However, - dnl general consensus is that you shouldn't need this ability. - - AC_SUBST(PYTHON_PREFIX) - PYTHON_PREFIX='${prefix}' - - AC_SUBST(PYTHON_EXEC_PREFIX) - PYTHON_EXEC_PREFIX='${exec_prefix}' - - dnl At times (like when building shared libraries) you may want - dnl to know which OS platform Python thinks this is. - - AC_SUBST(PYTHON_PLATFORM) - PYTHON_PLATFORM=`$PYTHON -c "import sys; print sys.platform"` - - - dnl Set up 4 directories: - - dnl pythondir -- where to install python scripts. This is the - dnl site-packages directory, not the python standard library - dnl directory like in previous automake betas. This behaviour - dnl is more consistent with lispdir.m4 for example. - dnl - dnl Also, if the package prefix isn't the same as python's prefix, - dnl then the old $(pythondir) was pretty useless. - - AC_SUBST(pythondir) - pythondir=$PYTHON_PREFIX"/lib/python"$PYTHON_VERSION/site-packages - - dnl pkgpythondir -- $PACKAGE directory under pythondir. Was - dnl PYTHON_SITE_PACKAGE in previous betas, but this naming is - dnl more consistent with the rest of automake. - dnl Maybe this should be put in python.am? - - AC_SUBST(pkgpythondir) - pkgpythondir=\${pythondir}/$PACKAGE - - dnl pyexecdir -- directory for installing python extension modules - dnl (shared libraries) Was PYTHON_SITE_EXEC in previous betas. - - AC_SUBST(pyexecdir) - pyexecdir=$PYTHON_EXEC_PREFIX"/lib/python"$PYTHON_VERSION/site-packages - - dnl pkgpyexecdir -- $(pyexecdir)/$(PACKAGE) - dnl Maybe this should be put in python.am? - - AC_SUBST(pkgpyexecdir) - pkgpyexecdir=\${pyexecdir}/$PACKAGE - - AC_MSG_RESULT([looks good]) - - fi -]) diff --git a/alarm/node_modules/node-forge/start.frag b/alarm/node_modules/node-forge/start.frag deleted file mode 100644 index dad9d0f..0000000 --- a/alarm/node_modules/node-forge/start.frag +++ /dev/null @@ -1,7 +0,0 @@ -(function(root, factory) { - if(typeof define === 'function' && define.amd) { - define([], factory); - } else { - root.forge = factory(); - } -})(this, function() { diff --git a/alarm/node_modules/node-forge/swf/SocketPool.swf b/alarm/node_modules/node-forge/swf/SocketPool.swf Binary files differdeleted file mode 100644 index c6cdaf9..0000000 --- a/alarm/node_modules/node-forge/swf/SocketPool.swf +++ /dev/null diff --git a/alarm/node_modules/node-forge/tests/aes-speed.js b/alarm/node_modules/node-forge/tests/aes-speed.js deleted file mode 100644 index 2049a8a..0000000 --- a/alarm/node_modules/node-forge/tests/aes-speed.js +++ /dev/null @@ -1,62 +0,0 @@ -var forge = require('../js/forge'); - -console.log('Times in 1000s of bytes/sec processed.'); - -aes_128('AES-CBC'); -aes_128('AES-CFB'); -aes_128('AES-OFB'); -aes_128('AES-CTR'); -aes_128('AES-GCM'); - -function aes_128(algorithm) { - console.log('Running ' + algorithm + ' for 5 seconds...'); - - var size = 1024; - var key = forge.random.getBytesSync(16); - var iv = forge.random.getBytes(algorithm === 'AES-GCM' ? 12 : 16); - var plain = forge.random.getBytesSync(size); - - // run for 5 seconds - var start = new Date().getTime(); - - var now; - var totalEncrypt = 0; - var totalDecrypt = 0; - var cipher; - var count = 0; - var passed = 0; - while(passed < 5000) { - var input = forge.util.createBuffer(plain); - - // encrypt, only measuring update() and finish() - cipher = forge.cipher.createCipher(algorithm, key); - cipher.start({iv: iv}); - now = new Date().getTime(); - cipher.update(input); - cipher.finish(); - totalEncrypt += new Date().getTime() - now; - - var ciphertext = cipher.output; - var tag = cipher.mode.tag; - count += cipher.output.length(); - - // decrypt, only measuring update() and finish() - cipher = forge.cipher.createDecipher(algorithm, key); - cipher.start({iv: iv, tag: tag}); - now = new Date().getTime(); - cipher.update(ciphertext); - if(!cipher.finish()) { - throw new Error('Decryption error.'); - } - totalDecrypt += new Date().getTime() - now; - - passed = new Date().getTime() - start; - } - - count = count / 1000; - totalEncrypt /= 1000; - totalDecrypt /= 1000; - console.log('encrypt: ' + (count / totalEncrypt) + ' k/sec'); - console.log('decrypt: ' + (count / totalDecrypt) + ' k/sec'); - console.log(); -} diff --git a/alarm/node_modules/node-forge/tests/common.html b/alarm/node_modules/node-forge/tests/common.html deleted file mode 100644 index 0fb4705..0000000 --- a/alarm/node_modules/node-forge/tests/common.html +++ /dev/null @@ -1,84 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" - "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> - <head> - <title>Forge Common Test</title> - <link type="text/css" rel="stylesheet" media="all" href="screen.css" /> - <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script> - <script type="text/javascript" src="forge/debug.js"></script> - <script type="text/javascript" src="forge/util.js"></script> - <script type="text/javascript" src="forge/log.js"></script> - <script type="text/javascript" src="forge/task.js"></script> - <script type="text/javascript" src="forge/md5.js"></script> - <script type="text/javascript" src="forge/sha1.js"></script> - <script type="text/javascript" src="forge/sha256.js"></script> - <script type="text/javascript" src="forge/hmac.js"></script> - <script type="text/javascript" src="forge/pbkdf2.js"></script> - <script type="text/javascript" src="forge/aes.js"></script> - <script type="text/javascript" src="forge/pem.js"></script> - <script type="text/javascript" src="forge/asn1.js"></script> - <script type="text/javascript" src="forge/jsbn.js"></script> - <script type="text/javascript" src="forge/prng.js"></script> - <script type="text/javascript" src="forge/random.js"></script> - <script type="text/javascript" src="forge/oids.js"></script> - <script type="text/javascript" src="forge/rsa.js"></script> - <script type="text/javascript" src="forge/pbe.js"></script> - <script type="text/javascript" src="forge/x509.js"></script> - <script type="text/javascript" src="forge/pki.js"></script> - <script type="text/javascript" src="forge/tls.js"></script> - <script type="text/javascript" src="forge/aesCipherSuites.js"></script> - <script type="text/javascript" src="common.js"></script> - - <link type="text/css" rel="stylesheet" media="all" href="screen.css" /> - <style type="text/css"> - .ready { color: inherit; background: inherit; } - .testing { color: black; background: yellow; } - .pass{ color: white; background: green; } - .fail{ color: white; background: red; } - </style> - </head> -<body> -<div class="nav"><a href="index.html">Forge Tests</a> / Common</div> - -<div class="header"> - <h1>Common Tests</h1> -</div> - -<div class="content"> - -<fieldset class="section"> - <ul> - <li>Test various Forge components.</li> - <li>See JavaScript console for more detailed output.</li> - </ul> -</fieldset> - -<fieldset class="section"> -<legend>Control</legend> - <button id="start">Start</button> - <button id="reset">Reset</button> - <br/> - <input id="scroll" type="checkbox" />Scroll Tests - <br/> - <button id="keygen">Generate RSA key pair</button> - <button id="certgen">Generate RSA certificate</button> - <input id="bits" value="1024"/>bits -</fieldset> - -<fieldset class="section"> -<legend>Progress</legend> -Status: <span id="status">?</span><br/> -Pass: <span id="pass">?</span>/<span id="total">?</span><br/> -Fail: <span id="fail">?</span> -</fieldset> - -<fieldset class="section"> -<legend>Tests</legend> -<div id="tests"></div> -</fieldset> - -</div> - -</body> -</html> diff --git a/alarm/node_modules/node-forge/tests/common.js b/alarm/node_modules/node-forge/tests/common.js deleted file mode 100644 index 57dfbc4..0000000 --- a/alarm/node_modules/node-forge/tests/common.js +++ /dev/null @@ -1,2199 +0,0 @@ -/** - * Forge Common Tests - * - * @author Dave Longley - * - * Copyright (c) 2009-2012 Digital Bazaar, Inc. All rights reserved. - */ -jQuery(function($) -{ - // logging category - var cat = 'forge.tests.common'; - - // local alias - var forge = window.forge; - - var tests = []; - var passed = 0; - var failed = 0; - - var init = function() - { - passed = failed = 0; - $('.ready,.testing,.pass,.fail') - .removeClass('ready testing pass fail'); - $('#status') - .text('Ready.') - .addClass('ready'); - $('#total').text(tests.length); - $('#pass').text(passed); - $('#fail').text(failed); - $('.expect').empty(); - $('.result').empty(); - $('.time').empty(); - $('.timePer').empty(); - $('#start').attr('disabled', ''); - }; - - var start = function() - { - $('#start').attr('disabled', 'true'); - // meta! use tasks to run the task tests - forge.task.start({ - type: 'test', - run: function(task) { - task.next('starting', function(task) { - forge.log.debug(cat, 'start'); - $('#status') - .text('Testing...') - .addClass('testing') - .removeClass('idle'); - }); - $.each(tests, function(i, test) { - task.next('test', function(task) { - var title = $('li:first', test.container); - if($('#scroll:checked').length === 1) - { - $('html,body').animate({scrollTop: title.offset().top}); - } - title.addClass('testing'); - test.run(task, test); - }); - task.next('test', function(task) { - $('li:first', test.container).removeClass('testing'); - }); - }); - task.next('success', function(task) { - forge.log.debug(cat, 'done'); - if(failed === 0) { - $('#status') - .text('PASS') - .addClass('pass') - .removeClass('testing'); - } else { - // FIXME: should just be hitting failure() below - $('#status') - .text('FAIL') - .addClass('fail') - .removeClass('testing'); - } - }); - }, - failure: function() { - $('#status') - .text('FAIL') - .addClass('fail') - .removeClass('testing'); - } - }); - }; - - $('#start').click(function() { - start(); - }); - - $('#reset').click(function() { - init(); - }); - - $('#keygen').click(function() { - var bits = $('#bits')[0].value; - var keys = forge.pki.rsa.generateKeyPair(bits); - forge.log.debug(cat, 'generating ' + bits + '-bit RSA key-pair...'); - setTimeout(function() - { - forge.log.debug(cat, 'private key:', keys.privateKey); - forge.log.debug(cat, forge.pki.privateKeyToPem(keys.privateKey)); - forge.log.debug(cat, 'public key:', keys.publicKey); - forge.log.debug(cat, forge.pki.publicKeyToPem(keys.publicKey)); - - forge.log.debug(cat, 'testing sign/verify...'); - setTimeout(function() - { - // do sign/verify test - try - { - var md = forge.md.sha1.create(); - md.update('foo'); - var signature = keys.privateKey.sign(md); - keys.publicKey.verify(md.digest().getBytes(), signature); - forge.log.debug(cat, 'sign/verify success'); - } - catch(ex) - { - forge.log.error(cat, 'sign/verify failure', ex); - } - }, 0); - }, 0); - }); - - $('#certgen').click(function() { - var bits = $('#bits')[0].value; - forge.log.debug(cat, 'generating ' + bits + - '-bit RSA key-pair and certificate...'); - setTimeout(function() - { - try - { - var keys = forge.pki.rsa.generateKeyPair(bits); - var cert = forge.pki.createCertificate(); - cert.serialNumber = '01'; - cert.validity.notBefore = new Date(); - cert.validity.notAfter = new Date(); - cert.validity.notAfter.setFullYear( - cert.validity.notBefore.getFullYear() + 1); - var attrs = [{ - name: 'commonName', - value: 'mycert' - }, { - name: 'countryName', - value: 'US' - }, { - shortName: 'ST', - value: 'Virginia' - }, { - name: 'localityName', - value: 'Blacksburg' - }, { - name: 'organizationName', - value: 'Test' - }, { - shortName: 'OU', - value: 'Test' - }]; - cert.setSubject(attrs); - cert.setIssuer(attrs); - cert.setExtensions([{ - name: 'basicConstraints', - cA: true - }, { - name: 'keyUsage', - keyCertSign: true - }, { - name: 'subjectAltName', - altNames: [{ - type: 6, // URI - value: 'http://localhost/dataspace/person/myname#this' - }] - }]); - // FIXME: add subjectKeyIdentifier extension - // FIXME: add authorityKeyIdentifier extension - cert.publicKey = keys.publicKey; - - // self-sign certificate - cert.sign(keys.privateKey); - - forge.log.debug(cat, 'certificate:', cert); - //forge.log.debug(cat, - // forge.asn1.prettyPrint(forge.pki.certificateToAsn1(cert))); - forge.log.debug(cat, forge.pki.certificateToPem(cert)); - - // verify certificate - forge.log.debug(cat, 'verified', cert.verify(cert)); - } - catch(ex) - { - forge.log.error(cat, ex, ex.message ? ex.message : ''); - } - }, 0); - }); - - var addTest = function(name, run) - { - var container = $('<ul><li>Test ' + name + '</li><ul/></ul>'); - var expect = $('<li>Expect: <span class="expect"/></li>'); - var result = $('<li>Result: <span class="result"/></li>'); - var time = $('<li>Time: <span class="time"/></li>'); - var timePer = $('<li>Time Per Iteration: <span class="timePer"/></li>'); - $('ul', container) - .append(expect) - .append(result) - .append(time) - .append(timePer); - $('#tests').append(container); - var test = { - container: container, - startTime: null, - run: function(task, test) { - test.startTime = new Date(); - run(task, test); - }, - expect: $('span', expect), - result: $('span', result), - check: function() { - var e = test.expect.text(); - var r = test.result.text(); - (e == r) ? test.pass() : test.fail(); - }, - pass: function(iterations) { - var dt = new Date() - test.startTime; - if(!iterations) - { - iterations = 1; - } - var dti = (dt / iterations); - passed += 1; - $('#pass').text(passed); - $('li:first', container).addClass('pass'); - $('span.time', container).html(dt + 'ms'); - $('span.timePer', container).html(dti + 'ms'); - }, - fail: function(iterations) { - var dt = new Date() - test.startTime; - if(!iterations) - { - iterations = 1; - } - var dti = (dt / iterations); - failed += 1; - $('#fail').text(failed); - $('li:first', container).addClass('fail'); - $('span.time', container).html(dt + 'ms'); - $('span.timePer', container).html(dti + 'ms'); - } - }; - tests.push(test); - }; - - addTest('buffer put bytes', function(task, test) - { - ba = forge.util.createBuffer(); - ba.putByte(1); - ba.putByte(2); - ba.putByte(3); - ba.putByte(4); - ba.putInt32(4); - ba.putByte(1); - ba.putByte(2); - ba.putByte(3); - ba.putInt32(4294967295); - var hex = ba.toHex(); - var bytes = []; - while(ba.length() > 0) - { - bytes.push(ba.getByte()); - } - var expect = [1, 2, 3, 4, 0, 0, 0, 4, 1, 2, 3, 255, 255, 255, 255]; - var exHex = '0102030400000004010203ffffffff'; - test.expect.html(exHex); - test.result.html(hex); - - test.check(); - }); - - addTest('buffer from hex', function(task, test) - { - var exHex = '0102030400000004010203ffffffff'; - test.expect.html(exHex); - - var buf = forge.util.createBuffer(); - buf.putBytes(forge.util.hexToBytes(exHex)); - test.result.html(buf.toHex()); - - test.check(); - }); - - addTest('base64 encode', function(task, test) - { - var s1 = '00010203050607080A0B0C0D0F1011121415161719'; - var s2 = 'MDAwMTAyMDMwNTA2MDcwODBBMEIwQzBEMEYxMDExMTIxNDE1MTYxNzE5'; - test.expect.html(s2); - - var out = forge.util.encode64(s1); - test.result.html(out); - - test.check(); - }); - - addTest('base64 decode', function(task, test) - { - var s1 = '00010203050607080A0B0C0D0F1011121415161719'; - var s2 = 'MDAwMTAyMDMwNTA2MDcwODBBMEIwQzBEMEYxMDExMTIxNDE1MTYxNzE5'; - test.expect.html(s1); - - var out = forge.util.decode64(s2); - test.result.html(out); - - test.check(); - }); - - addTest('md5 empty', function(task, test) - { - var expect = 'd41d8cd98f00b204e9800998ecf8427e'; - test.expect.html(expect); - var md = forge.md.md5.create(); - test.result.html(md.digest().toHex()); - test.check(); - }); - - addTest('md5 "abc"', function(task, test) - { - var expect = '900150983cd24fb0d6963f7d28e17f72'; - test.expect.html(expect); - var md = forge.md.md5.create(); - md.update('abc'); - test.result.html(md.digest().toHex()); - test.check(); - }); - - addTest('md5 "The quick brown fox jumps over the lazy dog"', - function(task, test) - { - var expect = '9e107d9d372bb6826bd81d3542a419d6'; - test.expect.html(expect); - var md = forge.md.md5.create(); - md.start(); - md.update('The quick brown fox jumps over the lazy dog'); - test.result.html(md.digest().toHex()); - test.check(); - }); - - // c'è - addTest('md5 "c\'\u00e8"', function(task, test) - { - var expect = '8ef7c2941d78fe89f31e614437c9db59'; - test.expect.html(expect); - var md = forge.md.md5.create(); - md.update("c'\u00e8", 'utf8'); - test.result.html(md.digest().toHex()); - test.check(); - }); - - addTest('md5 "THIS IS A MESSAGE"', - function(task, test) - { - var expect = '78eebfd9d42958e3f31244f116ab7bbe'; - test.expect.html(expect); - var md = forge.md.md5.create(); - md.start(); - md.update('THIS IS '); - md.update('A MESSAGE'); - // do twice to check continuing digest - test.result.html(md.digest().toHex()); - test.result.html(md.digest().toHex()); - test.check(); - }); - - addTest('md5 long message', - function(task, test) - { - var input = forge.util.createBuffer(); - input.putBytes(forge.util.hexToBytes( - '0100002903018d32e9c6dc423774c4c39a5a1b78f44cc2cab5f676d39' + - 'f703d29bfa27dfeb870000002002f0100')); - input.putBytes(forge.util.hexToBytes( - '0200004603014c2c1e835d39da71bc0857eb04c2b50fe90dbb2a8477f' + - 'e7364598d6f0575999c20a6c7248c5174da6d03ac711888f762fc4ed5' + - '4f7254b32273690de849c843073d002f00')); - input.putBytes(forge.util.hexToBytes( - '0b0003d20003cf0003cc308203c8308202b0a003020102020100300d0' + - '6092a864886f70d0101050500308186310b3009060355040613025553' + - '311d301b060355040a13144469676974616c2042617a6161722c20496' + - 'e632e31443042060355040b133b4269746d756e6b206c6f63616c686f' + - '73742d6f6e6c7920436572746966696361746573202d20417574686f7' + - '2697a6174696f6e207669612042545031123010060355040313096c6f' + - '63616c686f7374301e170d3130303231343137303931395a170d32303' + - '03231333137303931395a308186310b3009060355040613025553311d' + - '301b060355040a13144469676974616c2042617a6161722c20496e632' + - 'e31443042060355040b133b4269746d756e6b206c6f63616c686f7374' + - '2d6f6e6c7920436572746966696361746573202d20417574686f72697' + - 'a6174696f6e207669612042545031123010060355040313096c6f6361' + - '6c686f737430820122300d06092a864886f70d01010105000382010f0' + - '03082010a0282010100dc436f17d6909d8a9d6186ea218eb5c86b848b' + - 'ae02219bd56a71203daf07e81bc19e7e98134136bcb012881864bf03b' + - '3774652ad5eab85dba411a5114ffeac09babce75f31314345512cd87c' + - '91318b2e77433270a52185fc16f428c3ca412ad6e9484bc2fb87abb4e' + - '8fb71bf0f619e31a42340b35967f06c24a741a31c979c0bb8921a90a4' + - '7025fbeb8adca576979e70a56830c61170c9647c18c0794d68c0df38f' + - '3aac5fc3b530e016ea5659715339f3f3c209cdee9dbe794b5af92530c' + - '5754c1d874b78974bfad994e0dfc582275e79feb522f6e4bcc2b2945b' + - 'aedfb0dbdaebb605f9483ff0bea29ecd5f4d6f2769965d1b3e04f8422' + - '716042680011ff676f0203010001a33f303d300c0603551d130101ff0' + - '4023000300e0603551d0f0101ff0404030204f0301d0603551d250416' + - '301406082b0601050507030106082b06010505070302300d06092a864' + - '886f70d010105050003820101009c4562be3f2d8d8e388085a697f2f1' + - '06eaeff4992a43f198fe3dcf15c8229cf1043f061a38204f73d86f4fb' + - '6348048cc5279ed719873aa10e3773d92b629c2c3fcce04012c81ba3b' + - '4ec451e9644ec5191078402d845e05d02c7b4d974b4588276e5037aba' + - '7ef26a8bddeb21e10698c82f425e767dc401adf722fa73ab78cfa069b' + - 'd69052d7ca6a75cc9225550e315d71c5f8764362ea4dbc6ecb837a847' + - '1043c5a7f826a71af145a053090bd4bccca6a2c552841cdb1908a8352' + - 'f49283d2e641acdef667c7543af441a16f8294251e2ac376fa507b53a' + - 'e418dd038cd20cef1e7bfbf5ae03a7c88d93d843abaabbdc5f3431132' + - 'f3e559d2dd414c3eda38a210b8')); - input.putBytes(forge.util.hexToBytes('0e000000')); - input.putBytes(forge.util.hexToBytes( - '10000102010026a220b7be857402819b78d81080d01a682599bbd0090' + - '2985cc64edf8e520e4111eb0e1729a14ffa3498ca259cc9ad6fc78fa1' + - '30d968ebdb78dc0b950c0aa44355f13ba678419185d7e4608fe178ca6' + - 'b2cef33e4193778d1a70fe4d0dfcb110be4bbb4dbaa712177655728f9' + - '14ab4c0f6c4aef79a46b3d996c82b2ebe9ed1748eb5cace7dc44fb67e' + - '73f452a047f2ed199b3d50d5db960acf03244dc8efa4fc129faf8b65f' + - '9e52e62b5544722bd17d2358e817a777618a4265a3db277fc04851a82' + - 'a91fe6cdcb8127f156e0b4a5d1f54ce2742eb70c895f5f8b85f5febe6' + - '9bc73e891f9280826860a0c2ef94c7935e6215c3c4cd6b0e43e80cca3' + - '96d913d36be')); - - var expect = 'd15a2da0e92c3da55dc573f885b6e653'; - test.expect.html(expect); - - var md = forge.md.md5.create(); - md.start(); - md.update(input.getBytes()); - test.result.html(md.digest().toHex()); - - test.check(); - }); - - addTest('sha-1 empty', function(task, test) - { - var expect = 'da39a3ee5e6b4b0d3255bfef95601890afd80709'; - test.expect.html(expect); - var md = forge.md.sha1.create(); - test.result.html(md.digest().toHex()); - test.check(); - }); - - addTest('sha-1 "abc"', function(task, test) - { - var expect = 'a9993e364706816aba3e25717850c26c9cd0d89d'; - test.expect.html(expect); - var md = forge.md.sha1.create(); - md.update('abc'); - test.result.html(md.digest().toHex()); - test.check(); - }); - - addTest('sha-1 "The quick brown fox jumps over the lazy dog"', - function(task, test) - { - var expect = '2fd4e1c67a2d28fced849ee1bb76e7391b93eb12'; - test.expect.html(expect); - var md = forge.md.sha1.create(); - md.start(); - md.update('The quick brown fox jumps over the lazy dog'); - test.result.html(md.digest().toHex()); - test.check(); - }); - - // c'è - addTest('sha-1 "c\'\u00e8"', function(task, test) - { - var expect = '98c9a3f804daa73b68a5660d032499a447350c0d'; - test.expect.html(expect); - var md = forge.md.sha1.create(); - md.update("c'\u00e8", 'utf8'); - test.result.html(md.digest().toHex()); - test.check(); - }); - - addTest('sha-1 "THIS IS A MESSAGE"', - function(task, test) - { - var expect = '5f24f4d6499fd2d44df6c6e94be8b14a796c071d'; - test.expect.html(expect); - var md = forge.md.sha1.create(); - md.start(); - md.update('THIS IS '); - md.update('A MESSAGE'); - // do twice to check continuing digest - test.result.html(md.digest().toHex()); - test.result.html(md.digest().toHex()); - test.check(); - }); - - // other browsers too slow for this test - if($.browser.webkit) - { - addTest('sha-1 long message', - function(task, test) - { - var expect = '34aa973cd4c4daa4f61eeb2bdbad27316534016f'; - test.expect.html(expect); - var md = forge.md.sha1.create(); - md.start(); - md.update(forge.util.fillString('a', 1000000)); - // do twice to check continuing digest - test.result.html(md.digest().toHex()); - test.result.html(md.digest().toHex()); - test.check(); - }); - } - - addTest('sha-256 "abc"', function(task, test) - { - var expect = - 'ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad'; - test.expect.html(expect); - var md = forge.md.sha256.create(); - md.update('abc'); - test.result.html(md.digest().toHex()); - test.check(); - }); - - // c'è - addTest('sha-256 "c\'\u00e8"', function(task, test) - { - var expect = - '1aa15c717afffd312acce2217ce1c2e5dabca53c92165999132ec9ca5decdaca'; - test.expect.html(expect); - var md = forge.md.sha256.create(); - md.update("c'\u00e8", 'utf8'); - test.result.html(md.digest().toHex()); - test.check(); - }); - - addTest('sha-256 "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"', - function(task, test) - { - var expect = - '248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1'; - test.expect.html(expect); - var md = forge.md.sha256.create(); - md.start(); - md.update('abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq'); - test.result.html(md.digest().toHex()); - test.check(); - }); - - // other browsers too slow for this test - if($.browser.webkit) - { - addTest('sha-256 long message', - function(task, test) - { - var expect = - 'cdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd0'; - test.expect.html(expect); - var md = forge.md.sha256.create(); - md.start(); - md.update(forge.util.fillString('a', 1000000)); - // do twice to check continuing digest - test.result.html(md.digest().toHex()); - test.result.html(md.digest().toHex()); - test.check(); - }); - } - - addTest('hmac md5 "Hi There", 16-byte key', function(task, test) - { - var expect = '9294727a3638bb1c13f48ef8158bfc9d'; - test.expect.html(expect); - var key = forge.util.hexToBytes( - '0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b'); - var hmac = forge.hmac.create(); - hmac.start('MD5', key); - hmac.update('Hi There'); - test.result.html(hmac.digest().toHex()); - test.check(); - }); - - addTest('hmac md5 "what do ya want for nothing?", "Jefe" key', - function(task, test) - { - var expect = '750c783e6ab0b503eaa86e310a5db738'; - test.expect.html(expect); - var hmac = forge.hmac.create(); - hmac.start('MD5', 'Jefe'); - hmac.update('what do ya want for nothing?'); - test.result.html(hmac.digest().toHex()); - test.check(); - }); - - addTest('hmac md5 "Test Using Larger Than Block-Size Key - ' + - 'Hash Key First", 80-byte key', function(task, test) - { - var expect = '6b1ab7fe4bd7bf8f0b62e6ce61b9d0cd'; - test.expect.html(expect); - var key = forge.util.hexToBytes( - 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + - 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + - 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + - 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'); - var hmac = forge.hmac.create(); - hmac.start('MD5', key); - hmac.update('Test Using Larger Than Block-Size Key - Hash Key First'); - test.result.html(hmac.digest().toHex()); - test.check(); - }); - - addTest('hmac sha-1 "Hi There", 20-byte key', function(task, test) - { - var expect = 'b617318655057264e28bc0b6fb378c8ef146be00'; - test.expect.html(expect); - var key = forge.util.hexToBytes( - '0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b'); - var hmac = forge.hmac.create(); - hmac.start('SHA1', key); - hmac.update('Hi There'); - test.result.html(hmac.digest().toHex()); - test.check(); - }); - - addTest('hmac sha-1 "what do ya want for nothing?", "Jefe" key', - function(task, test) - { - var expect = 'effcdf6ae5eb2fa2d27416d5f184df9c259a7c79'; - test.expect.html(expect); - var hmac = forge.hmac.create(); - hmac.start('SHA1', 'Jefe'); - hmac.update('what do ya want for nothing?'); - test.result.html(hmac.digest().toHex()); - test.check(); - }); - - addTest('hmac sha-1 "Test Using Larger Than Block-Size Key - ' + - 'Hash Key First", 80-byte key', function(task, test) - { - var expect = 'aa4ae5e15272d00e95705637ce8a3b55ed402112'; - test.expect.html(expect); - var key = forge.util.hexToBytes( - 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + - 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + - 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + - 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'); - var hmac = forge.hmac.create(); - hmac.start('SHA1', key); - hmac.update('Test Using Larger Than Block-Size Key - Hash Key First'); - test.result.html(hmac.digest().toHex()); - test.check(); - }); - - addTest('pbkdf2 hmac-sha-1 c=1', function(task, test) - { - var expect = '0c60c80f961f0e71f3a9b524af6012062fe037a6'; - var dk = forge.pkcs5.pbkdf2('password', 'salt', 1, 20); - test.expect.html(expect); - test.result.html(forge.util.bytesToHex(dk)); - test.check(); - }); - - addTest('pbkdf2 hmac-sha-1 c=2', function(task, test) - { - var expect = 'ea6c014dc72d6f8ccd1ed92ace1d41f0d8de8957'; - var dk = forge.pkcs5.pbkdf2('password', 'salt', 2, 20); - test.expect.html(expect); - test.result.html(forge.util.bytesToHex(dk)); - test.check(); - }); - - addTest('pbkdf2 hmac-sha-1 c=2', function(task, test) - { - var expect = 'ea6c014dc72d6f8ccd1ed92ace1d41f0d8de8957'; - var dk = forge.pkcs5.pbkdf2('password', 'salt', 2, 20); - test.expect.html(expect); - test.result.html(forge.util.bytesToHex(dk)); - test.check(); - }); - - addTest('pbkdf2 hmac-sha-1 c=5 keylen=8', function(task, test) - { - var expect = 'd1daa78615f287e6'; - var salt = forge.util.hexToBytes('1234567878563412'); - var dk = forge.pkcs5.pbkdf2('password', salt, 5, 8); - test.expect.html(expect); - test.result.html(forge.util.bytesToHex(dk)); - test.check(); - }); - - // other browsers too slow for this test - if($.browser.webkit) - { - addTest('pbkdf2 hmac-sha-1 c=4096', function(task, test) - { - var expect = '4b007901b765489abead49d926f721d065a429c1'; - var dk = forge.pkcs5.pbkdf2('password', 'salt', 4096, 20); - test.expect.html(expect); - test.result.html(forge.util.bytesToHex(dk)); - test.check(); - }); - } - - /* too slow for javascript - addTest('pbkdf2 hmac-sha-1 c=16777216', function(task, test) - { - var expect = 'eefe3d61cd4da4e4e9945b3d6ba2158c2634e984'; - var dk = forge.pkcs5.pbkdf2('password', 'salt', 16777216, 20); - test.expect.html(expect); - test.result.html(forge.util.bytesToHex(dk)); - test.check(); - });*/ - - addTest('aes-128 encrypt', function(task, test) - { - var block = []; - block.push(0x00112233); - block.push(0x44556677); - block.push(0x8899aabb); - block.push(0xccddeeff); - var plain = block; - - var key = []; - key.push(0x00010203); - key.push(0x04050607); - key.push(0x08090a0b); - key.push(0x0c0d0e0f); - - var expect = []; - expect.push(0x69c4e0d8); - expect.push(0x6a7b0430); - expect.push(0xd8cdb780); - expect.push(0x70b4c55a); - - test.expect.html('69c4e0d86a7b0430d8cdb78070b4c55a'); - - var output = []; - var w = forge.aes._expandKey(key, false); - forge.aes._updateBlock(w, block, output, false); - - var out = forge.util.createBuffer(); - out.putInt32(output[0]); - out.putInt32(output[1]); - out.putInt32(output[2]); - out.putInt32(output[3]); - test.result.html(out.toHex()); - - test.check(); - }); - - addTest('aes-128 decrypt', function(task, test) - { - var block = []; - block.push(0x69c4e0d8); - block.push(0x6a7b0430); - block.push(0xd8cdb780); - block.push(0x70b4c55a); - - var key = []; - key.push(0x00010203); - key.push(0x04050607); - key.push(0x08090a0b); - key.push(0x0c0d0e0f); - - var expect = []; - expect.push(0x00112233); - expect.push(0x44556677); - expect.push(0x8899aabb); - expect.push(0xccddeeff); - - test.expect.html('00112233445566778899aabbccddeeff'); - - var output = []; - w = forge.aes._expandKey(key, true); - forge.aes._updateBlock(w, block, output, true); - - var out = forge.util.createBuffer(); - out.putInt32(output[0]); - out.putInt32(output[1]); - out.putInt32(output[2]); - out.putInt32(output[3]); - test.result.html(out.toHex()); - - test.check(); - }); - - addTest('aes-192 encrypt', function(task, test) - { - var block = []; - block.push(0x00112233); - block.push(0x44556677); - block.push(0x8899aabb); - block.push(0xccddeeff); - var plain = block; - - var key = []; - key.push(0x00010203); - key.push(0x04050607); - key.push(0x08090a0b); - key.push(0x0c0d0e0f); - key.push(0x10111213); - key.push(0x14151617); - - var expect = []; - expect.push(0xdda97ca4); - expect.push(0x864cdfe0); - expect.push(0x6eaf70a0); - expect.push(0xec0d7191); - - test.expect.html('dda97ca4864cdfe06eaf70a0ec0d7191'); - - var output = []; - var w = forge.aes._expandKey(key, false); - forge.aes._updateBlock(w, block, output, false); - - var out = forge.util.createBuffer(); - out.putInt32(output[0]); - out.putInt32(output[1]); - out.putInt32(output[2]); - out.putInt32(output[3]); - test.result.html(out.toHex()); - - test.check(); - }); - - addTest('aes-192 decrypt', function(task, test) - { - var block = []; - block.push(0xdda97ca4); - block.push(0x864cdfe0); - block.push(0x6eaf70a0); - block.push(0xec0d7191); - - var key = []; - key.push(0x00010203); - key.push(0x04050607); - key.push(0x08090a0b); - key.push(0x0c0d0e0f); - key.push(0x10111213); - key.push(0x14151617); - - var expect = []; - expect.push(0x00112233); - expect.push(0x44556677); - expect.push(0x8899aabb); - expect.push(0xccddeeff); - - test.expect.html('00112233445566778899aabbccddeeff'); - - var output = []; - w = forge.aes._expandKey(key, true); - forge.aes._updateBlock(w, block, output, true); - - var out = forge.util.createBuffer(); - out.putInt32(output[0]); - out.putInt32(output[1]); - out.putInt32(output[2]); - out.putInt32(output[3]); - test.result.html(out.toHex()); - - test.check(); - }); - - addTest('aes-256 encrypt', function(task, test) - { - var block = []; - block.push(0x00112233); - block.push(0x44556677); - block.push(0x8899aabb); - block.push(0xccddeeff); - var plain = block; - - var key = []; - key.push(0x00010203); - key.push(0x04050607); - key.push(0x08090a0b); - key.push(0x0c0d0e0f); - key.push(0x10111213); - key.push(0x14151617); - key.push(0x18191a1b); - key.push(0x1c1d1e1f); - - var expect = []; - expect.push(0x8ea2b7ca); - expect.push(0x516745bf); - expect.push(0xeafc4990); - expect.push(0x4b496089); - - test.expect.html('8ea2b7ca516745bfeafc49904b496089'); - - var output = []; - var w = forge.aes._expandKey(key, false); - forge.aes._updateBlock(w, block, output, false); - - var out = forge.util.createBuffer(); - out.putInt32(output[0]); - out.putInt32(output[1]); - out.putInt32(output[2]); - out.putInt32(output[3]); - test.result.html(out.toHex()); - - test.check(); - }); - - addTest('aes-256 decrypt', function(task, test) - { - var block = []; - block.push(0x8ea2b7ca); - block.push(0x516745bf); - block.push(0xeafc4990); - block.push(0x4b496089); - - var key = []; - key.push(0x00010203); - key.push(0x04050607); - key.push(0x08090a0b); - key.push(0x0c0d0e0f); - key.push(0x10111213); - key.push(0x14151617); - key.push(0x18191a1b); - key.push(0x1c1d1e1f); - - var expect = []; - expect.push(0x00112233); - expect.push(0x44556677); - expect.push(0x8899aabb); - expect.push(0xccddeeff); - - test.expect.html('00112233445566778899aabbccddeeff'); - - var output = []; - w = forge.aes._expandKey(key, true); - forge.aes._updateBlock(w, block, output, true); - - var out = forge.util.createBuffer(); - out.putInt32(output[0]); - out.putInt32(output[1]); - out.putInt32(output[2]); - out.putInt32(output[3]); - test.result.html(out.toHex()); - - test.check(); - }); - - (function() - { - var keys = [ - '06a9214036b8a15b512e03d534120006', - 'c286696d887c9aa0611bbb3e2025a45a', - '6c3ea0477630ce21a2ce334aa746c2cd', - '56e47a38c5598974bc46903dba290349' - ]; - - var ivs = [ - '3dafba429d9eb430b422da802c9fac41', - '562e17996d093d28ddb3ba695a2e6f58', - 'c782dc4c098c66cbd9cd27d825682c81', - '8ce82eefbea0da3c44699ed7db51b7d9' - ]; - - var inputs = [ - 'Single block msg', - '000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f', - 'This is a 48-byte message (exactly 3 AES blocks)', - 'a0a1a2a3a4a5a6a7a8a9aaabacadaeaf' + - 'b0b1b2b3b4b5b6b7b8b9babbbcbdbebf' + - 'c0c1c2c3c4c5c6c7c8c9cacbcccdcecf' + - 'd0d1d2d3d4d5d6d7d8d9dadbdcdddedf' - ]; - - var outputs = [ - 'e353779c1079aeb82708942dbe77181a', - 'd296cd94c2cccf8a3a863028b5e1dc0a7586602d253cfff91b8266bea6d61ab1', - 'd0a02b3836451753d493665d33f0e886' + - '2dea54cdb293abc7506939276772f8d5' + - '021c19216bad525c8579695d83ba2684', - 'c30e32ffedc0774e6aff6af0869f71aa' + - '0f3af07a9a31a9c684db207eb0ef8e4e' + - '35907aa632c3ffdf868bb7b29d3d46ad' + - '83ce9f9a102ee99d49a53e87f4c3da55' - ]; - - for(var i = 0; i < keys.length; ++i) - { - (function(i) - { - var key = forge.util.hexToBytes(keys[i]); - var iv = forge.util.hexToBytes(ivs[i]); - var input = (i & 1) ? forge.util.hexToBytes(inputs[i]) : inputs[i]; - var output = forge.util.hexToBytes(outputs[i]); - - addTest('aes-128 cbc encrypt', function(task, test) - { - // encrypt w/no padding - test.expect.html(outputs[i]); - var cipher = forge.aes.createEncryptionCipher(key); - cipher.start(iv); - cipher.update(forge.util.createBuffer(input)); - cipher.finish(function(){return true;}); - test.result.html(cipher.output.toHex()); - test.check(); - }); - - addTest('aes-128 cbc decrypt', function(task, test) - { - // decrypt w/no padding - test.expect.html(inputs[i]); - var cipher = forge.aes.createDecryptionCipher(key); - cipher.start(iv); - cipher.update(forge.util.createBuffer(output)); - cipher.finish(function(){return true;}); - var out = (i & 1) ? - cipher.output.toHex() : cipher.output.bytes(); - test.result.html(out); - test.check(); - }); - })(i); - } - })(); - - (function() - { - var keys = [ - '00000000000000000000000000000000', - '2b7e151628aed2a6abf7158809cf4f3c', - '2b7e151628aed2a6abf7158809cf4f3c', - '2b7e151628aed2a6abf7158809cf4f3c', - '2b7e151628aed2a6abf7158809cf4f3c', - '00000000000000000000000000000000' - ]; - - var ivs = [ - '80000000000000000000000000000000', - '000102030405060708090a0b0c0d0e0f', - '3B3FD92EB72DAD20333449F8E83CFB4A', - 'C8A64537A0B3A93FCDE3CDAD9F1CE58B', - '26751F67A3CBB140B1808CF187A4F4DF', - '60f9ff04fac1a25657bf5b36b5efaf75' - ]; - - var inputs = [ - '00000000000000000000000000000000', - '6bc1bee22e409f96e93d7e117393172a', - 'ae2d8a571e03ac9c9eb76fac45af8e51', - '30c81c46a35ce411e5fbc1191a0a52ef', - 'f69f2445df4f9b17ad2b417be66c3710', - 'This is a 48-byte message (exactly 3 AES blocks)' - ]; - - var outputs = [ - '3ad78e726c1ec02b7ebfe92b23d9ec34', - '3b3fd92eb72dad20333449f8e83cfb4a', - 'c8a64537a0b3a93fcde3cdad9f1ce58b', - '26751f67a3cbb140b1808cf187a4f4df', - 'c04b05357c5d1c0eeac4c66f9ff7f2e6', - '52396a2ba1ba420c5e5b699a814944d8' + - 'f4e7fbf984a038319fbc0b4ee45cfa6f' + - '07b2564beab5b5e92dbd44cb345f49b4' - ]; - - for(var i = 0; i < keys.length; ++i) - { - (function(i) - { - var key = forge.util.hexToBytes(keys[i]); - var iv = forge.util.hexToBytes(ivs[i]); - var input = (i !== 5) ? - forge.util.hexToBytes(inputs[i]) : inputs[i]; - var output = forge.util.hexToBytes(outputs[i]); - - addTest('aes-128 cfb encrypt', function(task, test) - { - // encrypt - test.expect.html(outputs[i]); - var cipher = forge.aes.createEncryptionCipher(key, 'CFB'); - cipher.start(iv); - cipher.update(forge.util.createBuffer(input)); - cipher.finish(); - test.result.html(cipher.output.toHex()); - test.check(); - }); - - addTest('aes-128 cfb decrypt', function(task, test) - { - // decrypt - test.expect.html(inputs[i]); - var cipher = forge.aes.createDecryptionCipher(key, 'CFB'); - cipher.start(iv); - cipher.update(forge.util.createBuffer(output)); - cipher.finish(); - var out = (i !== 5) ? - cipher.output.toHex() : cipher.output.getBytes(); - test.result.html(out); - test.check(); - }); - })(i); - } - })(); - - (function() - { - var keys = [ - '861009ec4d599fab1f40abc76e6f89880cff5833c79c548c99f9045f191cd90b' - ]; - - var ivs = [ - 'd927ad81199aa7dcadfdb4e47b6dc694' - ]; - - var inputs = [ - 'MY-DATA-AND-HERE-IS-MORE-DATA' - ]; - - var outputs = [ - '80eb666a9fc9e263faf71e87ffc94451d7d8df7cfcf2606470351dd5ac' - ]; - - for(var i = 0; i < keys.length; ++i) - { - (function(i) - { - var key = forge.util.hexToBytes(keys[i]); - var iv = forge.util.hexToBytes(ivs[i]); - var input = inputs[i]; - var output = forge.util.hexToBytes(outputs[i]); - - addTest('aes-256 cfb encrypt', function(task, test) - { - // encrypt - test.expect.html(outputs[i]); - var cipher = forge.aes.createEncryptionCipher(key, 'CFB'); - cipher.start(iv); - cipher.update(forge.util.createBuffer(input)); - cipher.finish(); - test.result.html(cipher.output.toHex()); - test.check(); - }); - - addTest('aes-256 cfb decrypt', function(task, test) - { - // decrypt - test.expect.html(inputs[i]); - var cipher = forge.aes.createDecryptionCipher(key, 'CFB'); - cipher.start(iv); - cipher.update(forge.util.createBuffer(output)); - cipher.finish(); - var out = cipher.output.getBytes(); - test.result.html(out); - test.check(); - }); - })(i); - } - })(); - - (function() - { - var keys = [ - '00000000000000000000000000000000', - '00000000000000000000000000000000' - ]; - - var ivs = [ - '80000000000000000000000000000000', - 'c8ca0d6a35dbeac776e911ee16bea7d3' - ]; - - var inputs = [ - '00000000000000000000000000000000', - 'This is a 48-byte message (exactly 3 AES blocks)' - ]; - - var outputs = [ - '3ad78e726c1ec02b7ebfe92b23d9ec34', - '39c0190727a76b2a90963426f63689cf' + - 'cdb8a2be8e20c5e877a81a724e3611f6' + - '2ecc386f2e941b2441c838906002be19' - ]; - - for(var i = 0; i < keys.length; ++i) - { - (function(i) - { - var key = forge.util.hexToBytes(keys[i]); - var iv = forge.util.hexToBytes(ivs[i]); - var input = (i !== 1) ? - forge.util.hexToBytes(inputs[i]) : inputs[i]; - var output = forge.util.hexToBytes(outputs[i]); - - addTest('aes-128 ofb encrypt', function(task, test) - { - // encrypt w/no padding - test.expect.html(outputs[i]); - var cipher = forge.aes.createEncryptionCipher(key, 'OFB'); - cipher.start(iv); - cipher.update(forge.util.createBuffer(input)); - cipher.finish(function(){return true;}); - test.result.html(cipher.output.toHex()); - test.check(); - }); - - addTest('aes-128 ofb decrypt', function(task, test) - { - // decrypt w/no padding - test.expect.html(inputs[i]); - var cipher = forge.aes.createDecryptionCipher(key, 'OFB'); - cipher.start(iv); - cipher.update(forge.util.createBuffer(output)); - cipher.finish(function(){return true;}); - var out = (i !== 1) ? - cipher.output.toHex() : cipher.output.getBytes(); - test.result.html(out); - test.check(); - }); - })(i); - } - })(); - - (function() - { - var keys = [ - '00000000000000000000000000000000', - '2b7e151628aed2a6abf7158809cf4f3c' - ]; - - var ivs = [ - '650cdb80ff9fc758342d2bd99ee2abcf', - 'f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff' - ]; - - var inputs = [ - 'This is a 48-byte message (exactly 3 AES blocks)', - '6bc1bee22e409f96e93d7e117393172a' - ]; - - var outputs = [ - '5ede11d00e9a76ec1d5e7e811ea3dd1c' + - 'e09ee941210f825d35718d3282796f1c' + - '07c3f1cb424f2b365766ab5229f5b5a4', - '874d6191b620e3261bef6864990db6ce' - ]; - - for(var i = 0; i < keys.length; ++i) - { - (function(i) - { - var key = forge.util.hexToBytes(keys[i]); - var iv = forge.util.hexToBytes(ivs[i]); - var input = (i !== 0) ? - forge.util.hexToBytes(inputs[i]) : inputs[i]; - var output = forge.util.hexToBytes(outputs[i]); - - addTest('aes-128 ctr encrypt', function(task, test) - { - // encrypt w/no padding - test.expect.html(outputs[i]); - var cipher = forge.aes.createEncryptionCipher(key, 'CTR'); - cipher.start(iv); - cipher.update(forge.util.createBuffer(input)); - cipher.finish(function(){return true;}); - test.result.html(cipher.output.toHex()); - test.check(); - }); - - addTest('aes-128 ctr decrypt', function(task, test) - { - // decrypt w/no padding - test.expect.html(inputs[i]); - var cipher = forge.aes.createDecryptionCipher(key, 'CTR'); - cipher.start(iv); - cipher.update(forge.util.createBuffer(output)); - cipher.finish(function(){return true;}); - var out = (i !== 0) ? - cipher.output.toHex() : cipher.output.getBytes(); - test.result.html(out); - test.check(); - }); - })(i); - } - })(); - - addTest('private key encryption', function(task, test) - { - var _privateKey = - '-----BEGIN RSA PRIVATE KEY-----\r\n' + - 'MIICXQIBAAKBgQDL0EugUiNGMWscLAVM0VoMdhDZEJOqdsUMpx9U0YZI7szokJqQ\r\n' + - 'NIwokiQ6EonNnWSMlIvy46AhnlRYn+ezeTeU7eMGTkP3VF29vXBo+dLq5e+8VyAy\r\n' + - 'Q3FzM1wI4ts4hRACF8w6mqygXQ7i/SDu8/rXqRGtvnM+z0MYDdKo80efzwIDAQAB\r\n' + - 'AoGAIzkGONi5G+JifmXlLJdplom486p3upf4Ce2/7mqfaG9MnkyPSairKD/JXvfh\r\n' + - 'NNWkkN8DKKDKBcVVElPgORYT0qwrWc7ueLBMUCbRXb1ZyfEulimG0R3kjUh7NYau\r\n' + - 'DaIkVgfykXGSQMZx8FoaT6L080zd+0emKDDYRrb+/kgJNJECQQDoUZoiC2K/DWNY\r\n' + - 'h3/ppZ0ane2y4SBmJUHJVMPQ2CEgxsrJTxet668ckNCKaOP/3VFPoWC41f17DvKq\r\n' + - 'noYINNntAkEA4JbZBZBVUrQFhHlrpXT4jzqtO2RlKZzEq8qmFZfEErxOT1WMyyCi\r\n' + - 'lAQ5gUKardo1Kf0omC8Xq/uO9ZYdED55KwJBALs6cJ65UFaq4oLJiQPzLd7yokuE\r\n' + - 'dcj8g71PLBTW6jPxIiMFNA89nz3FU9wIVp+xbMNhSoMMKqIPVPC+m0Rn260CQQDA\r\n' + - 'I83fWK/mZWUjBM33a68KumRiH238v8XyQxj7+C8i6D8G2GXvkigFAehAkb7LZZd+\r\n' + - 'KLuGFyPlWv3fVWHf99KpAkBQFKk3MRMl6IGJZUEFQe4l5whm8LkGU4acSqv9B3xt\r\n' + - 'qROkCrsFrMPqjuuzEmyHoQZ64r2PLJg7FOuyhBnQUOt4\r\n' + - '-----END RSA PRIVATE KEY-----'; - var pk = forge.pki.privateKeyFromPem(_privateKey); - var pem1 = forge.pki.privateKeyToPem(pk); - var pem2 = forge.pki.encryptRsaPrivateKey( - pk, 'password', {'encAlg': 'aes128'}); - var privateKey = forge.pki.decryptRsaPrivateKey(pem2, 'password'); - var pem3 = forge.pki.privateKeyToPem(privateKey); - if(pem1 === pem3) - { - test.pass(); - } - else - { - test.fail(); - } - }); - - addTest('random', function(task, test) - { - forge.random.getBytes(16); - forge.random.getBytes(24); - forge.random.getBytes(32); - - var b = forge.random.getBytes(10); - test.result.html(forge.util.bytesToHex(b)); - if(b.length === 10) - { - test.pass(); - } - else - { - test.fail(); - } - }); - - addTest('asn.1 oid => der', function(task, test) - { - test.expect.html('2a864886f70d'); - test.result.html(forge.asn1.oidToDer('1.2.840.113549').toHex()); - test.check(); - }); - - addTest('asn.1 der => oid', function(task, test) - { - var der = '2a864886f70d'; - test.expect.html('1.2.840.113549'); - test.result.html(forge.asn1.derToOid(forge.util.hexToBytes(der))); - test.check(); - }); - - (function() - { - var _privateKey = - '-----BEGIN RSA PRIVATE KEY-----\r\n' + - 'MIICXQIBAAKBgQDL0EugUiNGMWscLAVM0VoMdhDZEJOqdsUMpx9U0YZI7szokJqQ\r\n' + - 'NIwokiQ6EonNnWSMlIvy46AhnlRYn+ezeTeU7eMGTkP3VF29vXBo+dLq5e+8VyAy\r\n' + - 'Q3FzM1wI4ts4hRACF8w6mqygXQ7i/SDu8/rXqRGtvnM+z0MYDdKo80efzwIDAQAB\r\n' + - 'AoGAIzkGONi5G+JifmXlLJdplom486p3upf4Ce2/7mqfaG9MnkyPSairKD/JXvfh\r\n' + - 'NNWkkN8DKKDKBcVVElPgORYT0qwrWc7ueLBMUCbRXb1ZyfEulimG0R3kjUh7NYau\r\n' + - 'DaIkVgfykXGSQMZx8FoaT6L080zd+0emKDDYRrb+/kgJNJECQQDoUZoiC2K/DWNY\r\n' + - 'h3/ppZ0ane2y4SBmJUHJVMPQ2CEgxsrJTxet668ckNCKaOP/3VFPoWC41f17DvKq\r\n' + - 'noYINNntAkEA4JbZBZBVUrQFhHlrpXT4jzqtO2RlKZzEq8qmFZfEErxOT1WMyyCi\r\n' + - 'lAQ5gUKardo1Kf0omC8Xq/uO9ZYdED55KwJBALs6cJ65UFaq4oLJiQPzLd7yokuE\r\n' + - 'dcj8g71PLBTW6jPxIiMFNA89nz3FU9wIVp+xbMNhSoMMKqIPVPC+m0Rn260CQQDA\r\n' + - 'I83fWK/mZWUjBM33a68KumRiH238v8XyQxj7+C8i6D8G2GXvkigFAehAkb7LZZd+\r\n' + - 'KLuGFyPlWv3fVWHf99KpAkBQFKk3MRMl6IGJZUEFQe4l5whm8LkGU4acSqv9B3xt\r\n' + - 'qROkCrsFrMPqjuuzEmyHoQZ64r2PLJg7FOuyhBnQUOt4\r\n' + - '-----END RSA PRIVATE KEY-----\r\n'; - - var _publicKey = - '-----BEGIN PUBLIC KEY-----\r\n' + - 'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDL0EugUiNGMWscLAVM0VoMdhDZ\r\n' + - 'EJOqdsUMpx9U0YZI7szokJqQNIwokiQ6EonNnWSMlIvy46AhnlRYn+ezeTeU7eMG\r\n' + - 'TkP3VF29vXBo+dLq5e+8VyAyQ3FzM1wI4ts4hRACF8w6mqygXQ7i/SDu8/rXqRGt\r\n' + - 'vnM+z0MYDdKo80efzwIDAQAB\r\n' + - '-----END PUBLIC KEY-----\r\n'; - - var _certificate = - '-----BEGIN CERTIFICATE-----\r\n' + - 'MIIDIjCCAougAwIBAgIJANE2aHSbwpaRMA0GCSqGSIb3DQEBBQUAMGoxCzAJBgNV\r\n' + - 'BAYTAlVTMREwDwYDVQQIEwhWaXJnaW5pYTETMBEGA1UEBxMKQmxhY2tzYnVyZzEN\r\n' + - 'MAsGA1UEChMEVGVzdDENMAsGA1UECxMEVGVzdDEVMBMGA1UEAxMMbXlzZXJ2ZXIu\r\n' + - 'Y29tMB4XDTEwMDYxOTE3MzYyOFoXDTExMDYxOTE3MzYyOFowajELMAkGA1UEBhMC\r\n' + - 'VVMxETAPBgNVBAgTCFZpcmdpbmlhMRMwEQYDVQQHEwpCbGFja3NidXJnMQ0wCwYD\r\n' + - 'VQQKEwRUZXN0MQ0wCwYDVQQLEwRUZXN0MRUwEwYDVQQDEwxteXNlcnZlci5jb20w\r\n' + - 'gZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMvQS6BSI0YxaxwsBUzRWgx2ENkQ\r\n' + - 'k6p2xQynH1TRhkjuzOiQmpA0jCiSJDoSic2dZIyUi/LjoCGeVFif57N5N5Tt4wZO\r\n' + - 'Q/dUXb29cGj50url77xXIDJDcXMzXAji2ziFEAIXzDqarKBdDuL9IO7z+tepEa2+\r\n' + - 'cz7PQxgN0qjzR5/PAgMBAAGjgc8wgcwwHQYDVR0OBBYEFPV1Y+DHXW6bA/r9sv1y\r\n' + - 'NJ8jAwMAMIGcBgNVHSMEgZQwgZGAFPV1Y+DHXW6bA/r9sv1yNJ8jAwMAoW6kbDBq\r\n' + - 'MQswCQYDVQQGEwJVUzERMA8GA1UECBMIVmlyZ2luaWExEzARBgNVBAcTCkJsYWNr\r\n' + - 'c2J1cmcxDTALBgNVBAoTBFRlc3QxDTALBgNVBAsTBFRlc3QxFTATBgNVBAMTDG15\r\n' + - 'c2VydmVyLmNvbYIJANE2aHSbwpaRMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEF\r\n' + - 'BQADgYEARdH2KOlJWTC1CS2y/PAvg4uiM31PXMC1hqSdJlnLM1MY4hRfuf9VyTeX\r\n' + - 'Y6FdybcyDLSxKn9id+g9229ci9/s9PI+QmD5vXd8yZyScLc2JkYB4GC6+9D1+/+x\r\n' + - 's2hzMxuK6kzZlP+0l9LGcraMQPGRydjCARZZm4Uegln9rh85XFQ=\r\n' + - '-----END CERTIFICATE-----\r\n'; - - var _signature = - '9200ece65cdaed36bcc20b94c65af852e4f88f0b4fe5b249d54665f815992ac4' + - '3a1399e65d938c6a7f16dd39d971a53ca66523209dbbfbcb67afa579dbb0c220' + - '672813d9e6f4818f29b9becbb29da2032c5e422da97e0c39bfb7a2e7d568615a' + - '5073af0337ff215a8e1b2332d668691f4fb731440055420c24ac451dd3c913f4'; - - addTest('private key from pem/to pem', function(task, test) - { - try - { - // convert from pem - var key = forge.pki.privateKeyFromPem(_privateKey); - //forge.log.debug(cat, 'privateKey', key); - - // convert back to pem - var pem = forge.pki.privateKeyToPem(key); - test.expect.html(_privateKey); - test.result.html(pem); - test.check(); - } - catch(ex) - { - forge.log.error('test', ex); - test.fail(); - } - }); - - addTest('public key from pem/to pem', function(task, test) - { - try - { - // convert from pem - var key = forge.pki.publicKeyFromPem(_publicKey); - //forge.log.debug(cat, 'publicKey', key); - - // convert back to pem - var pem = forge.pki.publicKeyToPem(key); - test.expect.html(_publicKey); - test.result.html(pem); - test.check(); - } - catch(ex) - { - forge.log.error('test', ex); - test.fail(); - } - }); - - addTest('certificate key from pem/to pem', function(task, test) - { - try - { - var cert = forge.pki.certificateFromPem(_certificate); - /* - forge.log.debug(cat, 'cert', cert); - forge.log.debug(cat, 'CN', cert.subject.getField('CN').value); - forge.log.debug(cat, 'C', - cert.subject.getField({shortName: 'C'}).value); - forge.log.debug(cat, 'stateOrProvinceName', - cert.subject.getField({name: 'stateOrProvinceName'}).value); - forge.log.debug(cat, '2.5.4.7', - cert.subject.getField({type: '2.5.4.7'}).value); - */ - // convert back to pem - var pem = forge.pki.certificateToPem(cert); - test.expect.html(_certificate); - test.result.html(pem); - test.check(); - } - catch(ex) - { - forge.log.error('test', ex); - test.fail(); - } - }); - - addTest('verify signature', function(task, test) - { - try - { - var key = forge.pki.publicKeyFromPem(_publicKey); - var md = forge.md.sha1.create(); - md.update('0123456789abcdef'); - var signature = forge.util.hexToBytes(_signature); - var success = key.verify(md.digest().getBytes(), signature); - if(success) - { - test.pass(); - } - else - { - test.fail(); - } - } - catch(ex) - { - forge.log.error('test', ex); - test.fail(); - } - }); - - addTest('sign and verify', function(task, test) - { - try - { - var privateKey = forge.pki.privateKeyFromPem(_privateKey); - var publicKey = forge.pki.publicKeyFromPem(_publicKey); - - // do sign - var md = forge.md.sha1.create(); - md.update('0123456789abcdef'); - var st = +new Date(); - var signature = privateKey.sign(md); - var et = +new Date(); - //forge.log.debug(cat, 'sign time', (et - st) + 'ms'); - - // do verify - st = +new Date(); - var success = publicKey.verify(md.digest().getBytes(), signature); - et = +new Date(); - //forge.log.debug(cat, 'verify time', (et - st) + 'ms'); - if(success) - { - test.pass(); - } - else - { - test.fail(); - } - } - catch(ex) - { - forge.log.error('test', ex); - test.fail(); - } - }); - - addTest('certificate verify', function(task, test) - { - try - { - var cert = forge.pki.certificateFromPem(_certificate, true); - //forge.log.debug(cat, 'cert', cert); - var success = cert.verify(cert); - if(success) - { - test.pass(); - } - else - { - test.fail(); - } - } - catch(ex) - { - forge.log.error('test', ex); - test.fail(); - } - }); - })(); - - addTest('TLS prf', function(task, test) - { - // Note: This test vector is originally from: - // http://www.imc.org/ietf-tls/mail-archive/msg01589.html - // But that link is now dead. - var secret = forge.util.createBuffer(); - for(var i = 0; i < 48; ++i) - { - secret.putByte(0xAB); - } - secret = secret.getBytes(); - var seed = forge.util.createBuffer(); - for(var i = 0; i < 64; ++i) - { - seed.putByte(0xCD); - } - seed = seed.getBytes(); - - var bytes = forge.tls.prf_tls1(secret, 'PRF Testvector', seed, 104); - var expect = - 'd3d4d1e349b5d515044666d51de32bab258cb521' + - 'b6b053463e354832fd976754443bcf9a296519bc' + - '289abcbc1187e4ebd31e602353776c408aafb74c' + - 'bc85eff69255f9788faa184cbb957a9819d84a5d' + - '7eb006eb459d3ae8de9810454b8b2d8f1afbc655' + - 'a8c9a013'; - test.expect.html(expect); - test.result.html(bytes.toHex()); - test.check(); - }); - - // function to create certificate - var createCert = function(keys, cn, data) - { - var cert = forge.pki.createCertificate(); - cert.serialNumber = '01'; - cert.validity.notBefore = new Date(); - cert.validity.notAfter = new Date(); - cert.validity.notAfter.setFullYear( - cert.validity.notBefore.getFullYear() + 1); - var attrs = [{ - name: 'commonName', - value: cn - }, { - name: 'countryName', - value: 'US' - }, { - shortName: 'ST', - value: 'Virginia' - }, { - name: 'localityName', - value: 'Blacksburg' - }, { - name: 'organizationName', - value: 'Test' - }, { - shortName: 'OU', - value: 'Test' - }]; - cert.setSubject(attrs); - cert.setIssuer(attrs); - cert.setExtensions([{ - name: 'basicConstraints', - cA: true - }, { - name: 'keyUsage', - keyCertSign: true, - digitalSignature: true, - nonRepudiation: true, - keyEncipherment: true, - dataEncipherment: true - }, { - name: 'subjectAltName', - altNames: [{ - type: 6, // URI - value: 'http://myuri.com/webid#me' - }] - }]); - // FIXME: add subjectKeyIdentifier extension - // FIXME: add authorityKeyIdentifier extension - cert.publicKey = keys.publicKey; - - // self-sign certificate - cert.sign(keys.privateKey); - - // save data - data[cn] = { - cert: forge.pki.certificateToPem(cert), - privateKey: forge.pki.privateKeyToPem(keys.privateKey) - }; - }; - - var generateCert = function(task, test, cn, data) - { - task.block(); - - // create key-generation state and function to step algorithm - test.result.html( - 'Generating 512-bit key-pair and certificate for \"' + cn + '\".'); - var state = forge.pki.rsa.createKeyPairGenerationState(512); - var kgTime = +new Date(); - var step = function() - { - // step key-generation - if(!forge.pki.rsa.stepKeyPairGenerationState(state, 1000)) - { - test.result.html(test.result.html() + '.'); - setTimeout(step, 1); - } - // key-generation complete - else - { - kgTime = +new Date() - kgTime; - forge.log.debug(cat, 'Total key-gen time', kgTime + 'ms'); - try - { - createCert(state.keys, cn, data); - test.result.html( - test.result.html() + 'done. Time=' + kgTime + 'ms. '); - task.unblock(); - } - catch(ex) - { - forge.log.error(cat, ex, ex.message ? ex.message : ''); - test.result.html(ex.message); - test.fail(); - task.fail(); - } - } - }; - - // run key-gen algorithm - setTimeout(step, 0); - }; - - var clientSessionCache1 = forge.tls.createSessionCache(); - var serverSessionCache1 = forge.tls.createSessionCache(); - addTest('TLS connection, w/o client-certificate', function(task, test) - { - var data = {}; - - task.next('generate server certifcate', function(task) - { - generateCert(task, test, 'server', data); - }); - - task.next('starttls', function(task) - { - test.result.html(test.result.html() + 'Starting TLS...'); - - var end = - { - client: null, - server: null - }; - var success = false; - - // create client - end.client = forge.tls.createConnection( - { - server: false, - caStore: [data.server.cert], - sessionCache: clientSessionCache1, - // optional cipher suites in order of preference - cipherSuites: [ - forge.tls.CipherSuites.TLS_RSA_WITH_AES_128_CBC_SHA, - forge.tls.CipherSuites.TLS_RSA_WITH_AES_256_CBC_SHA], - virtualHost: 'server', - verify: function(c, verified, depth, certs) - { - test.result.html(test.result.html() + - 'Client verifying certificate w/CN: \"' + - certs[0].subject.getField('CN').value + - '\", verified: ' + verified + '...'); - if(verified !== true) - { - test.fail(); - task.fail(); - } - return verified; - }, - connected: function(c) - { - test.result.html(test.result.html() + 'Client connected...'); - - // send message to server - setTimeout(function() - { - c.prepare('Hello Server'); - }, 1); - }, - tlsDataReady: function(c) - { - // send TLS data to server - end.server.process(c.tlsData.getBytes()); - }, - dataReady: function(c) - { - var response = c.data.getBytes(); - test.result.html(test.result.html() + - 'Client received \"' + response + '\"'); - success = (response === 'Hello Client'); - c.close(); - }, - closed: function(c) - { - test.result.html(test.result.html() + 'Client disconnected.'); - test.result.html(success ? 'Success' : 'Failure'); - if(success) - { - test.expect.html('Success'); - task.unblock(); - test.pass(); - } - else - { - console.log('closed fail'); - test.fail(); - task.fail(); - } - }, - error: function(c, error) - { - test.result.html(test.result.html() + 'Error: ' + error.message); - test.fail(); - task.fail(); - } - }); - - // create server - end.server = forge.tls.createConnection( - { - server: true, - sessionCache: serverSessionCache1, - // optional cipher suites in order of preference - cipherSuites: [ - forge.tls.CipherSuites.TLS_RSA_WITH_AES_128_CBC_SHA, - forge.tls.CipherSuites.TLS_RSA_WITH_AES_256_CBC_SHA], - connected: function(c) - { - test.result.html(test.result.html() + 'Server connected...'); - }, - getCertificate: function(c, hint) - { - test.result.html(test.result.html() + - 'Server getting certificate for \"' + hint[0] + '\"...'); - return data.server.cert; - }, - getPrivateKey: function(c, cert) - { - return data.server.privateKey; - }, - tlsDataReady: function(c) - { - // send TLS data to client - end.client.process(c.tlsData.getBytes()); - }, - dataReady: function(c) - { - test.result.html(test.result.html() + - 'Server received \"' + c.data.getBytes() + '\"'); - - // send response - c.prepare('Hello Client'); - c.close(); - }, - closed: function(c) - { - test.result.html(test.result.html() + 'Server disconnected.'); - }, - error: function(c, error) - { - test.result.html(test.result.html() + 'Error: ' + error.message); - test.fail(); - task.fail(); - } - }); - - // start handshake - task.block(); - end.client.handshake(); - }); - }); - - var clientSessionCache2 = forge.tls.createSessionCache(); - var serverSessionCache2 = forge.tls.createSessionCache(); - addTest('TLS connection, w/optional client-certificate', function(task, test) - { - var data = {}; - - task.next('generate server certifcate', function(task) - { - generateCert(task, test, 'server', data); - }); - - // client-cert generated but not sent in this test - task.next('generate client certifcate', function(task) - { - generateCert(task, test, 'client', data); - }); - - task.next('starttls', function(task) - { - test.result.html(test.result.html() + 'Starting TLS...'); - - var end = - { - client: null, - server: null - }; - var success = false; - - // create client - end.client = forge.tls.createConnection( - { - server: false, - caStore: [data.server.cert], - sessionCache: clientSessionCache2, - // supported cipher suites in order of preference - cipherSuites: [ - forge.tls.CipherSuites.TLS_RSA_WITH_AES_128_CBC_SHA, - forge.tls.CipherSuites.TLS_RSA_WITH_AES_256_CBC_SHA], - virtualHost: 'server', - verify: function(c, verified, depth, certs) - { - test.result.html(test.result.html() + - 'Client verifying certificate w/CN: \"' + - certs[0].subject.getField('CN').value + - '\", verified: ' + verified + '...'); - if(verified !== true) - { - test.fail(); - task.fail(); - } - return verified; - }, - connected: function(c) - { - test.result.html(test.result.html() + 'Client connected...'); - - // send message to server - setTimeout(function() - { - c.prepare('Hello Server'); - }, 1); - }, - tlsDataReady: function(c) - { - // send TLS data to server - end.server.process(c.tlsData.getBytes()); - }, - dataReady: function(c) - { - var response = c.data.getBytes(); - test.result.html(test.result.html() + - 'Client received \"' + response + '\"'); - success = (response === 'Hello Client'); - c.close(); - }, - closed: function(c) - { - test.result.html(test.result.html() + 'Client disconnected.'); - test.result.html(success ? 'Success' : 'Failure'); - if(success) - { - test.expect.html('Success'); - task.unblock(); - test.pass(); - } - else - { - console.log('closed fail'); - test.fail(); - task.fail(); - } - }, - error: function(c, error) - { - test.result.html(test.result.html() + 'Error: ' + error.message); - test.fail(); - task.fail(); - } - }); - - // create server - end.server = forge.tls.createConnection( - { - server: true, - caStore: [data.client.cert], - sessionCache: serverSessionCache2, - // supported cipher suites in order of preference - cipherSuites: [ - forge.tls.CipherSuites.TLS_RSA_WITH_AES_128_CBC_SHA, - forge.tls.CipherSuites.TLS_RSA_WITH_AES_256_CBC_SHA], - connected: function(c) - { - test.result.html(test.result.html() + 'Server connected...'); - }, - verifyClient: 'optional', - verify: function(c, verified, depth, certs) - { - test.result.html(test.result.html() + - 'Server verifying certificate w/CN: \"' + - certs[0].subject.getField('CN').value + - '\", verified: ' + verified + '...'); - if(verified !== true) - { - test.fail(); - task.fail(); - } - return verified; - }, - getCertificate: function(c, hint) - { - test.result.html(test.result.html() + - 'Server getting certificate for \"' + hint[0] + '\"...'); - return data.server.cert; - }, - getPrivateKey: function(c, cert) - { - return data.server.privateKey; - }, - tlsDataReady: function(c) - { - // send TLS data to client - end.client.process(c.tlsData.getBytes()); - }, - dataReady: function(c) - { - test.result.html(test.result.html() + - 'Server received \"' + c.data.getBytes() + '\"'); - - // send response - c.prepare('Hello Client'); - c.close(); - }, - closed: function(c) - { - test.result.html(test.result.html() + 'Server disconnected.'); - }, - error: function(c, error) - { - test.result.html(test.result.html() + 'Error: ' + error.message); - test.fail(); - task.fail(); - } - }); - - // start handshake - task.block(); - end.client.handshake(); - }); - }); - - var clientSessionCache3 = forge.tls.createSessionCache(); - var serverSessionCache3 = forge.tls.createSessionCache(); - addTest('TLS connection, w/client-certificate', function(task, test) - { - var data = {}; - - task.next('generate server certifcate', function(task) - { - generateCert(task, test, 'server', data); - }); - - task.next('generate client certifcate', function(task) - { - generateCert(task, test, 'client', data); - }); - - task.next('starttls', function(task) - { - test.result.html(test.result.html() + 'Starting TLS...'); - - var end = - { - client: null, - server: null - }; - var success = false; - - // create client - end.client = forge.tls.createConnection( - { - server: false, - caStore: [data.server.cert], - sessionCache: clientSessionCache3, - // supported cipher suites in order of preference - cipherSuites: [ - forge.tls.CipherSuites.TLS_RSA_WITH_AES_128_CBC_SHA, - forge.tls.CipherSuites.TLS_RSA_WITH_AES_256_CBC_SHA], - virtualHost: 'server', - verify: function(c, verified, depth, certs) - { - test.result.html(test.result.html() + - 'Client verifying certificate w/CN: \"' + - certs[0].subject.getField('CN').value + - '\", verified: ' + verified + '...'); - if(verified !== true) - { - test.fail(); - task.fail(); - } - return verified; - }, - connected: function(c) - { - test.result.html(test.result.html() + 'Client connected...'); - - // send message to server - setTimeout(function() - { - c.prepare('Hello Server'); - }, 1); - }, - getCertificate: function(c, hint) - { - test.result.html(test.result.html() + - 'Client getting certificate ...'); - return data.client.cert; - }, - getPrivateKey: function(c, cert) - { - return data.client.privateKey; - }, - tlsDataReady: function(c) - { - // send TLS data to server - end.server.process(c.tlsData.getBytes()); - }, - dataReady: function(c) - { - var response = c.data.getBytes(); - test.result.html(test.result.html() + - 'Client received \"' + response + '\"'); - success = (response === 'Hello Client'); - c.close(); - }, - closed: function(c) - { - test.result.html(test.result.html() + 'Client disconnected.'); - test.result.html(success ? 'Success' : 'Failure'); - if(success) - { - test.expect.html('Success'); - task.unblock(); - test.pass(); - } - else - { - console.log('closed fail'); - test.fail(); - task.fail(); - } - }, - error: function(c, error) - { - test.result.html(test.result.html() + 'Error: ' + error.message); - test.fail(); - task.fail(); - } - }); - - // create server - end.server = forge.tls.createConnection( - { - server: true, - caStore: [data.client.cert], - sessionCache: serverSessionCache3, - // supported cipher suites in order of preference - cipherSuites: [ - forge.tls.CipherSuites.TLS_RSA_WITH_AES_128_CBC_SHA, - forge.tls.CipherSuites.TLS_RSA_WITH_AES_256_CBC_SHA], - connected: function(c) - { - test.result.html(test.result.html() + 'Server connected...'); - }, - verifyClient: true, // use 'optional' to request but not require - verify: function(c, verified, depth, certs) - { - test.result.html(test.result.html() + - 'Server verifying certificate w/CN: \"' + - certs[0].subject.getField('CN').value + - '\", verified: ' + verified + '...'); - if(verified !== true) - { - test.fail(); - task.fail(); - } - return verified; - }, - getCertificate: function(c, hint) - { - test.result.html(test.result.html() + - 'Server getting certificate for \"' + hint[0] + '\"...'); - return data.server.cert; - }, - getPrivateKey: function(c, cert) - { - return data.server.privateKey; - }, - tlsDataReady: function(c) - { - // send TLS data to client - end.client.process(c.tlsData.getBytes()); - }, - dataReady: function(c) - { - test.result.html(test.result.html() + - 'Server received \"' + c.data.getBytes() + '\"'); - - // send response - c.prepare('Hello Client'); - c.close(); - }, - closed: function(c) - { - test.result.html(test.result.html() + 'Server disconnected.'); - }, - error: function(c, error) - { - test.result.html(test.result.html() + 'Error: ' + error.message); - test.fail(); - task.fail(); - } - }); - - // start handshake - task.block(); - end.client.handshake(); - }); - }); - - init(); -}); diff --git a/alarm/node_modules/node-forge/tests/favicon.ico b/alarm/node_modules/node-forge/tests/favicon.ico deleted file mode 100644 index e69de29..0000000 --- a/alarm/node_modules/node-forge/tests/favicon.ico +++ /dev/null diff --git a/alarm/node_modules/node-forge/tests/flash/Test.as b/alarm/node_modules/node-forge/tests/flash/Test.as deleted file mode 100644 index 7c03727..0000000 --- a/alarm/node_modules/node-forge/tests/flash/Test.as +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright (c) 2010 Digital Bazaar, Inc. All rights reserved. - * - * @author Dave Longley - */ -package -{ - import flash.display.Sprite; - - public class Test extends Sprite - { - import flash.events.*; - import flash.net.*; - - import flash.external.ExternalInterface; - import flash.system.Security; - - public function Test() - { - try - { - // FIXME: replace 'localhost' with cross-domain host to hit - var xhost:String = "localhost"; - Security.loadPolicyFile("xmlsocket://" + xhost + ":80"); - - var loader:URLLoader = new URLLoader(); - loader.addEventListener( - Event.COMPLETE, completeHandler); - loader.addEventListener( - Event.OPEN, openHandler); - loader.addEventListener( - ProgressEvent.PROGRESS, progressHandler); - loader.addEventListener( - SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler); - loader.addEventListener( - HTTPStatusEvent.HTTP_STATUS, httpStatusHandler); - loader.addEventListener( - IOErrorEvent.IO_ERROR, ioErrorHandler); - - var request:URLRequest = new URLRequest( - "http://" + xhost + "/index.html"); - loader.load(request); - } - catch(e:Error) - { - log("error=" + e.errorID + "," + e.name + "," + e.message); - throw e; - } - } - - private function log(obj:Object):void - { - if(obj is String) - { - var str:String = obj as String; - ExternalInterface.call("console.log", "Test", str); - } - else if(obj is Error) - { - var e:Error = obj as Error; - log("error=" + e.errorID + "," + e.name + "," + e.message); - } - } - - private function completeHandler(event:Event):void - { - var loader:URLLoader = URLLoader(event.target); - log("complete: " + loader.data); - } - - private function openHandler(event:Event):void - { - log("open: " + event); - } - - private function progressHandler(event:ProgressEvent):void - { - log("progress:" + event.bytesLoaded + " total: " + event.bytesTotal); - } - - private function securityErrorHandler(event:SecurityErrorEvent):void - { - log("securityError: " + event); - } - - private function httpStatusHandler(event:HTTPStatusEvent):void - { - log("httpStatus: " + event); - } - - private function ioErrorHandler(event:IOErrorEvent):void - { - log("ioError: " + event); - } - } -} diff --git a/alarm/node_modules/node-forge/tests/flash/build-flash.xml b/alarm/node_modules/node-forge/tests/flash/build-flash.xml deleted file mode 100644 index f037c58..0000000 --- a/alarm/node_modules/node-forge/tests/flash/build-flash.xml +++ /dev/null @@ -1,7 +0,0 @@ -<flex-config> - <compiler> - <source-path> - <path-element>.</path-element> - </source-path> - </compiler> -</flex-config> diff --git a/alarm/node_modules/node-forge/tests/flash/index.html b/alarm/node_modules/node-forge/tests/flash/index.html deleted file mode 100644 index 26a10b8..0000000 --- a/alarm/node_modules/node-forge/tests/flash/index.html +++ /dev/null @@ -1,27 +0,0 @@ -<html> - <head> - <link type="text/css" rel="stylesheet" media="all" href="screen.css" /> - <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js"></script> - - <script type="text/javascript"> - //<![CDATA[ - swfobject.embedSWF( - 'Test.swf', 'test', '0', '0', '9.0.0', - false, {}, {allowscriptaccess: 'always'}, {}); - //]]> - </script> - </head> - <body> - <div class="header"> - <h1>Flash Cross-Domain URLLoader Test</h1> - </div> - - <div class="content"> - - <div id="test"> - <p>Could not load the flash test.</p> - </div> - - </div> - </body> -</html> diff --git a/alarm/node_modules/node-forge/tests/forge_ssl/forge/__init__.py b/alarm/node_modules/node-forge/tests/forge_ssl/forge/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/alarm/node_modules/node-forge/tests/forge_ssl/forge/__init__.py +++ /dev/null diff --git a/alarm/node_modules/node-forge/tests/forge_ssl/forge/_ssl.c b/alarm/node_modules/node-forge/tests/forge_ssl/forge/_ssl.c deleted file mode 100644 index bdef8c9..0000000 --- a/alarm/node_modules/node-forge/tests/forge_ssl/forge/_ssl.c +++ /dev/null @@ -1,1770 +0,0 @@ -/* SSL socket module - - SSL support based on patches by Brian E Gallew and Laszlo Kovacs. - Re-worked a bit by Bill Janssen to add server-side support and - certificate decoding. Chris Stawarz contributed some non-blocking - patches. - - This module is imported by ssl.py. It should *not* be used - directly. - - XXX should partial writes be enabled, SSL_MODE_ENABLE_PARTIAL_WRITE? - - XXX integrate several "shutdown modes" as suggested in - http://bugs.python.org/issue8108#msg102867 ? -*/ - -#include "Python.h" - -#ifdef WITH_THREAD -#include "pythread.h" -#define PySSL_BEGIN_ALLOW_THREADS { \ - PyThreadState *_save = NULL; \ - if (_ssl_locks_count>0) {_save = PyEval_SaveThread();} -#define PySSL_BLOCK_THREADS if (_ssl_locks_count>0){PyEval_RestoreThread(_save)}; -#define PySSL_UNBLOCK_THREADS if (_ssl_locks_count>0){_save = PyEval_SaveThread()}; -#define PySSL_END_ALLOW_THREADS if (_ssl_locks_count>0){PyEval_RestoreThread(_save);} \ - } - -#else /* no WITH_THREAD */ - -#define PySSL_BEGIN_ALLOW_THREADS -#define PySSL_BLOCK_THREADS -#define PySSL_UNBLOCK_THREADS -#define PySSL_END_ALLOW_THREADS - -#endif - -enum py_ssl_error { - /* these mirror ssl.h */ - PY_SSL_ERROR_NONE, - PY_SSL_ERROR_SSL, - PY_SSL_ERROR_WANT_READ, - PY_SSL_ERROR_WANT_WRITE, - PY_SSL_ERROR_WANT_X509_LOOKUP, - PY_SSL_ERROR_SYSCALL, /* look at error stack/return value/errno */ - PY_SSL_ERROR_ZERO_RETURN, - PY_SSL_ERROR_WANT_CONNECT, - /* start of non ssl.h errorcodes */ - PY_SSL_ERROR_EOF, /* special case of SSL_ERROR_SYSCALL */ - PY_SSL_ERROR_INVALID_ERROR_CODE -}; - -enum py_ssl_server_or_client { - PY_SSL_CLIENT, - PY_SSL_SERVER -}; - -enum py_ssl_cert_requirements { - PY_SSL_CERT_NONE, - PY_SSL_CERT_OPTIONAL, - PY_SSL_CERT_REQUIRED -}; - -enum py_ssl_version { - PY_SSL_VERSION_SSL2, - PY_SSL_VERSION_SSL3, - PY_SSL_VERSION_SSL23, - PY_SSL_VERSION_TLS1 -}; - -enum py_ssl_sess_cache_mode { - PY_SSL_SESS_CACHE_OFF, - PY_SSL_SESS_CACHE_CLIENT, - PY_SSL_SESS_CACHE_SERVER, - PY_SSL_SESS_CACHE_BOTH -}; - -/* Include symbols from _socket module */ -#include "socketmodule.h" - -#if defined(HAVE_POLL_H) -#include <poll.h> -#elif defined(HAVE_SYS_POLL_H) -#include <sys/poll.h> -#endif - -/* Include OpenSSL header files */ -#include "openssl/rsa.h" -#include "openssl/crypto.h" -#include "openssl/x509.h" -#include "openssl/x509v3.h" -#include "openssl/pem.h" -#include "openssl/ssl.h" -#include "openssl/err.h" -#include "openssl/rand.h" - -/* SSL error object */ -static PyObject *PySSLErrorObject; - -#ifdef WITH_THREAD - -/* serves as a flag to see whether we've initialized the SSL thread support. */ -/* 0 means no, greater than 0 means yes */ - -static unsigned int _ssl_locks_count = 0; - -#endif /* def WITH_THREAD */ - -/* SSL socket object */ - -#define X509_NAME_MAXLEN 256 - -/* RAND_* APIs got added to OpenSSL in 0.9.5 */ -#if OPENSSL_VERSION_NUMBER >= 0x0090500fL -# define HAVE_OPENSSL_RAND 1 -#else -# undef HAVE_OPENSSL_RAND -#endif - -typedef struct { - PyObject_HEAD - PySocketSockObject *Socket; /* Socket on which we're layered */ - int inherited; - SSL_CTX* ctx; - SSL* ssl; - X509* peer_cert; - char server[X509_NAME_MAXLEN]; - char issuer[X509_NAME_MAXLEN]; - int shutdown_seen_zero; - -} PySSLObject; - -static PyTypeObject PySSL_Type; -static PyObject *PySSL_SSLwrite(PySSLObject *self, PyObject *args); -static PyObject *PySSL_SSLread(PySSLObject *self, PyObject *args); -static int check_socket_and_wait_for_timeout(PySocketSockObject *s, - int writing); -static PyObject *PySSL_peercert(PySSLObject *self, PyObject *args); -static PyObject *PySSL_cipher(PySSLObject *self); - -#define PySSLObject_Check(v) (Py_TYPE(v) == &PySSL_Type) - -typedef enum { - SOCKET_IS_NONBLOCKING, - SOCKET_IS_BLOCKING, - SOCKET_HAS_TIMED_OUT, - SOCKET_HAS_BEEN_CLOSED, - SOCKET_TOO_LARGE_FOR_SELECT, - SOCKET_OPERATION_OK -} timeout_state; - -/* Wrap error strings with filename and line # */ -#define STRINGIFY1(x) #x -#define STRINGIFY2(x) STRINGIFY1(x) -#define ERRSTR1(x,y,z) (x ":" y ": " z) -#define ERRSTR(x) ERRSTR1("_ssl.c", STRINGIFY2(__LINE__), x) - -/* XXX It might be helpful to augment the error message generated - below with the name of the SSL function that generated the error. - I expect it's obvious most of the time. -*/ - -static PyObject * -PySSL_SetError(PySSLObject *obj, int ret, char *filename, int lineno) -{ - PyObject *v; - char buf[2048]; - char *errstr; - int err; - enum py_ssl_error p = PY_SSL_ERROR_NONE; - - assert(ret <= 0); - - if (obj->ssl != NULL) { - err = SSL_get_error(obj->ssl, ret); - - switch (err) { - case SSL_ERROR_ZERO_RETURN: - errstr = "TLS/SSL connection has been closed"; - p = PY_SSL_ERROR_ZERO_RETURN; - break; - case SSL_ERROR_WANT_READ: - errstr = "The operation did not complete (read)"; - p = PY_SSL_ERROR_WANT_READ; - break; - case SSL_ERROR_WANT_WRITE: - p = PY_SSL_ERROR_WANT_WRITE; - errstr = "The operation did not complete (write)"; - break; - case SSL_ERROR_WANT_X509_LOOKUP: - p = PY_SSL_ERROR_WANT_X509_LOOKUP; - errstr = "The operation did not complete (X509 lookup)"; - break; - case SSL_ERROR_WANT_CONNECT: - p = PY_SSL_ERROR_WANT_CONNECT; - errstr = "The operation did not complete (connect)"; - break; - case SSL_ERROR_SYSCALL: - { - unsigned long e = ERR_get_error(); - if (e == 0) { - if (ret == 0 || !obj->Socket) { - p = PY_SSL_ERROR_EOF; - errstr = "EOF occurred in violation of protocol"; - } else if (ret == -1) { - /* underlying BIO reported an I/O error */ - ERR_clear_error(); - return obj->Socket->errorhandler(); - } else { /* possible? */ - p = PY_SSL_ERROR_SYSCALL; - errstr = "Some I/O error occurred"; - } - } else { - p = PY_SSL_ERROR_SYSCALL; - /* XXX Protected by global interpreter lock */ - errstr = ERR_error_string(e, NULL); - } - break; - } - case SSL_ERROR_SSL: - { - unsigned long e = ERR_get_error(); - p = PY_SSL_ERROR_SSL; - if (e != 0) - /* XXX Protected by global interpreter lock */ - errstr = ERR_error_string(e, NULL); - else { /* possible? */ - errstr = "A failure in the SSL library occurred"; - } - break; - } - default: - p = PY_SSL_ERROR_INVALID_ERROR_CODE; - errstr = "Invalid error code"; - } - } else { - errstr = ERR_error_string(ERR_peek_last_error(), NULL); - } - PyOS_snprintf(buf, sizeof(buf), "_ssl.c:%d: %s", lineno, errstr); - ERR_clear_error(); - v = Py_BuildValue("(is)", p, buf); - if (v != NULL) { - PyErr_SetObject(PySSLErrorObject, v); - Py_DECREF(v); - } - return NULL; -} - -static PyObject * -_setSSLError (char *errstr, int errcode, char *filename, int lineno) { - - char buf[2048]; - PyObject *v; - - if (errstr == NULL) { - errcode = ERR_peek_last_error(); - errstr = ERR_error_string(errcode, NULL); - } - PyOS_snprintf(buf, sizeof(buf), "_ssl.c:%d: %s", lineno, errstr); - ERR_clear_error(); - v = Py_BuildValue("(is)", errcode, buf); - if (v != NULL) { - PyErr_SetObject(PySSLErrorObject, v); - Py_DECREF(v); - } - return NULL; -} - -static PySSLObject * -newPySSLObject(PySSLObject *ssl_object, PySocketSockObject *Sock, - char *key_file, char *cert_file, - enum py_ssl_server_or_client socket_type, - enum py_ssl_cert_requirements certreq, - enum py_ssl_version proto_version, - enum py_ssl_sess_cache_mode cache_mode, - char *sess_id_ctx, - char *cacerts_file) -{ - PySSLObject *self; - char *errstr = NULL; - int ret; - int verification_mode; - int sess_cache_mode; - - self = PyObject_New(PySSLObject, &PySSL_Type); /* Create new object */ - if (self == NULL) - return NULL; - memset(self->server, '\0', sizeof(char) * X509_NAME_MAXLEN); - memset(self->issuer, '\0', sizeof(char) * X509_NAME_MAXLEN); - self->peer_cert = NULL; - self->inherited = 0; - self->ssl = NULL; - self->ctx = NULL; - self->Socket = NULL; - - /* Make sure the SSL error state is initialized */ - (void) ERR_get_state(); - ERR_clear_error(); - - if ((key_file && !cert_file) || (!key_file && cert_file)) { - errstr = ERRSTR("Both the key & certificate files " - "must be specified"); - goto fail; - } - - if ((socket_type == PY_SSL_SERVER) && (ssl_object == NULL) && - ((key_file == NULL) || (cert_file == NULL))) { - errstr = ERRSTR("Both the key & certificate files " - "must be specified for server-side operation"); - goto fail; - } - - if (ssl_object != NULL) { - self->inherited = 1; - self->ctx = ssl_object->ctx; - } else { - self->inherited = 0; - - PySSL_BEGIN_ALLOW_THREADS - if (proto_version == PY_SSL_VERSION_TLS1) - self->ctx = SSL_CTX_new(TLSv1_method()); /* Set up context */ - else if (proto_version == PY_SSL_VERSION_SSL3) - self->ctx = SSL_CTX_new(SSLv3_method()); /* Set up context */ - else if (proto_version == PY_SSL_VERSION_SSL2) - self->ctx = SSL_CTX_new(SSLv2_method()); /* Set up context */ - else if (proto_version == PY_SSL_VERSION_SSL23) - self->ctx = SSL_CTX_new(SSLv23_method()); /* Set up context */ - PySSL_END_ALLOW_THREADS - } - - if (self->ctx == NULL) { - errstr = ERRSTR("Invalid SSL protocol variant specified."); - goto fail; - } - - if (self->inherited == 0 && certreq != PY_SSL_CERT_NONE) { - if (cacerts_file == NULL) { - errstr = ERRSTR("No root certificates specified for " - "verification of other-side certificates."); - goto fail; - } else { - PySSL_BEGIN_ALLOW_THREADS - ret = SSL_CTX_load_verify_locations(self->ctx, - cacerts_file, - NULL); - PySSL_END_ALLOW_THREADS - if (ret != 1) { - _setSSLError(NULL, 0, __FILE__, __LINE__); - goto fail; - } - } - } - if (self->inherited == 0 && key_file) { - PySSL_BEGIN_ALLOW_THREADS - ret = SSL_CTX_use_PrivateKey_file(self->ctx, key_file, - SSL_FILETYPE_PEM); - PySSL_END_ALLOW_THREADS - if (ret != 1) { - _setSSLError(NULL, ret, __FILE__, __LINE__); - goto fail; - } - - PySSL_BEGIN_ALLOW_THREADS - ret = SSL_CTX_use_certificate_chain_file(self->ctx, - cert_file); - PySSL_END_ALLOW_THREADS - if (ret != 1) { - /* - fprintf(stderr, "ret is %d, errcode is %lu, %lu, with file \"%s\"\n", - ret, ERR_peek_error(), ERR_peek_last_error(), cert_file); - */ - if (ERR_peek_last_error() != 0) { - _setSSLError(NULL, ret, __FILE__, __LINE__); - goto fail; - } - } - } - - if (self->inherited == 0) { - /* ssl compatibility */ - SSL_CTX_set_options(self->ctx, SSL_OP_ALL); - - /* session cache mode */ - PySSL_BEGIN_ALLOW_THREADS - sess_cache_mode = SSL_SESS_CACHE_SERVER; - if (cache_mode == PY_SSL_SESS_CACHE_OFF) - sess_cache_mode = SSL_SESS_CACHE_OFF; - else if (cache_mode == PY_SSL_SESS_CACHE_CLIENT) - sess_cache_mode = SSL_SESS_CACHE_CLIENT; - else if (cache_mode == PY_SSL_SESS_CACHE_SERVER) - sess_cache_mode = SSL_SESS_CACHE_SERVER; - else if (cache_mode == PY_SSL_SESS_CACHE_BOTH) - sess_cache_mode = SSL_SESS_CACHE_BOTH; - SSL_CTX_set_session_cache_mode(self->ctx, sess_cache_mode); - - /* session id context */ - if (sess_id_ctx != NULL) - SSL_CTX_set_session_id_context(self->ctx, - (const unsigned char*)sess_id_ctx, - strlen(sess_id_ctx)); - PySSL_END_ALLOW_THREADS - - verification_mode = SSL_VERIFY_NONE; - if (certreq == PY_SSL_CERT_OPTIONAL) - verification_mode = SSL_VERIFY_PEER; - else if (certreq == PY_SSL_CERT_REQUIRED) - verification_mode = (SSL_VERIFY_PEER | - SSL_VERIFY_FAIL_IF_NO_PEER_CERT); - SSL_CTX_set_verify(self->ctx, verification_mode, - NULL); /* set verify lvl */ - } - - self->ssl = SSL_new(self->ctx); /* New ssl struct */ - SSL_set_fd(self->ssl, Sock->sock_fd); /* Set the socket for SSL */ -#ifdef SSL_MODE_AUTO_RETRY - SSL_set_mode(self->ssl, SSL_MODE_AUTO_RETRY); -#endif - - /* If the socket is in non-blocking mode or timeout mode, set the BIO - * to non-blocking mode (blocking is the default) - */ - if (Sock->sock_timeout >= 0.0) { - /* Set both the read and write BIO's to non-blocking mode */ - BIO_set_nbio(SSL_get_rbio(self->ssl), 1); - BIO_set_nbio(SSL_get_wbio(self->ssl), 1); - } - - PySSL_BEGIN_ALLOW_THREADS - if (socket_type == PY_SSL_CLIENT) - SSL_set_connect_state(self->ssl); - else - SSL_set_accept_state(self->ssl); - PySSL_END_ALLOW_THREADS - - self->Socket = Sock; - Py_INCREF(self->Socket); - return self; - fail: - if (errstr) - PyErr_SetString(PySSLErrorObject, errstr); - Py_DECREF(self); - return NULL; -} - -static PyObject * -PySSL_sslwrap(PyObject *self, PyObject *args) -{ - PySocketSockObject *Sock; - int server_side = 0; - int verification_mode = PY_SSL_CERT_NONE; - int protocol = PY_SSL_VERSION_SSL23; - int sess_cache_mode = PY_SSL_SESS_CACHE_SERVER; - char *sess_id_ctx = NULL; - char *key_file = NULL; - char *cert_file = NULL; - char *cacerts_file = NULL; - - if (!PyArg_ParseTuple(args, "O!i|zziiizz:sslwrap", - PySocketModule.Sock_Type, - &Sock, - &server_side, - &key_file, &cert_file, - &verification_mode, &protocol, - &sess_cache_mode, &sess_id_ctx, - &cacerts_file)) - return NULL; - - /* - fprintf(stderr, - "server_side is %d, keyfile %p, certfile %p, verify_mode %d, " - "protocol %d, sess_cache_mode %d, sess_id_ctx %p, certs %p\n", - server_side, key_file, cert_file, verification_mode, - protocol, sess_cache_mode, sess_id_ctx, cacerts_file); - */ - - return (PyObject *) newPySSLObject(NULL, Sock, key_file, cert_file, - server_side, verification_mode, - protocol, sess_cache_mode, sess_id_ctx, - cacerts_file); -} - -PyDoc_STRVAR(sslwrap_doc, -"sslwrap(socket, server_side, [keyfile, certfile, certs_mode, protocol,\n" -" sess_cache_mode, sess_id_ctx, cacertsfile]) -> sslobject"); - -/* SSL object methods */ - -static PyObject * -PySSL_SSLwrap_accepted(PySSLObject *self, PyObject *args) -{ - PySocketSockObject *Sock; - - if (!PyArg_ParseTuple(args, "O!:sslwrap", - PySocketModule.Sock_Type, - &Sock)) - return NULL; - - return (PyObject *) newPySSLObject(self, Sock, NULL, NULL, - PY_SSL_SERVER, 0, 0, 0, NULL, NULL); -} - -PyDoc_STRVAR(PySSL_SSLwrap_accepted_doc, -"wrap_accepted(socket) -> sslobject"); - -static PyObject *PySSL_SSLdo_handshake(PySSLObject *self) -{ - int ret; - int err; - int sockstate, nonblocking; - - /* just in case the blocking state of the socket has been changed */ - nonblocking = (self->Socket->sock_timeout >= 0.0); - BIO_set_nbio(SSL_get_rbio(self->ssl), nonblocking); - BIO_set_nbio(SSL_get_wbio(self->ssl), nonblocking); - - /* Actually negotiate SSL connection */ - /* XXX If SSL_do_handshake() returns 0, it's also a failure. */ - sockstate = 0; - do { - PySSL_BEGIN_ALLOW_THREADS - ret = SSL_do_handshake(self->ssl); - err = SSL_get_error(self->ssl, ret); - PySSL_END_ALLOW_THREADS - if(PyErr_CheckSignals()) { - return NULL; - } - if (err == SSL_ERROR_WANT_READ) { - sockstate = check_socket_and_wait_for_timeout(self->Socket, 0); - } else if (err == SSL_ERROR_WANT_WRITE) { - sockstate = check_socket_and_wait_for_timeout(self->Socket, 1); - } else { - sockstate = SOCKET_OPERATION_OK; - } - if (sockstate == SOCKET_HAS_TIMED_OUT) { - PyErr_SetString(PySSLErrorObject, - ERRSTR("The handshake operation timed out")); - return NULL; - } else if (sockstate == SOCKET_HAS_BEEN_CLOSED) { - PyErr_SetString(PySSLErrorObject, - ERRSTR("Underlying socket has been closed.")); - return NULL; - } else if (sockstate == SOCKET_TOO_LARGE_FOR_SELECT) { - PyErr_SetString(PySSLErrorObject, - ERRSTR("Underlying socket too large for select().")); - return NULL; - } else if (sockstate == SOCKET_IS_NONBLOCKING) { - break; - } - } while (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE); - if (ret < 1) - return PySSL_SetError(self, ret, __FILE__, __LINE__); - - if (self->peer_cert) - X509_free (self->peer_cert); - PySSL_BEGIN_ALLOW_THREADS - if ((self->peer_cert = SSL_get_peer_certificate(self->ssl))) { - X509_NAME_oneline(X509_get_subject_name(self->peer_cert), - self->server, X509_NAME_MAXLEN); - X509_NAME_oneline(X509_get_issuer_name(self->peer_cert), - self->issuer, X509_NAME_MAXLEN); - } - PySSL_END_ALLOW_THREADS - - Py_INCREF(Py_None); - return Py_None; -} - -static PyObject * -PySSL_server(PySSLObject *self) -{ - return PyString_FromString(self->server); -} - -static PyObject * -PySSL_issuer(PySSLObject *self) -{ - return PyString_FromString(self->issuer); -} - -static PyObject * -_create_tuple_for_attribute (ASN1_OBJECT *name, ASN1_STRING *value) { - - char namebuf[X509_NAME_MAXLEN]; - int buflen; - PyObject *name_obj; - PyObject *value_obj; - PyObject *attr; - unsigned char *valuebuf = NULL; - - buflen = OBJ_obj2txt(namebuf, sizeof(namebuf), name, 0); - if (buflen < 0) { - _setSSLError(NULL, 0, __FILE__, __LINE__); - goto fail; - } - name_obj = PyString_FromStringAndSize(namebuf, buflen); - if (name_obj == NULL) - goto fail; - - buflen = ASN1_STRING_to_UTF8(&valuebuf, value); - if (buflen < 0) { - _setSSLError(NULL, 0, __FILE__, __LINE__); - Py_DECREF(name_obj); - goto fail; - } - value_obj = PyUnicode_DecodeUTF8((char *) valuebuf, - buflen, "strict"); - OPENSSL_free(valuebuf); - if (value_obj == NULL) { - Py_DECREF(name_obj); - goto fail; - } - attr = PyTuple_New(2); - if (attr == NULL) { - Py_DECREF(name_obj); - Py_DECREF(value_obj); - goto fail; - } - PyTuple_SET_ITEM(attr, 0, name_obj); - PyTuple_SET_ITEM(attr, 1, value_obj); - return attr; - - fail: - return NULL; -} - -static PyObject * -_create_tuple_for_X509_NAME (X509_NAME *xname) -{ - PyObject *dn = NULL; /* tuple which represents the "distinguished name" */ - PyObject *rdn = NULL; /* tuple to hold a "relative distinguished name" */ - PyObject *rdnt; - PyObject *attr = NULL; /* tuple to hold an attribute */ - int entry_count = X509_NAME_entry_count(xname); - X509_NAME_ENTRY *entry; - ASN1_OBJECT *name; - ASN1_STRING *value; - int index_counter; - int rdn_level = -1; - int retcode; - - dn = PyList_New(0); - if (dn == NULL) - return NULL; - /* now create another tuple to hold the top-level RDN */ - rdn = PyList_New(0); - if (rdn == NULL) - goto fail0; - - for (index_counter = 0; - index_counter < entry_count; - index_counter++) - { - entry = X509_NAME_get_entry(xname, index_counter); - - /* check to see if we've gotten to a new RDN */ - if (rdn_level >= 0) { - if (rdn_level != entry->set) { - /* yes, new RDN */ - /* add old RDN to DN */ - rdnt = PyList_AsTuple(rdn); - Py_DECREF(rdn); - if (rdnt == NULL) - goto fail0; - retcode = PyList_Append(dn, rdnt); - Py_DECREF(rdnt); - if (retcode < 0) - goto fail0; - /* create new RDN */ - rdn = PyList_New(0); - if (rdn == NULL) - goto fail0; - } - } - rdn_level = entry->set; - - /* now add this attribute to the current RDN */ - name = X509_NAME_ENTRY_get_object(entry); - value = X509_NAME_ENTRY_get_data(entry); - attr = _create_tuple_for_attribute(name, value); - /* - fprintf(stderr, "RDN level %d, attribute %s: %s\n", - entry->set, - PyString_AS_STRING(PyTuple_GET_ITEM(attr, 0)), - PyString_AS_STRING(PyTuple_GET_ITEM(attr, 1))); - */ - if (attr == NULL) - goto fail1; - retcode = PyList_Append(rdn, attr); - Py_DECREF(attr); - if (retcode < 0) - goto fail1; - } - /* now, there's typically a dangling RDN */ - if ((rdn != NULL) && (PyList_Size(rdn) > 0)) { - rdnt = PyList_AsTuple(rdn); - Py_DECREF(rdn); - if (rdnt == NULL) - goto fail0; - retcode = PyList_Append(dn, rdnt); - Py_DECREF(rdnt); - if (retcode < 0) - goto fail0; - } - - /* convert list to tuple */ - rdnt = PyList_AsTuple(dn); - Py_DECREF(dn); - if (rdnt == NULL) - return NULL; - return rdnt; - - fail1: - Py_XDECREF(rdn); - - fail0: - Py_XDECREF(dn); - return NULL; -} - -static PyObject * -_get_peer_alt_names (X509 *certificate) { - - /* this code follows the procedure outlined in - OpenSSL's crypto/x509v3/v3_prn.c:X509v3_EXT_print() - function to extract the STACK_OF(GENERAL_NAME), - then iterates through the stack to add the - names. */ - - int i, j; - PyObject *peer_alt_names = Py_None; - PyObject *v, *t; - X509_EXTENSION *ext = NULL; - GENERAL_NAMES *names = NULL; - GENERAL_NAME *name; - X509V3_EXT_METHOD *method; - BIO *biobuf = NULL; - char buf[2048]; - char *vptr; - int len; - const unsigned char *p; - - if (certificate == NULL) - return peer_alt_names; - - /* get a memory buffer */ - biobuf = BIO_new(BIO_s_mem()); - - i = 0; - while ((i = X509_get_ext_by_NID( - certificate, NID_subject_alt_name, i)) >= 0) { - - if (peer_alt_names == Py_None) { - peer_alt_names = PyList_New(0); - if (peer_alt_names == NULL) - goto fail; - } - - /* now decode the altName */ - ext = X509_get_ext(certificate, i); - if(!(method = X509V3_EXT_get(ext))) { - PyErr_SetString(PySSLErrorObject, - ERRSTR("No method for internalizing subjectAltName!")); - goto fail; - } - - p = ext->value->data; - if (method->it) - names = (GENERAL_NAMES*) (ASN1_item_d2i(NULL, - &p, - ext->value->length, - ASN1_ITEM_ptr(method->it))); - else - names = (GENERAL_NAMES*) (method->d2i(NULL, - &p, - ext->value->length)); - - for(j = 0; j < sk_GENERAL_NAME_num(names); j++) { - - /* get a rendering of each name in the set of names */ - - name = sk_GENERAL_NAME_value(names, j); - if (name->type == GEN_DIRNAME) { - - /* we special-case DirName as a tuple of tuples of attributes */ - - t = PyTuple_New(2); - if (t == NULL) { - goto fail; - } - - v = PyString_FromString("DirName"); - if (v == NULL) { - Py_DECREF(t); - goto fail; - } - PyTuple_SET_ITEM(t, 0, v); - - v = _create_tuple_for_X509_NAME (name->d.dirn); - if (v == NULL) { - Py_DECREF(t); - goto fail; - } - PyTuple_SET_ITEM(t, 1, v); - - } else { - - /* for everything else, we use the OpenSSL print form */ - - (void) BIO_reset(biobuf); - GENERAL_NAME_print(biobuf, name); - len = BIO_gets(biobuf, buf, sizeof(buf)-1); - if (len < 0) { - _setSSLError(NULL, 0, __FILE__, __LINE__); - goto fail; - } - vptr = strchr(buf, ':'); - if (vptr == NULL) - goto fail; - t = PyTuple_New(2); - if (t == NULL) - goto fail; - v = PyString_FromStringAndSize(buf, (vptr - buf)); - if (v == NULL) { - Py_DECREF(t); - goto fail; - } - PyTuple_SET_ITEM(t, 0, v); - v = PyString_FromStringAndSize((vptr + 1), (len - (vptr - buf + 1))); - if (v == NULL) { - Py_DECREF(t); - goto fail; - } - PyTuple_SET_ITEM(t, 1, v); - } - - /* and add that rendering to the list */ - - if (PyList_Append(peer_alt_names, t) < 0) { - Py_DECREF(t); - goto fail; - } - Py_DECREF(t); - } - } - BIO_free(biobuf); - if (peer_alt_names != Py_None) { - v = PyList_AsTuple(peer_alt_names); - Py_DECREF(peer_alt_names); - return v; - } else { - return peer_alt_names; - } - - - fail: - if (biobuf != NULL) - BIO_free(biobuf); - - if (peer_alt_names != Py_None) { - Py_XDECREF(peer_alt_names); - } - - return NULL; -} - -static PyObject * -_decode_certificate (X509 *certificate, int verbose) { - - PyObject *retval = NULL; - BIO *biobuf = NULL; - PyObject *peer; - PyObject *peer_alt_names = NULL; - PyObject *issuer; - PyObject *version; - PyObject *sn_obj; - ASN1_INTEGER *serialNumber; - char buf[2048]; - int len; - ASN1_TIME *notBefore, *notAfter; - PyObject *pnotBefore, *pnotAfter; - - retval = PyDict_New(); - if (retval == NULL) - return NULL; - - peer = _create_tuple_for_X509_NAME( - X509_get_subject_name(certificate)); - if (peer == NULL) - goto fail0; - if (PyDict_SetItemString(retval, (const char *) "subject", peer) < 0) { - Py_DECREF(peer); - goto fail0; - } - Py_DECREF(peer); - - if (verbose) { - issuer = _create_tuple_for_X509_NAME( - X509_get_issuer_name(certificate)); - if (issuer == NULL) - goto fail0; - if (PyDict_SetItemString(retval, (const char *)"issuer", issuer) < 0) { - Py_DECREF(issuer); - goto fail0; - } - Py_DECREF(issuer); - - version = PyInt_FromLong(X509_get_version(certificate) + 1); - if (PyDict_SetItemString(retval, "version", version) < 0) { - Py_DECREF(version); - goto fail0; - } - Py_DECREF(version); - } - - /* get a memory buffer */ - biobuf = BIO_new(BIO_s_mem()); - - if (verbose) { - - (void) BIO_reset(biobuf); - serialNumber = X509_get_serialNumber(certificate); - /* should not exceed 20 octets, 160 bits, so buf is big enough */ - i2a_ASN1_INTEGER(biobuf, serialNumber); - len = BIO_gets(biobuf, buf, sizeof(buf)-1); - if (len < 0) { - _setSSLError(NULL, 0, __FILE__, __LINE__); - goto fail1; - } - sn_obj = PyString_FromStringAndSize(buf, len); - if (sn_obj == NULL) - goto fail1; - if (PyDict_SetItemString(retval, "serialNumber", sn_obj) < 0) { - Py_DECREF(sn_obj); - goto fail1; - } - Py_DECREF(sn_obj); - - (void) BIO_reset(biobuf); - notBefore = X509_get_notBefore(certificate); - ASN1_TIME_print(biobuf, notBefore); - len = BIO_gets(biobuf, buf, sizeof(buf)-1); - if (len < 0) { - _setSSLError(NULL, 0, __FILE__, __LINE__); - goto fail1; - } - pnotBefore = PyString_FromStringAndSize(buf, len); - if (pnotBefore == NULL) - goto fail1; - if (PyDict_SetItemString(retval, "notBefore", pnotBefore) < 0) { - Py_DECREF(pnotBefore); - goto fail1; - } - Py_DECREF(pnotBefore); - } - - (void) BIO_reset(biobuf); - notAfter = X509_get_notAfter(certificate); - ASN1_TIME_print(biobuf, notAfter); - len = BIO_gets(biobuf, buf, sizeof(buf)-1); - if (len < 0) { - _setSSLError(NULL, 0, __FILE__, __LINE__); - goto fail1; - } - pnotAfter = PyString_FromStringAndSize(buf, len); - if (pnotAfter == NULL) - goto fail1; - if (PyDict_SetItemString(retval, "notAfter", pnotAfter) < 0) { - Py_DECREF(pnotAfter); - goto fail1; - } - Py_DECREF(pnotAfter); - - /* Now look for subjectAltName */ - - peer_alt_names = _get_peer_alt_names(certificate); - if (peer_alt_names == NULL) - goto fail1; - else if (peer_alt_names != Py_None) { - if (PyDict_SetItemString(retval, "subjectAltName", - peer_alt_names) < 0) { - Py_DECREF(peer_alt_names); - goto fail1; - } - Py_DECREF(peer_alt_names); - } - - BIO_free(biobuf); - return retval; - - fail1: - if (biobuf != NULL) - BIO_free(biobuf); - fail0: - Py_XDECREF(retval); - return NULL; -} - - -static PyObject * -PySSL_test_decode_certificate (PyObject *mod, PyObject *args) { - - PyObject *retval = NULL; - char *filename = NULL; - X509 *x=NULL; - BIO *cert; - int verbose = 1; - - if (!PyArg_ParseTuple(args, "s|i:test_decode_certificate", &filename, &verbose)) - return NULL; - - if ((cert=BIO_new(BIO_s_file())) == NULL) { - PyErr_SetString(PySSLErrorObject, "Can't malloc memory to read file"); - goto fail0; - } - - if (BIO_read_filename(cert,filename) <= 0) { - PyErr_SetString(PySSLErrorObject, "Can't open file"); - goto fail0; - } - - x = PEM_read_bio_X509_AUX(cert,NULL, NULL, NULL); - if (x == NULL) { - PyErr_SetString(PySSLErrorObject, "Error decoding PEM-encoded file"); - goto fail0; - } - - retval = _decode_certificate(x, verbose); - - fail0: - - if (cert != NULL) BIO_free(cert); - return retval; -} - - -static PyObject * -PySSL_peercert(PySSLObject *self, PyObject *args) -{ - PyObject *retval = NULL; - int len; - int verification; - PyObject *binary_mode = Py_None; - - if (!PyArg_ParseTuple(args, "|O:peer_certificate", &binary_mode)) - return NULL; - - if (!self->peer_cert) - Py_RETURN_NONE; - - if (PyObject_IsTrue(binary_mode)) { - /* return cert in DER-encoded format */ - - unsigned char *bytes_buf = NULL; - - bytes_buf = NULL; - len = i2d_X509(self->peer_cert, &bytes_buf); - if (len < 0) { - PySSL_SetError(self, len, __FILE__, __LINE__); - return NULL; - } - retval = PyString_FromStringAndSize((const char *) bytes_buf, len); - OPENSSL_free(bytes_buf); - return retval; - - } else { - - verification = SSL_CTX_get_verify_mode(self->ctx); - if ((verification & SSL_VERIFY_PEER) == 0) - return PyDict_New(); - else - return _decode_certificate (self->peer_cert, 0); - } -} - -PyDoc_STRVAR(PySSL_peercert_doc, -"peer_certificate([der=False]) -> certificate\n\ -\n\ -Returns the certificate for the peer. If no certificate was provided,\n\ -returns None. If a certificate was provided, but not validated, returns\n\ -an empty dictionary. Otherwise returns a dict containing information\n\ -about the peer certificate.\n\ -\n\ -If the optional argument is True, returns a DER-encoded copy of the\n\ -peer certificate, or None if no certificate was provided. This will\n\ -return the certificate even if it wasn't validated."); - -static PyObject *PySSL_cipher (PySSLObject *self) { - - PyObject *retval, *v; - SSL_CIPHER *current; - char *cipher_name; - char *cipher_protocol; - - if (self->ssl == NULL) - return Py_None; - current = SSL_get_current_cipher(self->ssl); - if (current == NULL) - return Py_None; - - retval = PyTuple_New(3); - if (retval == NULL) - return NULL; - - cipher_name = (char *) SSL_CIPHER_get_name(current); - if (cipher_name == NULL) { - PyTuple_SET_ITEM(retval, 0, Py_None); - } else { - v = PyString_FromString(cipher_name); - if (v == NULL) - goto fail0; - PyTuple_SET_ITEM(retval, 0, v); - } - cipher_protocol = SSL_CIPHER_get_version(current); - if (cipher_protocol == NULL) { - PyTuple_SET_ITEM(retval, 1, Py_None); - } else { - v = PyString_FromString(cipher_protocol); - if (v == NULL) - goto fail0; - PyTuple_SET_ITEM(retval, 1, v); - } - v = PyInt_FromLong(SSL_CIPHER_get_bits(current, NULL)); - if (v == NULL) - goto fail0; - PyTuple_SET_ITEM(retval, 2, v); - return retval; - - fail0: - Py_DECREF(retval); - return NULL; -} - -static void PySSL_dealloc(PySSLObject *self) -{ - if (self->peer_cert) /* Possible not to have one? */ - X509_free (self->peer_cert); - if (self->ssl) - SSL_free(self->ssl); - if (self->ctx && self->inherited == 0) - SSL_CTX_free(self->ctx); - Py_XDECREF(self->Socket); - PyObject_Del(self); -} - -/* If the socket has a timeout, do a select()/poll() on the socket. - The argument writing indicates the direction. - Returns one of the possibilities in the timeout_state enum (above). - */ - -static int -check_socket_and_wait_for_timeout(PySocketSockObject *s, int writing) -{ - fd_set fds; - struct timeval tv; - int rc; - - /* Nothing to do unless we're in timeout mode (not non-blocking) */ - if (s->sock_timeout < 0.0) - return SOCKET_IS_BLOCKING; - else if (s->sock_timeout == 0.0) - return SOCKET_IS_NONBLOCKING; - - /* Guard against closed socket */ - if (s->sock_fd < 0) - return SOCKET_HAS_BEEN_CLOSED; - - /* Prefer poll, if available, since you can poll() any fd - * which can't be done with select(). */ -#ifdef HAVE_POLL - { - struct pollfd pollfd; - int timeout; - - pollfd.fd = s->sock_fd; - pollfd.events = writing ? POLLOUT : POLLIN; - - /* s->sock_timeout is in seconds, timeout in ms */ - timeout = (int)(s->sock_timeout * 1000 + 0.5); - PySSL_BEGIN_ALLOW_THREADS - rc = poll(&pollfd, 1, timeout); - PySSL_END_ALLOW_THREADS - - goto normal_return; - } -#endif - - /* Guard against socket too large for select*/ -#ifndef Py_SOCKET_FD_CAN_BE_GE_FD_SETSIZE - if (s->sock_fd >= FD_SETSIZE) - return SOCKET_TOO_LARGE_FOR_SELECT; -#endif - - /* Construct the arguments to select */ - tv.tv_sec = (int)s->sock_timeout; - tv.tv_usec = (int)((s->sock_timeout - tv.tv_sec) * 1e6); - FD_ZERO(&fds); - FD_SET(s->sock_fd, &fds); - - /* See if the socket is ready */ - PySSL_BEGIN_ALLOW_THREADS - if (writing) - rc = select(s->sock_fd+1, NULL, &fds, NULL, &tv); - else - rc = select(s->sock_fd+1, &fds, NULL, NULL, &tv); - PySSL_END_ALLOW_THREADS - -#ifdef HAVE_POLL -normal_return: -#endif - /* Return SOCKET_TIMED_OUT on timeout, SOCKET_OPERATION_OK otherwise - (when we are able to write or when there's something to read) */ - return rc == 0 ? SOCKET_HAS_TIMED_OUT : SOCKET_OPERATION_OK; -} - -static PyObject *PySSL_SSLwrite(PySSLObject *self, PyObject *args) -{ - char *data; - int len; - int count; - int sockstate; - int err; - int nonblocking; - - if (!PyArg_ParseTuple(args, "s#:write", &data, &count)) - return NULL; - - /* just in case the blocking state of the socket has been changed */ - nonblocking = (self->Socket->sock_timeout >= 0.0); - BIO_set_nbio(SSL_get_rbio(self->ssl), nonblocking); - BIO_set_nbio(SSL_get_wbio(self->ssl), nonblocking); - - sockstate = check_socket_and_wait_for_timeout(self->Socket, 1); - if (sockstate == SOCKET_HAS_TIMED_OUT) { - PyErr_SetString(PySSLErrorObject, - "The write operation timed out"); - return NULL; - } else if (sockstate == SOCKET_HAS_BEEN_CLOSED) { - PyErr_SetString(PySSLErrorObject, - "Underlying socket has been closed."); - return NULL; - } else if (sockstate == SOCKET_TOO_LARGE_FOR_SELECT) { - PyErr_SetString(PySSLErrorObject, - "Underlying socket too large for select()."); - return NULL; - } - do { - err = 0; - PySSL_BEGIN_ALLOW_THREADS - len = SSL_write(self->ssl, data, count); - err = SSL_get_error(self->ssl, len); - PySSL_END_ALLOW_THREADS - if(PyErr_CheckSignals()) { - return NULL; - } - if (err == SSL_ERROR_WANT_READ) { - sockstate = check_socket_and_wait_for_timeout(self->Socket, 0); - } else if (err == SSL_ERROR_WANT_WRITE) { - sockstate = check_socket_and_wait_for_timeout(self->Socket, 1); - } else { - sockstate = SOCKET_OPERATION_OK; - } - if (sockstate == SOCKET_HAS_TIMED_OUT) { - PyErr_SetString(PySSLErrorObject, - "The write operation timed out"); - return NULL; - } else if (sockstate == SOCKET_HAS_BEEN_CLOSED) { - PyErr_SetString(PySSLErrorObject, - "Underlying socket has been closed."); - return NULL; - } else if (sockstate == SOCKET_IS_NONBLOCKING) { - break; - } - } while (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE); - if (len > 0) - return PyInt_FromLong(len); - else - return PySSL_SetError(self, len, __FILE__, __LINE__); -} - -PyDoc_STRVAR(PySSL_SSLwrite_doc, -"write(s) -> len\n\ -\n\ -Writes the string s into the SSL object. Returns the number\n\ -of bytes written."); - -static PyObject *PySSL_SSLpending(PySSLObject *self) -{ - int count = 0; - - PySSL_BEGIN_ALLOW_THREADS - count = SSL_pending(self->ssl); - PySSL_END_ALLOW_THREADS - if (count < 0) - return PySSL_SetError(self, count, __FILE__, __LINE__); - else - return PyInt_FromLong(count); -} - -PyDoc_STRVAR(PySSL_SSLpending_doc, -"pending() -> count\n\ -\n\ -Returns the number of already decrypted bytes available for read,\n\ -pending on the connection.\n"); - -static PyObject *PySSL_SSLread(PySSLObject *self, PyObject *args) -{ - PyObject *buf; - int count = 0; - int len = 1024; - int sockstate; - int err; - int nonblocking; - - if (!PyArg_ParseTuple(args, "|i:read", &len)) - return NULL; - - if (!(buf = PyString_FromStringAndSize((char *) 0, len))) - return NULL; - - /* just in case the blocking state of the socket has been changed */ - nonblocking = (self->Socket->sock_timeout >= 0.0); - BIO_set_nbio(SSL_get_rbio(self->ssl), nonblocking); - BIO_set_nbio(SSL_get_wbio(self->ssl), nonblocking); - - /* first check if there are bytes ready to be read */ - PySSL_BEGIN_ALLOW_THREADS - count = SSL_pending(self->ssl); - PySSL_END_ALLOW_THREADS - - if (!count) { - sockstate = check_socket_and_wait_for_timeout(self->Socket, 0); - if (sockstate == SOCKET_HAS_TIMED_OUT) { - PyErr_SetString(PySSLErrorObject, - "The read operation timed out"); - Py_DECREF(buf); - return NULL; - } else if (sockstate == SOCKET_TOO_LARGE_FOR_SELECT) { - PyErr_SetString(PySSLErrorObject, - "Underlying socket too large for select()."); - Py_DECREF(buf); - return NULL; - } else if (sockstate == SOCKET_HAS_BEEN_CLOSED) { - if (SSL_get_shutdown(self->ssl) != - SSL_RECEIVED_SHUTDOWN) - { - Py_DECREF(buf); - PyErr_SetString(PySSLErrorObject, - "Socket closed without SSL shutdown handshake"); - return NULL; - } else { - /* should contain a zero-length string */ - _PyString_Resize(&buf, 0); - return buf; - } - } - } - do { - err = 0; - PySSL_BEGIN_ALLOW_THREADS - count = SSL_read(self->ssl, PyString_AsString(buf), len); - err = SSL_get_error(self->ssl, count); - PySSL_END_ALLOW_THREADS - if(PyErr_CheckSignals()) { - Py_DECREF(buf); - return NULL; - } - if (err == SSL_ERROR_WANT_READ) { - sockstate = check_socket_and_wait_for_timeout(self->Socket, 0); - } else if (err == SSL_ERROR_WANT_WRITE) { - sockstate = check_socket_and_wait_for_timeout(self->Socket, 1); - } else if ((err == SSL_ERROR_ZERO_RETURN) && - (SSL_get_shutdown(self->ssl) == - SSL_RECEIVED_SHUTDOWN)) - { - _PyString_Resize(&buf, 0); - return buf; - } else { - sockstate = SOCKET_OPERATION_OK; - } - if (sockstate == SOCKET_HAS_TIMED_OUT) { - PyErr_SetString(PySSLErrorObject, - "The read operation timed out"); - Py_DECREF(buf); - return NULL; - } else if (sockstate == SOCKET_IS_NONBLOCKING) { - break; - } - } while (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE); - if (count <= 0) { - Py_DECREF(buf); - return PySSL_SetError(self, count, __FILE__, __LINE__); - } - if (count != len) - _PyString_Resize(&buf, count); - return buf; -} - -PyDoc_STRVAR(PySSL_SSLread_doc, -"read([len]) -> string\n\ -\n\ -Read up to len bytes from the SSL socket."); - -static PyObject *PySSL_SSLshutdown(PySSLObject *self) -{ - int err, ssl_err, sockstate, nonblocking; - int zeros = 0; - - /* Guard against closed socket */ - if (self->Socket->sock_fd < 0) { - PyErr_SetString(PySSLErrorObject, - "Underlying socket has been closed."); - return NULL; - } - - /* Just in case the blocking state of the socket has been changed */ - nonblocking = (self->Socket->sock_timeout >= 0.0); - BIO_set_nbio(SSL_get_rbio(self->ssl), nonblocking); - BIO_set_nbio(SSL_get_wbio(self->ssl), nonblocking); - - while (1) { - PySSL_BEGIN_ALLOW_THREADS - /* Disable read-ahead so that unwrap can work correctly. - * Otherwise OpenSSL might read in too much data, - * eating clear text data that happens to be - * transmitted after the SSL shutdown. - * Should be safe to call repeatedly everytime this - * function is used and the shutdown_seen_zero != 0 - * condition is met. - */ - if (self->shutdown_seen_zero) - SSL_set_read_ahead(self->ssl, 0); - err = SSL_shutdown(self->ssl); - PySSL_END_ALLOW_THREADS - /* If err == 1, a secure shutdown with SSL_shutdown() is complete */ - if (err > 0) - break; - if (err == 0) { - /* Don't loop endlessly; instead preserve legacy - behaviour of trying SSL_shutdown() only twice. - This looks necessary for OpenSSL < 0.9.8m */ - if (++zeros > 1) - break; - /* Shutdown was sent, now try receiving */ - self->shutdown_seen_zero = 1; - continue; - } - - /* Possibly retry shutdown until timeout or failure */ - ssl_err = SSL_get_error(self->ssl, err); - if (ssl_err == SSL_ERROR_WANT_READ) - sockstate = check_socket_and_wait_for_timeout(self->Socket, 0); - else if (ssl_err == SSL_ERROR_WANT_WRITE) - sockstate = check_socket_and_wait_for_timeout(self->Socket, 1); - else - break; - if (sockstate == SOCKET_HAS_TIMED_OUT) { - if (ssl_err == SSL_ERROR_WANT_READ) - PyErr_SetString(PySSLErrorObject, - "The read operation timed out"); - else - PyErr_SetString(PySSLErrorObject, - "The write operation timed out"); - return NULL; - } - else if (sockstate == SOCKET_TOO_LARGE_FOR_SELECT) { - PyErr_SetString(PySSLErrorObject, - "Underlying socket too large for select()."); - return NULL; - } - else if (sockstate != SOCKET_OPERATION_OK) - /* Retain the SSL error code */ - break; - } - - if (err < 0) - return PySSL_SetError(self, err, __FILE__, __LINE__); - else { - Py_INCREF(self->Socket); - return (PyObject *) (self->Socket); - } -} - -PyDoc_STRVAR(PySSL_SSLshutdown_doc, -"shutdown(s) -> socket\n\ -\n\ -Does the SSL shutdown handshake with the remote end, and returns\n\ -the underlying socket object."); - -static PyMethodDef PySSLMethods[] = { - {"wrap_accepted", (PyCFunction)PySSL_SSLwrap_accepted, METH_VARARGS, - PySSL_SSLwrap_accepted_doc}, - {"do_handshake", (PyCFunction)PySSL_SSLdo_handshake, METH_NOARGS}, - {"write", (PyCFunction)PySSL_SSLwrite, METH_VARARGS, - PySSL_SSLwrite_doc}, - {"read", (PyCFunction)PySSL_SSLread, METH_VARARGS, - PySSL_SSLread_doc}, - {"pending", (PyCFunction)PySSL_SSLpending, METH_NOARGS, - PySSL_SSLpending_doc}, - {"server", (PyCFunction)PySSL_server, METH_NOARGS}, - {"issuer", (PyCFunction)PySSL_issuer, METH_NOARGS}, - {"peer_certificate", (PyCFunction)PySSL_peercert, METH_VARARGS, - PySSL_peercert_doc}, - {"cipher", (PyCFunction)PySSL_cipher, METH_NOARGS}, - {"shutdown", (PyCFunction)PySSL_SSLshutdown, METH_NOARGS, - PySSL_SSLshutdown_doc}, - {NULL, NULL} -}; - -static PyObject *PySSL_getattr(PySSLObject *self, char *name) -{ - return Py_FindMethod(PySSLMethods, (PyObject *)self, name); -} - -static PyTypeObject PySSL_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "ssl.SSLContext", /*tp_name*/ - sizeof(PySSLObject), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - /* methods */ - (destructor)PySSL_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ - (getattrfunc)PySSL_getattr, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_compare*/ - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash*/ -}; - -#ifdef HAVE_OPENSSL_RAND - -/* helper routines for seeding the SSL PRNG */ -static PyObject * -PySSL_RAND_add(PyObject *self, PyObject *args) -{ - char *buf; - int len; - double entropy; - - if (!PyArg_ParseTuple(args, "s#d:RAND_add", &buf, &len, &entropy)) - return NULL; - RAND_add(buf, len, entropy); - Py_INCREF(Py_None); - return Py_None; -} - -PyDoc_STRVAR(PySSL_RAND_add_doc, -"RAND_add(string, entropy)\n\ -\n\ -Mix string into the OpenSSL PRNG state. entropy (a float) is a lower\n\ -bound on the entropy contained in string. See RFC 1750."); - -static PyObject * -PySSL_RAND_status(PyObject *self) -{ - return PyInt_FromLong(RAND_status()); -} - -PyDoc_STRVAR(PySSL_RAND_status_doc, -"RAND_status() -> 0 or 1\n\ -\n\ -Returns 1 if the OpenSSL PRNG has been seeded with enough data and 0 if not.\n\ -It is necessary to seed the PRNG with RAND_add() on some platforms before\n\ -using the ssl() function."); - -static PyObject * -PySSL_RAND_egd(PyObject *self, PyObject *arg) -{ - int bytes; - - if (!PyString_Check(arg)) - return PyErr_Format(PyExc_TypeError, - "RAND_egd() expected string, found %s", - Py_TYPE(arg)->tp_name); - bytes = RAND_egd(PyString_AS_STRING(arg)); - if (bytes == -1) { - PyErr_SetString(PySSLErrorObject, - "EGD connection failed or EGD did not return " - "enough data to seed the PRNG"); - return NULL; - } - return PyInt_FromLong(bytes); -} - -PyDoc_STRVAR(PySSL_RAND_egd_doc, -"RAND_egd(path) -> bytes\n\ -\n\ -Queries the entropy gather daemon (EGD) on the socket named by 'path'.\n\ -Returns number of bytes read. Raises SSLError if connection to EGD\n\ -fails or if it does provide enough data to seed PRNG."); - -#endif - -/* List of functions exported by this module. */ - -static PyMethodDef PySSL_methods[] = { - {"sslwrap", PySSL_sslwrap, - METH_VARARGS, sslwrap_doc}, - {"_test_decode_cert", PySSL_test_decode_certificate, - METH_VARARGS}, -#ifdef HAVE_OPENSSL_RAND - {"RAND_add", PySSL_RAND_add, METH_VARARGS, - PySSL_RAND_add_doc}, - {"RAND_egd", PySSL_RAND_egd, METH_O, - PySSL_RAND_egd_doc}, - {"RAND_status", (PyCFunction)PySSL_RAND_status, METH_NOARGS, - PySSL_RAND_status_doc}, -#endif - {NULL, NULL} /* Sentinel */ -}; - - -#ifdef WITH_THREAD - -/* an implementation of OpenSSL threading operations in terms - of the Python C thread library */ - -static PyThread_type_lock *_ssl_locks = NULL; - -static unsigned long _ssl_thread_id_function (void) { - return PyThread_get_thread_ident(); -} - -static void _ssl_thread_locking_function (int mode, int n, const char *file, int line) { - /* this function is needed to perform locking on shared data - structures. (Note that OpenSSL uses a number of global data - structures that will be implicitly shared whenever multiple threads - use OpenSSL.) Multi-threaded applications will crash at random if - it is not set. - - locking_function() must be able to handle up to CRYPTO_num_locks() - different mutex locks. It sets the n-th lock if mode & CRYPTO_LOCK, and - releases it otherwise. - - file and line are the file number of the function setting the - lock. They can be useful for debugging. - */ - - if ((_ssl_locks == NULL) || - (n < 0) || ((unsigned)n >= _ssl_locks_count)) - return; - - if (mode & CRYPTO_LOCK) { - PyThread_acquire_lock(_ssl_locks[n], 1); - } else { - PyThread_release_lock(_ssl_locks[n]); - } -} - -static int _setup_ssl_threads(void) { - - unsigned int i; - - if (_ssl_locks == NULL) { - _ssl_locks_count = CRYPTO_num_locks(); - _ssl_locks = (PyThread_type_lock *) - malloc(sizeof(PyThread_type_lock) * _ssl_locks_count); - if (_ssl_locks == NULL) - return 0; - memset(_ssl_locks, 0, sizeof(PyThread_type_lock) * _ssl_locks_count); - for (i = 0; i < _ssl_locks_count; i++) { - _ssl_locks[i] = PyThread_allocate_lock(); - if (_ssl_locks[i] == NULL) { - unsigned int j; - for (j = 0; j < i; j++) { - PyThread_free_lock(_ssl_locks[j]); - } - free(_ssl_locks); - return 0; - } - } - CRYPTO_set_locking_callback(_ssl_thread_locking_function); - CRYPTO_set_id_callback(_ssl_thread_id_function); - } - return 1; -} - -#endif /* def HAVE_THREAD */ - -PyDoc_STRVAR(module_doc, -"Implementation module for SSL socket operations. See the socket module\n\ -for documentation."); - -PyMODINIT_FUNC -init_forge_ssl(void) -{ - PyObject *m, *d; - - Py_TYPE(&PySSL_Type) = &PyType_Type; - - m = Py_InitModule3("_forge_ssl", PySSL_methods, module_doc); - if (m == NULL) - return; - d = PyModule_GetDict(m); - - /* Load _socket module and its C API */ - if (PySocketModule_ImportModuleAndAPI()) - return; - - /* Init OpenSSL */ - SSL_load_error_strings(); - SSL_library_init(); -#ifdef WITH_THREAD - /* note that this will start threading if not already started */ - if (!_setup_ssl_threads()) { - return; - } -#endif - OpenSSL_add_all_algorithms(); - - /* Add symbols to module dict */ - PySSLErrorObject = PyErr_NewException("ssl.SSLError", - PySocketModule.error, - NULL); - if (PySSLErrorObject == NULL) - return; - if (PyDict_SetItemString(d, "SSLError", PySSLErrorObject) != 0) - return; - if (PyDict_SetItemString(d, "SSLType", - (PyObject *)&PySSL_Type) != 0) - return; - PyModule_AddIntConstant(m, "SSL_ERROR_ZERO_RETURN", - PY_SSL_ERROR_ZERO_RETURN); - PyModule_AddIntConstant(m, "SSL_ERROR_WANT_READ", - PY_SSL_ERROR_WANT_READ); - PyModule_AddIntConstant(m, "SSL_ERROR_WANT_WRITE", - PY_SSL_ERROR_WANT_WRITE); - PyModule_AddIntConstant(m, "SSL_ERROR_WANT_X509_LOOKUP", - PY_SSL_ERROR_WANT_X509_LOOKUP); - PyModule_AddIntConstant(m, "SSL_ERROR_SYSCALL", - PY_SSL_ERROR_SYSCALL); - PyModule_AddIntConstant(m, "SSL_ERROR_SSL", - PY_SSL_ERROR_SSL); - PyModule_AddIntConstant(m, "SSL_ERROR_WANT_CONNECT", - PY_SSL_ERROR_WANT_CONNECT); - /* non ssl.h errorcodes */ - PyModule_AddIntConstant(m, "SSL_ERROR_EOF", - PY_SSL_ERROR_EOF); - PyModule_AddIntConstant(m, "SSL_ERROR_INVALID_ERROR_CODE", - PY_SSL_ERROR_INVALID_ERROR_CODE); - /* cert requirements */ - PyModule_AddIntConstant(m, "CERT_NONE", - PY_SSL_CERT_NONE); - PyModule_AddIntConstant(m, "CERT_OPTIONAL", - PY_SSL_CERT_OPTIONAL); - PyModule_AddIntConstant(m, "CERT_REQUIRED", - PY_SSL_CERT_REQUIRED); - - /* protocol versions */ - PyModule_AddIntConstant(m, "PROTOCOL_SSLv2", - PY_SSL_VERSION_SSL2); - PyModule_AddIntConstant(m, "PROTOCOL_SSLv3", - PY_SSL_VERSION_SSL3); - PyModule_AddIntConstant(m, "PROTOCOL_SSLv23", - PY_SSL_VERSION_SSL23); - PyModule_AddIntConstant(m, "PROTOCOL_TLSv1", - PY_SSL_VERSION_TLS1); - - /* session cache modes */ - PyModule_AddIntConstant(m, "SESS_CACHE_OFF", - PY_SSL_SESS_CACHE_OFF); - PyModule_AddIntConstant(m, "SESS_CACHE_CLIENT", - PY_SSL_SESS_CACHE_CLIENT); - PyModule_AddIntConstant(m, "SESS_CACHE_SERVER", - PY_SSL_SESS_CACHE_SERVER); - PyModule_AddIntConstant(m, "SESS_CACHE_BOTH", - PY_SSL_SESS_CACHE_BOTH); -} diff --git a/alarm/node_modules/node-forge/tests/forge_ssl/forge/socketmodule.h b/alarm/node_modules/node-forge/tests/forge_ssl/forge/socketmodule.h deleted file mode 100644 index a4415b5..0000000 --- a/alarm/node_modules/node-forge/tests/forge_ssl/forge/socketmodule.h +++ /dev/null @@ -1,268 +0,0 @@ -/* Socket module header file */ - -/* Includes needed for the sockaddr_* symbols below */ -#ifndef MS_WINDOWS -#ifdef __VMS -# include <socket.h> -# else -# include <sys/socket.h> -# endif -# include <netinet/in.h> -# if !(defined(__BEOS__) || defined(__CYGWIN__) || (defined(PYOS_OS2) && defined(PYCC_VACPP))) -# include <netinet/tcp.h> -# endif - -#else /* MS_WINDOWS */ -# include <winsock2.h> -# include <ws2tcpip.h> -/* VC6 is shipped with old platform headers, and does not have MSTcpIP.h - * Separate SDKs have all the functions we want, but older ones don't have - * any version information. - * I use SIO_GET_MULTICAST_FILTER to detect a decent SDK. - */ -# ifdef SIO_GET_MULTICAST_FILTER -# include <MSTcpIP.h> /* for SIO_RCVALL */ -# define HAVE_ADDRINFO -# define HAVE_SOCKADDR_STORAGE -# define HAVE_GETADDRINFO -# define HAVE_GETNAMEINFO -# define ENABLE_IPV6 -# else -typedef int socklen_t; -# endif /* IPPROTO_IPV6 */ -#endif /* MS_WINDOWS */ - -#ifdef HAVE_SYS_UN_H -# include <sys/un.h> -#else -# undef AF_UNIX -#endif - -#ifdef HAVE_LINUX_NETLINK_H -# ifdef HAVE_ASM_TYPES_H -# include <asm/types.h> -# endif -# include <linux/netlink.h> -#else -# undef AF_NETLINK -#endif - -#ifdef HAVE_BLUETOOTH_BLUETOOTH_H -/* -#include <bluetooth/bluetooth.h> -#include <bluetooth/rfcomm.h> -#include <bluetooth/l2cap.h> -#include <bluetooth/sco.h> -#include <bluetooth/hci.h> -*/ -#endif - -#ifdef HAVE_BLUETOOTH_H -#include <bluetooth.h> -#endif - -#ifdef HAVE_NETPACKET_PACKET_H -# include <sys/ioctl.h> -# include <net/if.h> -# include <netpacket/packet.h> -#endif - -#ifdef HAVE_LINUX_TIPC_H -# include <linux/tipc.h> -#endif - -#ifndef Py__SOCKET_H -#define Py__SOCKET_H -#ifdef __cplusplus -extern "C" { -#endif - -/* Python module and C API name */ -#define PySocket_MODULE_NAME "_socket" -#define PySocket_CAPI_NAME "CAPI" - -/* Abstract the socket file descriptor type */ -#ifdef MS_WINDOWS -typedef SOCKET SOCKET_T; -# ifdef MS_WIN64 -# define SIZEOF_SOCKET_T 8 -# else -# define SIZEOF_SOCKET_T 4 -# endif -#else -typedef int SOCKET_T; -# define SIZEOF_SOCKET_T SIZEOF_INT -#endif - -/* Socket address */ -typedef union sock_addr { - struct sockaddr_in in; -#ifdef AF_UNIX - struct sockaddr_un un; -#endif -#ifdef AF_NETLINK - struct sockaddr_nl nl; -#endif -#ifdef ENABLE_IPV6 - struct sockaddr_in6 in6; - struct sockaddr_storage storage; -#endif -#ifdef HAVE_BLUETOOTH_BLUETOOTH_H -/* - struct sockaddr_l2 bt_l2; - struct sockaddr_rc bt_rc; - struct sockaddr_sco bt_sco; - struct sockaddr_hci bt_hci; -*/ -#endif -#ifdef HAVE_NETPACKET_PACKET_H - struct sockaddr_ll ll; -#endif -} sock_addr_t; - -/* The object holding a socket. It holds some extra information, - like the address family, which is used to decode socket address - arguments properly. */ - -typedef struct { - PyObject_HEAD - SOCKET_T sock_fd; /* Socket file descriptor */ - int sock_family; /* Address family, e.g., AF_INET */ - int sock_type; /* Socket type, e.g., SOCK_STREAM */ - int sock_proto; /* Protocol type, usually 0 */ - PyObject *(*errorhandler)(void); /* Error handler; checks - errno, returns NULL and - sets a Python exception */ - double sock_timeout; /* Operation timeout in seconds; - 0.0 means non-blocking */ -} PySocketSockObject; - -/* --- C API ----------------------------------------------------*/ - -/* Short explanation of what this C API export mechanism does - and how it works: - - The _ssl module needs access to the type object defined in - the _socket module. Since cross-DLL linking introduces a lot of - problems on many platforms, the "trick" is to wrap the - C API of a module in a struct which then gets exported to - other modules via a PyCObject. - - The code in socketmodule.c defines this struct (which currently - only contains the type object reference, but could very - well also include other C APIs needed by other modules) - and exports it as PyCObject via the module dictionary - under the name "CAPI". - - Other modules can now include the socketmodule.h file - which defines the needed C APIs to import and set up - a static copy of this struct in the importing module. - - After initialization, the importing module can then - access the C APIs from the _socket module by simply - referring to the static struct, e.g. - - Load _socket module and its C API; this sets up the global - PySocketModule: - - if (PySocketModule_ImportModuleAndAPI()) - return; - - - Now use the C API as if it were defined in the using - module: - - if (!PyArg_ParseTuple(args, "O!|zz:ssl", - - PySocketModule.Sock_Type, - - (PyObject*)&Sock, - &key_file, &cert_file)) - return NULL; - - Support could easily be extended to export more C APIs/symbols - this way. Currently, only the type object is exported, - other candidates would be socket constructors and socket - access functions. - -*/ - -/* C API for usage by other Python modules */ -typedef struct { - PyTypeObject *Sock_Type; - PyObject *error; -} PySocketModule_APIObject; - -/* XXX The net effect of the following appears to be to define a function - XXX named PySocketModule_APIObject in _ssl.c. It's unclear why it isn't - XXX defined there directly. - - >>> It's defined here because other modules might also want to use - >>> the C API. - -*/ -#ifndef PySocket_BUILDING_SOCKET - -/* --- C API ----------------------------------------------------*/ - -/* Interfacestructure to C API for other modules. - Call PySocketModule_ImportModuleAndAPI() to initialize this - structure. After that usage is simple: - - if (!PyArg_ParseTuple(args, "O!|zz:ssl", - &PySocketModule.Sock_Type, (PyObject*)&Sock, - &key_file, &cert_file)) - return NULL; - ... -*/ - -static -PySocketModule_APIObject PySocketModule; - -/* You *must* call this before using any of the functions in - PySocketModule and check its outcome; otherwise all accesses will - result in a segfault. Returns 0 on success. */ - -#ifndef DPRINTF -# define DPRINTF if (0) printf -#endif - -static -int PySocketModule_ImportModuleAndAPI(void) -{ - PyObject *mod = 0, *v = 0; - char *apimodule = PySocket_MODULE_NAME; - char *apiname = PySocket_CAPI_NAME; - void *api; - - DPRINTF("Importing the %s C API...\n", apimodule); - mod = PyImport_ImportModuleNoBlock(apimodule); - if (mod == NULL) - goto onError; - DPRINTF(" %s package found\n", apimodule); - v = PyObject_GetAttrString(mod, apiname); - if (v == NULL) - goto onError; - Py_DECREF(mod); - DPRINTF(" API object %s found\n", apiname); - api = PyCObject_AsVoidPtr(v); - if (api == NULL) - goto onError; - Py_DECREF(v); - memcpy(&PySocketModule, api, sizeof(PySocketModule)); - DPRINTF(" API object loaded and initialized.\n"); - return 0; - - onError: - DPRINTF(" not found.\n"); - Py_XDECREF(mod); - Py_XDECREF(v); - return -1; -} - -#endif /* !PySocket_BUILDING_SOCKET */ - -#ifdef __cplusplus -} -#endif -#endif /* !Py__SOCKET_H */ diff --git a/alarm/node_modules/node-forge/tests/forge_ssl/forge/ssl.py b/alarm/node_modules/node-forge/tests/forge_ssl/forge/ssl.py deleted file mode 100644 index aa9fc14..0000000 --- a/alarm/node_modules/node-forge/tests/forge_ssl/forge/ssl.py +++ /dev/null @@ -1,486 +0,0 @@ -# Wrapper module for _ssl, providing some additional facilities -# implemented in Python. Written by Bill Janssen. - -"""\ -This module provides some more Pythonic support for SSL. - -Object types: - - SSLSocket -- subtype of socket.socket which does SSL over the socket - -Exceptions: - - SSLError -- exception raised for I/O errors - -Functions: - - cert_time_to_seconds -- convert time string used for certificate - notBefore and notAfter functions to integer - seconds past the Epoch (the time values - returned from time.time()) - - fetch_server_certificate (HOST, PORT) -- fetch the certificate provided - by the server running on HOST at port PORT. No - validation of the certificate is performed. - -Integer constants: - -SSL_ERROR_ZERO_RETURN -SSL_ERROR_WANT_READ -SSL_ERROR_WANT_WRITE -SSL_ERROR_WANT_X509_LOOKUP -SSL_ERROR_SYSCALL -SSL_ERROR_SSL -SSL_ERROR_WANT_CONNECT - -SSL_ERROR_EOF -SSL_ERROR_INVALID_ERROR_CODE - -The following group define certificate requirements that one side is -allowing/requiring from the other side: - -CERT_NONE - no certificates from the other side are required (or will - be looked at if provided) -CERT_OPTIONAL - certificates are not required, but if provided will be - validated, and if validation fails, the connection will - also fail -CERT_REQUIRED - certificates are required, and will be validated, and - if validation fails, the connection will also fail - -The following constants identify various SSL protocol variants: - -PROTOCOL_SSLv2 -PROTOCOL_SSLv3 -PROTOCOL_SSLv23 -PROTOCOL_TLSv1 - -The following constants identify various SSL session caching modes: - -SESS_CACHE_OFF -SESS_CACHE_CLIENT -SESS_CACHE_SERVER -SESS_CACHE_BOTH -""" - -import textwrap - -import _forge_ssl # if we can't import it, let the error propagate - -from _forge_ssl import SSLError -from _forge_ssl import CERT_NONE, CERT_OPTIONAL, CERT_REQUIRED -from _forge_ssl import PROTOCOL_SSLv2, PROTOCOL_SSLv3, PROTOCOL_SSLv23, PROTOCOL_TLSv1 -from _forge_ssl import SESS_CACHE_OFF, SESS_CACHE_CLIENT, SESS_CACHE_SERVER, SESS_CACHE_BOTH -from _forge_ssl import RAND_status, RAND_egd, RAND_add -from _forge_ssl import \ - SSL_ERROR_ZERO_RETURN, \ - SSL_ERROR_WANT_READ, \ - SSL_ERROR_WANT_WRITE, \ - SSL_ERROR_WANT_X509_LOOKUP, \ - SSL_ERROR_SYSCALL, \ - SSL_ERROR_SSL, \ - SSL_ERROR_WANT_CONNECT, \ - SSL_ERROR_EOF, \ - SSL_ERROR_INVALID_ERROR_CODE - -from socket import socket, _fileobject, _delegate_methods -from socket import error as socket_error -from socket import getnameinfo as _getnameinfo -import base64 # for DER-to-PEM translation -import errno - -class SSLSocket(socket): - - """This class implements a subtype of socket.socket that wraps - the underlying OS socket in an SSL context when necessary, and - provides read and write methods over that channel.""" - - def __init__(self, parent_socket, sock, keyfile=None, certfile=None, - server_side=False, cert_reqs=CERT_NONE, - ssl_version=PROTOCOL_SSLv23, - sess_cache_mode=SESS_CACHE_SERVER, - sess_id_ctx=None, - ca_certs=None, - do_handshake_on_connect=True, - suppress_ragged_eofs=True): - socket.__init__(self, _sock=sock._sock) - # The initializer for socket overrides the methods send(), recv(), etc. - # in the instancce, which we don't need -- but we want to provide the - # methods defined in SSLSocket. - for attr in _delegate_methods: - try: - delattr(self, attr) - except AttributeError: - pass - - if certfile and not keyfile: - keyfile = certfile - - create = True - connected = False - if not server_side: - # see if it's connected - try: - socket.getpeername(self) - connected = True - except socket_error, e: - if e.errno != errno.ENOTCONN: - raise - # no, no connection yet - self._sslobj = None - create = False - if create: - # yes, create the SSL object - if parent_socket == None: - self._sslobj = _forge_ssl.sslwrap( - self._sock, - server_side, - keyfile, certfile, - cert_reqs, ssl_version, - sess_cache_mode, sess_id_ctx, - ca_certs) - else: - self._sslobj = parent_socket._sslobj.wrap_accepted(self._sock) - - if connected and do_handshake_on_connect: - self.do_handshake() - self.keyfile = keyfile - self.certfile = certfile - self.cert_reqs = cert_reqs - self.ssl_version = ssl_version - self.sess_cache_mode = sess_cache_mode - self.sess_id_ctx = sess_id_ctx - self.ca_certs = ca_certs - self.do_handshake_on_connect = do_handshake_on_connect - self.suppress_ragged_eofs = suppress_ragged_eofs - self._makefile_refs = 0 - - def read(self, len=1024): - - """Read up to LEN bytes and return them. - Return zero-length string on EOF.""" - - try: - return self._sslobj.read(len) - except SSLError, x: - if x.args[0] == SSL_ERROR_EOF and self.suppress_ragged_eofs: - return '' - else: - raise - - def write(self, data): - - """Write DATA to the underlying SSL channel. Returns - number of bytes of DATA actually transmitted.""" - - return self._sslobj.write(data) - - def getpeercert(self, binary_form=False): - - """Returns a formatted version of the data in the - certificate provided by the other end of the SSL channel. - Return None if no certificate was provided, {} if a - certificate was provided, but not validated.""" - - return self._sslobj.peer_certificate(binary_form) - - def cipher(self): - - if not self._sslobj: - return None - else: - return self._sslobj.cipher() - - def send(self, data, flags=0): - if self._sslobj: - if flags != 0: - raise ValueError( - "non-zero flags not allowed in calls to send() on %s" % - self.__class__) - while True: - try: - v = self._sslobj.write(data) - except SSLError, x: - if x.args[0] == SSL_ERROR_WANT_READ: - return 0 - elif x.args[0] == SSL_ERROR_WANT_WRITE: - return 0 - else: - raise - else: - return v - else: - return socket.send(self, data, flags) - - def sendto(self, data, addr, flags=0): - if self._sslobj: - raise ValueError("sendto not allowed on instances of %s" % - self.__class__) - else: - return socket.sendto(self, data, addr, flags) - - def sendall(self, data, flags=0): - if self._sslobj: - if flags != 0: - raise ValueError( - "non-zero flags not allowed in calls to sendall() on %s" % - self.__class__) - amount = len(data) - count = 0 - while (count < amount): - v = self.send(data[count:]) - count += v - return amount - else: - return socket.sendall(self, data, flags) - - def recv(self, buflen=1024, flags=0): - if self._sslobj: - if flags != 0: - raise ValueError( - "non-zero flags not allowed in calls to recv() on %s" % - self.__class__) - return self.read(buflen) - else: - return socket.recv(self, buflen, flags) - - def recv_into(self, buffer, nbytes=None, flags=0): - if buffer and (nbytes is None): - nbytes = len(buffer) - elif nbytes is None: - nbytes = 1024 - if self._sslobj: - if flags != 0: - raise ValueError( - "non-zero flags not allowed in calls to recv_into() on %s" % - self.__class__) - tmp_buffer = self.read(nbytes) - v = len(tmp_buffer) - buffer[:v] = tmp_buffer - return v - else: - return socket.recv_into(self, buffer, nbytes, flags) - - def recvfrom(self, addr, buflen=1024, flags=0): - if self._sslobj: - raise ValueError("recvfrom not allowed on instances of %s" % - self.__class__) - else: - return socket.recvfrom(self, addr, buflen, flags) - - def recvfrom_into(self, buffer, nbytes=None, flags=0): - if self._sslobj: - raise ValueError("recvfrom_into not allowed on instances of %s" % - self.__class__) - else: - return socket.recvfrom_into(self, buffer, nbytes, flags) - - def pending(self): - if self._sslobj: - return self._sslobj.pending() - else: - return 0 - - def unwrap(self): - if self._sslobj: - try: - # if connected then shutdown - self.getpeername() - s = self._sslobj.shutdown() - except: - s = self._sock - self._sslobj = None - return s - else: - raise ValueError("No SSL wrapper around " + str(self)) - - def shutdown(self, how): - self._sslobj = None - socket.shutdown(self, how) - - def close(self): - if self._makefile_refs < 1: - if self._sslobj: - self.unwrap() - socket.close(self) - else: - self._makefile_refs -= 1 - - def do_handshake(self): - - """Perform a TLS/SSL handshake.""" - - self._sslobj.do_handshake() - - def connect(self, addr): - - """Connects to remote ADDR, and then wraps the connection in - an SSL channel.""" - - # Here we assume that the socket is client-side, and not - # connected at the time of the call. We connect it, then wrap it. - if self._sslobj: - raise ValueError("attempt to connect already-connected SSLSocket!") - socket.connect(self, addr) - self._sslobj = _forge_ssl.sslwrap(self._sock, False, - self.keyfile, self.certfile, - self.cert_reqs, self.ssl_version, - self.sess_cache_mode, - self.sess_id_ctx, - self.ca_certs) - if self.do_handshake_on_connect: - self.do_handshake() - - def accept(self): - - """Accepts a new connection from a remote client, and returns - a tuple containing that new connection wrapped with a server-side - SSL channel, and the address of the remote client.""" - - newsock, addr = socket.accept(self) - return (SSLSocket(self, - newsock, - keyfile=self.keyfile, - certfile=self.certfile, - server_side=True, - cert_reqs=self.cert_reqs, - ssl_version=self.ssl_version, - sess_cache_mode=self.sess_cache_mode, - sess_id_ctx=self.sess_id_ctx, - ca_certs=self.ca_certs, - do_handshake_on_connect=self.do_handshake_on_connect, - suppress_ragged_eofs=self.suppress_ragged_eofs), - addr) - - def makefile(self, mode='r', bufsize=-1): - - """Make and return a file-like object that - works with the SSL connection. Just use the code - from the socket module.""" - - self._makefile_refs += 1 - # close=True so as to decrement the reference count when done with - # the file-like object. - return _fileobject(self, mode, bufsize, close=True) - - - -def wrap_socket(sock, parent_socket=None, keyfile=None, certfile=None, - server_side=False, cert_reqs=CERT_NONE, - ssl_version=PROTOCOL_SSLv23, - sess_cache_mode=SESS_CACHE_SERVER, - sess_id_ctx=None, - ca_certs=None, - do_handshake_on_connect=True, - suppress_ragged_eofs=True): - - return SSLSocket(parent_socket, - sock, keyfile=keyfile, certfile=certfile, - server_side=server_side, cert_reqs=cert_reqs, - ssl_version=ssl_version, - sess_cache_mode=sess_cache_mode, - sess_id_ctx=sess_id_ctx, - ca_certs=ca_certs, - do_handshake_on_connect=do_handshake_on_connect, - suppress_ragged_eofs=suppress_ragged_eofs) - - -# some utility functions - -def cert_time_to_seconds(cert_time): - - """Takes a date-time string in standard ASN1_print form - ("MON DAY 24HOUR:MINUTE:SEC YEAR TIMEZONE") and return - a Python time value in seconds past the epoch.""" - - import time - return time.mktime(time.strptime(cert_time, "%b %d %H:%M:%S %Y GMT")) - -PEM_HEADER = "-----BEGIN CERTIFICATE-----" -PEM_FOOTER = "-----END CERTIFICATE-----" - -def DER_cert_to_PEM_cert(der_cert_bytes): - - """Takes a certificate in binary DER format and returns the - PEM version of it as a string.""" - - if hasattr(base64, 'standard_b64encode'): - # preferred because older API gets line-length wrong - f = base64.standard_b64encode(der_cert_bytes) - return (PEM_HEADER + '\n' + - textwrap.fill(f, 64) + '\n' + - PEM_FOOTER + '\n') - else: - return (PEM_HEADER + '\n' + - base64.encodestring(der_cert_bytes) + - PEM_FOOTER + '\n') - -def PEM_cert_to_DER_cert(pem_cert_string): - - """Takes a certificate in ASCII PEM format and returns the - DER-encoded version of it as a byte sequence""" - - if not pem_cert_string.startswith(PEM_HEADER): - raise ValueError("Invalid PEM encoding; must start with %s" - % PEM_HEADER) - if not pem_cert_string.strip().endswith(PEM_FOOTER): - raise ValueError("Invalid PEM encoding; must end with %s" - % PEM_FOOTER) - d = pem_cert_string.strip()[len(PEM_HEADER):-len(PEM_FOOTER)] - return base64.decodestring(d) - -def get_server_certificate(addr, ssl_version=PROTOCOL_SSLv3, ca_certs=None): - - """Retrieve the certificate from the server at the specified address, - and return it as a PEM-encoded string. - If 'ca_certs' is specified, validate the server cert against it. - If 'ssl_version' is specified, use it in the connection attempt.""" - - host, port = addr - if (ca_certs is not None): - cert_reqs = CERT_REQUIRED - else: - cert_reqs = CERT_NONE - s = wrap_socket(socket(), ssl_version=ssl_version, - cert_reqs=cert_reqs, ca_certs=ca_certs) - s.connect(addr) - dercert = s.getpeercert(True) - s.close() - return DER_cert_to_PEM_cert(dercert) - -def get_protocol_name(protocol_code): - if protocol_code == PROTOCOL_TLSv1: - return "TLSv1" - elif protocol_code == PROTOCOL_SSLv23: - return "SSLv23" - elif protocol_code == PROTOCOL_SSLv2: - return "SSLv2" - elif protocol_code == PROTOCOL_SSLv3: - return "SSLv3" - else: - return "<unknown>" - - -# a replacement for the old socket.ssl function - -def sslwrap_simple(sock, keyfile=None, certfile=None): - - """A replacement for the old socket.ssl function. Designed - for compability with Python 2.5 and earlier. Will disappear in - Python 3.0.""" - - if hasattr(sock, "_sock"): - sock = sock._sock - - ssl_sock = _forge_ssl.sslwrap(sock, 0, keyfile, certfile, - CERT_NONE, PROTOCOL_SSLv23, - SESS_CACHE_SERVER, None, None) - try: - sock.getpeername() - except: - # no, no connection yet - pass - else: - # yes, do the handshake - ssl_sock.do_handshake() - - return ssl_sock diff --git a/alarm/node_modules/node-forge/tests/forge_ssl/setup.py b/alarm/node_modules/node-forge/tests/forge_ssl/setup.py deleted file mode 100644 index 350ae37..0000000 --- a/alarm/node_modules/node-forge/tests/forge_ssl/setup.py +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/env python - -from distutils.core import setup, Extension - -ssl = Extension('_forge_ssl', - sources = ['forge/_ssl.c']) - -setup (name = 'Forge SSL', - version = '1.0', - description = 'Python SSL with session cache support.', - ext_modules = [ssl], - py_modules = ['forge.ssl']) diff --git a/alarm/node_modules/node-forge/tests/form.html b/alarm/node_modules/node-forge/tests/form.html deleted file mode 100644 index cfe9f94..0000000 --- a/alarm/node_modules/node-forge/tests/form.html +++ /dev/null @@ -1,150 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" - "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> - <head> - <title>Forge Form Test</title> - <link type="text/css" rel="stylesheet" media="all" href="screen.css" /> - <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script> - <script type="text/javascript" src="forge/debug.js"></script> - <script type="text/javascript" src="forge/util.js"></script> - <script type="text/javascript" src="forge/log.js"></script> - <script type="text/javascript" src="forge/form.js"></script> - <script type="text/javascript" src="form.js"></script> - - <link type="text/css" rel="stylesheet" media="all" href="screen.css" /> - </head> -<body> -<div class="nav"><a href="index.html">Forge Tests</a> / Form</div> - -<div class="header"> - <h1>Form Tests</h1> -</div> - -<div class="content"> - -<form id="form-1" class="ajax standard" method="post" action=""> - <fieldset> - <legend>Text</legend> - - <p> - <input name="text1" type="text" value="value1" /> - <input name="text2.sub1" type="text" value="value2" /> - <input name="text2.sub2[]" type="text" value="value3" /> - <input name="text2.sub2[]" type="text" value="value4" /> - <input name="text2.sub3[0]" type="text" value="value5" /> - <input name="text2.sub4[0][0]" type="text" value="value6" /> - <input name="text2.sub4[0][]" type="text" value="value7" /> - <input name="text2.sub5[foo][]" type="text" value="value8" /> - <input name="text2.sub5[dotted.name]" type="text" value="value9" /> - <input name="text2.sub6[]" type="text" value="value10" /> - <input name="text2.sub7[].@" type="text" value="value11" /> - <input name="text2.sub7[].@" type="text" value="value12" /> - <input name="text2.sub8[][].@" type="text" value="value13" /> - </p> - - <p> - <label>username <input name="username" type="text" value="username" /></label> - <label>password <input name="password" type="password" value="password" /></label> - </p> - - <p> - <label>password1.1 <input name="password1" type="password" value="password" /></label> - <label>password1.2 <input name="password1" type="password" value="password" /></label> - </p> - </fieldset> - - <fieldset> - <legend>Checkbox</legend> - - <p> - <label><input name="checkbox1" type="checkbox" value="c1" /> C1</label> - <label><input name="checkbox1" type="checkbox" value="c2" /> C1</label> - <label><input name="checkbox1" type="checkbox" value="c3" /> C1</label> - </p> - - <p> - <label><input name="checkbox2[]" type="checkbox" value="c1" /> C2[]</label> - <label><input name="checkbox2[]" type="checkbox" value="c2" /> C2[]</label> - <label><input name="checkbox2[3]" type="checkbox" value="c3" /> C2[3]</label> - <label><input name="checkbox2[]" type="checkbox" value="c4" /> C2[]</label> - <label><input name="checkbox2.sub1" type="checkbox" value="c4" /> C2.sub1</label> - </p> - - <p> - <label><input name="checkbox3.sub1" type="checkbox" value="c1" /> C3.s1</label> - <label><input name="checkbox3.sub2" type="checkbox" value="c2" /> C3.s2</label> - <label><input name="checkbox3.sub2" type="checkbox" value="c3" /> C3.s2</label> - <label><input name="checkbox3[]" type="checkbox" value="c4" /> C3[]</label> - </p> - </fieldset> - - <fieldset> - <legend>Radio</legend> - - <p> - <label><input name="radio1" type="radio" value="r1" /> R1</label> - <label><input name="radio1" type="radio" value="r2" /> R1</label> - <label><input name="radio1" type="radio" value="r3" /> R1</label> - <label><input name="radio1" type="radio" value="r4" /> R1</label> - </p> - - <p> - <label><input name="radio2.sub1" type="radio" value="r1" /> R2.s1</label> - <label><input name="radio2.sub1" type="radio" value="r2" /> R2.s1</label> - <label><input name="radio2.sub2" type="radio" value="r3" /> R2.s2</label> - <label><input name="radio2.sub2" type="radio" value="r4" /> R2.s2</label> - </p> - </fieldset> - - <fieldset> - <legend>Select</legend> - <p> - <select name="select1"> - <option value="select1">Select 1</option> - <option value="select2">Select 2</option> - <option value="select3">Select 3</option> - </select> - </p> - - <p> - <select name="select2" multiple="multiple"> - <option value="select1">Select 1</option> - <option value="select2">Select 2</option> - <option value="select3">Select 3</option> - </select> - </p> - </fieldset> - - <fieldset> - <legend>Text Area</legend> - - <textarea name="textarea">Test text.</textarea> - </fieldset> - - <fieldset> - <legend>Buttons</legend> - - <p> - <button name="button1" type="submit" value="submit">Submit Form</button> - <button name="button2" type="reset" value="reset">Reset Form</button> - </p> - </fieldset> - - <fieldset> - <legend>Input Buttons</legend> - - <p> - <input name="submit" type="submit" value="Submit Form" /> - <input name="reset" type="reset" value="Reset Form" /> - </p> - </fieldset> -</form> - -<p>Result:</p> -<div id="result"></div> - -</div> - -</body> -</html> diff --git a/alarm/node_modules/node-forge/tests/form.js b/alarm/node_modules/node-forge/tests/form.js deleted file mode 100644 index abfbab0..0000000 --- a/alarm/node_modules/node-forge/tests/form.js +++ /dev/null @@ -1,40 +0,0 @@ -/** - * Forge Form Tests - * - * @author Dave Longley - * - * Copyright (c) 2011 Digital Bazaar, Inc. All rights reserved. - */ -(function($) { -$(document).ready(function() -{ - // logging category - var cat = 'forge.tests.form'; - - // local alias - var forge = window.forge; - - $('form.ajax').each(function(i, form) - { - $(form).submit(function() - { - try - { - var f = forge.form.serialize($(this)); - forge.log.debug(cat, 'result:', JSON.stringify(f)); - $('#result').html(JSON.stringify(f)); - - /* dictionary test - var f = forge.form.serialize($(this), '.', {'username':'user'}); - forge.log.debug(cat, 'result:', JSON.stringify(f)); - */ - } - catch(e) - { - console.log('exception', e.stack); - } - return false; - }); - }); -}); -})(jQuery); diff --git a/alarm/node_modules/node-forge/tests/heartbleed.js b/alarm/node_modules/node-forge/tests/heartbleed.js deleted file mode 100644 index b38869a..0000000 --- a/alarm/node_modules/node-forge/tests/heartbleed.js +++ /dev/null @@ -1,55 +0,0 @@ -var forge = require('../js/forge'); -var net = require('net'); - -var socket = new net.Socket(); - -var client = forge.tls.createConnection({ - server: false, - verify: function(connection, verified, depth, certs) { - // skip verification for testing - return true; - }, - connected: function(connection) { - // heartbleeds 2k - console.log('[tls] connected'); - connection.prepareHeartbeatRequest('', 2048); - setTimeout(function() { - client.close(); - }, 1000); - }, - tlsDataReady: function(connection) { - // encrypted data is ready to be sent to the server - var data = connection.tlsData.getBytes(); - socket.write(data, 'binary'); - }, - dataReady: function(connection) { - // clear data from the server is ready - var data = connection.data.getBytes(); - console.log('[tls] received from the server: ' + data); - }, - heartbeatReceived: function(c, payload) { - console.log('Heartbleed:\n' + payload.toHex()); - client.close(); - }, - closed: function() { - console.log('[tls] disconnected'); - socket.end(); - }, - error: function(connection, error) { - console.log('[tls] error', error); - } -}); - -socket.on('connect', function() { - console.log('[socket] connected'); - client.handshake(); -}); -socket.on('data', function(data) { - client.process(data.toString('binary')); -}); -socket.on('end', function() { - console.log('[socket] disconnected'); -}); - -// connect -socket.connect(443, 'yahoo.com'); diff --git a/alarm/node_modules/node-forge/tests/http.html b/alarm/node_modules/node-forge/tests/http.html deleted file mode 100644 index 3bdf941..0000000 --- a/alarm/node_modules/node-forge/tests/http.html +++ /dev/null @@ -1,229 +0,0 @@ -<html> - <head> - <link type="text/css" rel="stylesheet" media="all" href="screen.css" /> - <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js"></script> - <script type="text/javascript" src="forge/util.js"></script> - <script type="text/javascript" src="forge/socket.js"></script> - <script type="text/javascript" src="forge/http.js"></script> - <script type="text/javascript" src="forge/log.js"></script> - - <script type="text/javascript"> - //<![CDATA[ - // logging category - var cat = 'forge.tests.http'; - - window.forge.socketPool = - { - ready: function() - { - forge.log.debug(cat, 'SocketPool ready.'); - } - }; - - swfobject.embedSWF( - 'forge/SocketPool.swf', 'socketPool', '0', '0', '9.0.0', - false, {}, {allowscriptaccess: 'always'}, {}); - - // local aliases - var net = window.forge.net; - var http = window.forge.http; - var util = window.forge.util; - - var client; - - function client_init() - { - try - { - var sp = net.createSocketPool({ - flashId: 'socketPool', - policyPort: 19945, - msie: false - }); - client = http.createClient({ - //url: 'http://' + window.location.host, - socketPool: sp, - connections: 10 - }); - - document.getElementById('feedback').innerHTML = - 'HTTP client created'; - } - catch(ex) - { - forge.log.error(cat, ex); - } - return false; - } - - function client_cleanup() - { - var sp = client.socketPool; - client.destroy(); - sp.destroy(); - document.getElementById('feedback').innerHTML = - 'HTTP client cleaned up'; - return false; - } - - function client_send() - { - var request = http.createRequest({ - method: 'GET', - path: '/' - //body: 'echo=foo', - //headers: [{'Content-Type': 'application/x-www-form-urlencoded'}] - }); - - client.send({ - request: request, - connected: function(e) - { - forge.log.debug(cat, 'connected', e); - }, - headerReady: function(e) - { - forge.log.debug(cat, 'header ready', e); - }, - bodyReady: function(e) - { - forge.log.debug(cat, 'body ready', e); - }, - error: function(e) - { - forge.log.error(cat, 'error', e); - } - }); - document.getElementById('feedback').innerHTML = - 'HTTP request sent'; - return false; - } - - function client_send_10() - { - for(var i = 0; i < 10; ++i) - { - client_send(); - } - return false; - } - - function client_stress() - { - for(var i = 0; i < 10; ++i) - { - setTimeout(function() - { - for(var i = 0; i < 10; ++i) - { - client_send(); - } - }, 0); - } - return false; - } - - function client_cookies() - { - var cookie = - { - name: 'test-cookie', - value: 'test-value', - maxAge: -1, - secure: false, - path: '/' - }; - client.setCookie(cookie); - forge.log.debug(cat, 'cookie', client.getCookie('test-cookie')); - } - - function client_clear_cookies() - { - client.clearCookies(); - } - - function request_add_cookies() - { - var cookie1 = - { - name: 'test-cookie1', - value: 'test-value1', - maxAge: -1, - secure: false, - path: '/' - }; - var cookie2 = - { - name: 'test-cookie2', - value: 'test-value2', - maxAge: -1, - secure: false, - path: '/' - }; - var request = http.createRequest({ - method: 'GET', - path: '/' - }); - request.addCookie(cookie1); - request.addCookie(cookie2); - forge.log.debug(cat, 'request', request.toString()); - } - - function response_get_cookies() - { - var response = http.createResponse(); - response.appendField('Set-Cookie', - 'test-cookie1=test-value1; max-age=0; path=/; secure'); - response.appendField('Set-Cookie', - 'test-cookie2=test-value2; ' + - 'expires=Thu, 21-Aug-2008 23:47:25 GMT; path=/'); - var cookies = response.getCookies(); - forge.log.debug(cat, 'cookies', cookies); - } - - //]]> - </script> - </head> - <body> - <div class="nav"><a href="index.html">Forge Tests</a> / HTTP</div> - - <div class="header"> - <h1>HTTP Test</h1> - </div> - - <div class="content"> - - <div id="socketPool"> - <p>Could not load the flash SocketPool.</p> - </div> - - <fieldset class="section"> - <ul> - <li>Use the controls below to test the HTTP client.</li> - <li>You currently need a JavaScript console to view the output.</li> - </ul> - </fieldset> - - <fieldset class="section"> - <legend>Controls</legend> - <button id="init" onclick="javascript:return client_init();">init</button> - <button id="cleanup" onclick="javascript:return client_cleanup();">cleanup</button> - <button id="send" onclick="javascript:return client_send();">send</button> - <button id="send10" onclick="javascript:return client_send_10();">send 10</button> - <button id="stress" onclick="javascript:return client_stress();">stress</button> - <button id="client_cookies" onclick="javascript:return client_cookies();">cookies</button> - <button id="clear_cookies" onclick="javascript:return client_clear_cookies();">clear cookies</button> - <button id="add_cookies" onclick="javascript:return request_add_cookies();">add cookies</button> - <button id="get_cookies" onclick="javascript:return response_get_cookies();">get cookies</button> - </fieldset> - - <fieldset class="section"> - <legend>Feedback</legend> - <p>Feedback from the flash SocketPool:</p> - <div id="feedback"> - None - </div> - - </div> - </body> -</html> diff --git a/alarm/node_modules/node-forge/tests/index.html b/alarm/node_modules/node-forge/tests/index.html deleted file mode 100644 index 2e27c8a..0000000 --- a/alarm/node_modules/node-forge/tests/index.html +++ /dev/null @@ -1,64 +0,0 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" - "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> - -<html xmlns="http://www.w3.org/1999/xhtml"> -<head> - <meta name="author" content="Digital Bazaar, Inc.; http://digitalbazaar.com/" /> - <meta name="description" content="Forge Tests" /> - <link type="text/css" rel="stylesheet" media="all" href="screen.css" /> - <title>Forge Tests</title> -</head> - -<body> - <div class="header"> - <h1>Forge Tests</h1> - </div> - <div class="content"> - <fieldset class="section"> - <ul> - <li>These are various tests of the Forge JavaScript libraries.</li> - <li>Please see the code and documentation for details.</li> - </ul> - </fieldset> - <fieldset class="section"> - <legend>Tests</legend> - <ul> - <li><a href="common.html">Common</a> - <sup>1,2</sup> - </li> - <li><a href="form.html">Form</a> - <sup>1,2</sup> - </li> - <li><a href="performance.html">Performance</a> - <sup>1,2</sup> - </li> - <li><a href="tasks.html">Tasks</a> - <sup>1,2</sup> - </li> - <li><a href="socketPool.html">SocketPool</a> - <sup>1</sup> - </li> - <li><a href="http.html">HTTP</a> - <sup>1</sup> - </li> - <li><a href="tls.html">TLS</a> - <sup>2</sup> - </li> - <li><a href="xhr.html">XHR</a> - <sup>1,2</sup> - </li> - <li><a href="webid.html">Web ID</a> - <sup>1,2</sup> - </li> - </ul> - <div> - <span><sup>1</sup>: Test works over HTTP</span><br/> - <span><sup>2</sup>: Test works over HTTPS</span> - </div> - </fieldset> - </div> - <div class="footer"> - Copyright © 2010 <a href="http://digitalbazaar.com/">Digital Bazaar, Inc.</a> - </div> -</body> -</html> diff --git a/alarm/node_modules/node-forge/tests/keygen.html b/alarm/node_modules/node-forge/tests/keygen.html deleted file mode 100644 index 22e2432..0000000 --- a/alarm/node_modules/node-forge/tests/keygen.html +++ /dev/null @@ -1,56 +0,0 @@ -<!DOCTYPE html> -<html lang="en"> -<head> - <meta charset="utf-8" /> - <script type="text/javascript" src="forge/util.js"></script> - <script type="text/javascript" src="forge/sha256.js"></script> - <script type="text/javascript" src="forge/cipher.js"></script> - <script type="text/javascript" src="forge/cipherModes.js"></script> - <script type="text/javascript" src="forge/aes.js"></script> - <script type="text/javascript" src="forge/prng.js"></script> - <script type="text/javascript" src="forge/random.js"></script> - <script type="text/javascript" src="forge/jsbn.js"></script> - <script type="text/javascript" src="forge/asn1.js"></script> - <script type="text/javascript" src="forge/pem.js"></script> - <script type="text/javascript" src="forge/rsa.js"></script> -</head> - -<body> - -<script type="text/javascript"> - -function async() { - var bits = 2048; - console.log('Generating ' + bits + '-bit key-pair...'); - var st = +new Date(); - forge.pki.rsa.generateKeyPair({ - bits: bits, - workers: -1, - /*workLoad: 100,*/ - workerScript: 'forge/prime.worker.js' - }, function(err, keypair) { - var et = +new Date(); - console.log('Key-pair created in ' + (et - st) + 'ms.'); - //console.log('private', forge.pki.privateKeyToPem(keypair.privateKey)); - //console.log('public', forge.pki.publicKeyToPem(keypair.publicKey)); - }); -} - -function sync() { - var bits = 2048; - console.log('Generating ' + bits + '-bit key-pair...'); - var st = +new Date(); - var keypair = forge.pki.rsa.generateKeyPair(bits); - var et = +new Date(); - console.log('Key-pair created in ' + (et - st) + 'ms.'); - //console.log('private', forge.pki.privateKeyToPem(keypair.privateKey)); - //console.log('public', forge.pki.publicKeyToPem(keypair.publicKey)); -} - -async(); -//sync(); - -</script> - -</body> -</html> diff --git a/alarm/node_modules/node-forge/tests/login.css b/alarm/node_modules/node-forge/tests/login.css deleted file mode 100644 index 3a1cb05..0000000 --- a/alarm/node_modules/node-forge/tests/login.css +++ /dev/null @@ -1,26 +0,0 @@ -/* WebID CSS */ - -* { -margin: 0; -padding: 0; -} - -p { -margin: 10px 0; -} - -body { -margin: 10px; -font-family: helvetica,arial,sans-serif; -font-size: 14px; -} - -#header { -padding: 5px; -background-color: #ddf; -border: 2px solid #000; -} - -#header h1 { -font-size: 20px; -} diff --git a/alarm/node_modules/node-forge/tests/loginDemo.html b/alarm/node_modules/node-forge/tests/loginDemo.html deleted file mode 100644 index a1aecd4..0000000 --- a/alarm/node_modules/node-forge/tests/loginDemo.html +++ /dev/null @@ -1,56 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" - "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> - <head> - <title>Web ID Login</title> - <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js"></script> - <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script> - <script type="text/javascript" src="forge/debug.js"></script> - <script type="text/javascript" src="forge/util.js"></script> - <script type="text/javascript" src="forge/log.js"></script> - <script type="text/javascript" src="forge/task.js"></script> - <script type="text/javascript" src="forge/socket.js"></script> - <script type="text/javascript" src="forge/md5.js"></script> - <script type="text/javascript" src="forge/sha1.js"></script> - <script type="text/javascript" src="forge/hmac.js"></script> - <script type="text/javascript" src="forge/aes.js"></script> - <script type="text/javascript" src="forge/pem.js"></script> - <script type="text/javascript" src="forge/asn1.js"></script> - <script type="text/javascript" src="forge/jsbn.js"></script> - <script type="text/javascript" src="forge/prng.js"></script> - <script type="text/javascript" src="forge/random.js"></script> - <script type="text/javascript" src="forge/oids.js"></script> - <script type="text/javascript" src="forge/rsa.js"></script> - <script type="text/javascript" src="forge/pbe.js"></script> - <script type="text/javascript" src="forge/x509.js"></script> - <script type="text/javascript" src="forge/pki.js"></script> - <script type="text/javascript" src="forge/tls.js"></script> - <script type="text/javascript" src="forge/aesCipherSuites.js"></script> - <script type="text/javascript" src="forge/http.js"></script> - <script type="text/javascript" src="forge/xhr.js"></script> - <script type="text/javascript" src="loginDemo.js"></script> - - <link type="text/css" rel="stylesheet" media="all" href="login.css" /> - </head> -<body> - -<div id="header"> - <h1>Web ID Login</h1> -</div> - -<div id="content"> - <p>Please select a Web ID to log in to <span id="domain">this website</span>.</p> - - <div id="webids"></div> - - <p>Do not select an identity if you do not trust this website.</p> - - <!-- div used to hold the flash socket pool implementation --> - <div id="socketPool"> - <p>Could not load the flash SocketPool.</p> - </div> -</div> - -</body> -</html> diff --git a/alarm/node_modules/node-forge/tests/loginDemo.js b/alarm/node_modules/node-forge/tests/loginDemo.js deleted file mode 100644 index 859e1f0..0000000 --- a/alarm/node_modules/node-forge/tests/loginDemo.js +++ /dev/null @@ -1,149 +0,0 @@ -/** - * Forge Web ID Tests - * - * @author Dave Longley - * - * Copyright (c) 2010 Digital Bazaar, Inc. All rights reserved. - */ -(function($) -{ - // load flash socket pool - window.forge.socketPool = {}; - window.forge.socketPool.ready = function() - { - // init page - init($); - }; - swfobject.embedSWF( - 'forge/SocketPool.swf', 'socketPool', '0', '0', '9.0.0', - false, {}, {allowscriptaccess: 'always'}, {}); -})(jQuery); - -var init = function($) -{ - // logging category - var cat = 'forge.tests.loginDemo'; - - // local alias - var forge = window.forge; - try - { - // get query variables - var query = forge.util.getQueryVariables(); - var domain = query.domain || ''; - var auth = query.auth || ''; - var redirect = query.redirect || ''; - var pport = query.pport || 843; - redirect = 'https://' + domain + '/' + redirect; - if(domain) - { - $('#domain').html('`' + domain + '`'); - } - - // for chosen webid - var chosen = null; - - // init forge xhr - forge.xhr.init({ - flashId: 'socketPool', - msie: $.browser.msie, - url: 'https://' + domain, - policyPort: pport, - connections: 1, - caCerts: [], - verify: function(c, verified, depth, certs) - { - // don't care about cert verification for test - return true; - }, - getCertificate: function(c) - { - forge.log.debug(cat, 'using cert', chosen.certificate); - return chosen.certificate; - }, - getPrivateKey: function(c) - { - //forge.log.debug(cat, 'using private key', chosen.privateKey); - return chosen.privateKey; - } - }); - - // get flash API - var flashApi = document.getElementById('socketPool'); - - // get web ids collection - var webids = forge.util.getItem( - flashApi, 'forge.test.webid', 'webids'); - webids = webids || {}; - - var id = 0; - var list = $('<ul/>'); - for(var key in webids) - { - (function(webid) - { - var cert = forge.pki.certificateFromPem(webid.certificate); - var item = $('<li/>'); - var button = $('<button>'); - button.attr('id', '' + (webid + id++)); - button.html('Choose'); - button.click(function() - { - button.attr('disabled', 'disabled'); - - // set chosen webid - chosen = webid; - - // do webid call - $.ajax( - { - type: 'GET', - url: '/' + auth, - success: function(data, textStatus, xhr) - { - if(data !== '') - { - forge.log.debug(cat, 'authentication completed'); - forge.log.debug(cat, data); - window.name = data; - } - else - { - forge.log.debug(cat, 'authentication failed'); - window.name = ''; - } - window.location = redirect; - }, - error: function(xhr, textStatus, errorThrown) - { - forge.log.error(cat, 'authentication failed'); - }, - xhr: forge.xhr.create - }); - }); - item.append(button); - item.append(' ' + key + '<br/>'); - - // display certificate attributes - var attr; - for(var n = 0; n < cert.subject.attributes.length; ++n) - { - attr = cert.subject.attributes[n]; - item.append(attr.name + ': ' + attr.value + '<br/>'); - } - - list.append(item); - })(webids[key]); - } - if(list.html() === '<ul/>') - { - list.append('None'); - } - - $('#webids').append(list); - } - catch(ex) - { - forge.log.error(cat, ex); - } -}; diff --git a/alarm/node_modules/node-forge/tests/nodejs-create-cert.js b/alarm/node_modules/node-forge/tests/nodejs-create-cert.js deleted file mode 100644 index d1666eb..0000000 --- a/alarm/node_modules/node-forge/tests/nodejs-create-cert.js +++ /dev/null @@ -1,110 +0,0 @@ -var forge = require('../js/forge'); - -console.log('Generating 1024-bit key-pair...'); -var keys = forge.pki.rsa.generateKeyPair(1024); -console.log('Key-pair created.'); - -console.log('Creating self-signed certificate...'); -var cert = forge.pki.createCertificate(); -cert.publicKey = keys.publicKey; -cert.serialNumber = '01'; -cert.validity.notBefore = new Date(); -cert.validity.notAfter = new Date(); -cert.validity.notAfter.setFullYear(cert.validity.notBefore.getFullYear() + 1); -var attrs = [{ - name: 'commonName', - value: 'example.org' -}, { - name: 'countryName', - value: 'US' -}, { - shortName: 'ST', - value: 'Virginia' -}, { - name: 'localityName', - value: 'Blacksburg' -}, { - name: 'organizationName', - value: 'Test' -}, { - shortName: 'OU', - value: 'Test' -}]; -cert.setSubject(attrs); -cert.setIssuer(attrs); -cert.setExtensions([{ - name: 'basicConstraints', - cA: true/*, - pathLenConstraint: 4*/ -}, { - name: 'keyUsage', - keyCertSign: true, - digitalSignature: true, - nonRepudiation: true, - keyEncipherment: true, - dataEncipherment: true -}, { - name: 'extKeyUsage', - serverAuth: true, - clientAuth: true, - codeSigning: true, - emailProtection: true, - timeStamping: true -}, { - name: 'nsCertType', - client: true, - server: true, - email: true, - objsign: true, - sslCA: true, - emailCA: true, - objCA: true -}, { - name: 'subjectAltName', - altNames: [{ - type: 6, // URI - value: 'http://example.org/webid#me' - }, { - type: 7, // IP - ip: '127.0.0.1' - }] -}, { - name: 'subjectKeyIdentifier' -}]); -// FIXME: add authorityKeyIdentifier extension - -// self-sign certificate -cert.sign(keys.privateKey/*, forge.md.sha256.create()*/); -console.log('Certificate created.'); - -// PEM-format keys and cert -var pem = { - privateKey: forge.pki.privateKeyToPem(keys.privateKey), - publicKey: forge.pki.publicKeyToPem(keys.publicKey), - certificate: forge.pki.certificateToPem(cert) -}; - -console.log('\nKey-Pair:'); -console.log(pem.privateKey); -console.log(pem.publicKey); - -console.log('\nCertificate:'); -console.log(pem.certificate); - -// verify certificate -var caStore = forge.pki.createCaStore(); -caStore.addCertificate(cert); -try { - forge.pki.verifyCertificateChain(caStore, [cert], - function(vfd, depth, chain) { - if(vfd === true) { - console.log('SubjectKeyIdentifier verified: ' + - cert.verifySubjectKeyIdentifier()); - console.log('Certificate verified.'); - } - return true; - }); -} catch(ex) { - console.log('Certificate verification failure: ' + - JSON.stringify(ex, null, 2)); -} diff --git a/alarm/node_modules/node-forge/tests/nodejs-create-csr.js b/alarm/node_modules/node-forge/tests/nodejs-create-csr.js deleted file mode 100644 index 1cb335f..0000000 --- a/alarm/node_modules/node-forge/tests/nodejs-create-csr.js +++ /dev/null @@ -1,66 +0,0 @@ -var forge = require('../js/forge'); - -console.log('Generating 1024-bit key-pair...'); -var keys = forge.pki.rsa.generateKeyPair(1024); -console.log('Key-pair created.'); - -console.log('Creating certification request (CSR) ...'); -var csr = forge.pki.createCertificationRequest(); -csr.publicKey = keys.publicKey; -csr.setSubject([{ - name: 'commonName', - value: 'example.org' -}, { - name: 'countryName', - value: 'US' -}, { - shortName: 'ST', - value: 'Virginia' -}, { - name: 'localityName', - value: 'Blacksburg' -}, { - name: 'organizationName', - value: 'Test' -}, { - shortName: 'OU', - value: 'Test' -}]); -// add optional attributes -csr.setAttributes([{ - name: 'challengePassword', - value: 'password' -}, { - name: 'unstructuredName', - value: 'My company' -}]); - -// sign certification request -csr.sign(keys.privateKey/*, forge.md.sha256.create()*/); -console.log('Certification request (CSR) created.'); - -// PEM-format keys and csr -var pem = { - privateKey: forge.pki.privateKeyToPem(keys.privateKey), - publicKey: forge.pki.publicKeyToPem(keys.publicKey), - csr: forge.pki.certificationRequestToPem(csr) -}; - -console.log('\nKey-Pair:'); -console.log(pem.privateKey); -console.log(pem.publicKey); - -console.log('\nCertification Request (CSR):'); -console.log(pem.csr); - -// verify certification request -try { - if(csr.verify()) { - console.log('Certification request (CSR) verified.'); - } else { - throw new Error('Signature not verified.'); - } -} catch(err) { - console.log('Certification request (CSR) verification failure: ' + - JSON.stringify(err, null, 2)); -} diff --git a/alarm/node_modules/node-forge/tests/nodejs-create-pkcs12.js b/alarm/node_modules/node-forge/tests/nodejs-create-pkcs12.js deleted file mode 100644 index e52eefa..0000000 --- a/alarm/node_modules/node-forge/tests/nodejs-create-pkcs12.js +++ /dev/null @@ -1,160 +0,0 @@ -var forge = require('../js/forge'); - -try { - // generate a keypair - console.log('Generating 1024-bit key-pair...'); - var keys = forge.pki.rsa.generateKeyPair(1024); - console.log('Key-pair created.'); - - // create a certificate - console.log('Creating self-signed certificate...'); - var cert = forge.pki.createCertificate(); - cert.publicKey = keys.publicKey; - cert.serialNumber = '01'; - cert.validity.notBefore = new Date(); - cert.validity.notAfter = new Date(); - cert.validity.notAfter.setFullYear(cert.validity.notBefore.getFullYear() + 1); - var attrs = [{ - name: 'commonName', - value: 'example.org' - }, { - name: 'countryName', - value: 'US' - }, { - shortName: 'ST', - value: 'Virginia' - }, { - name: 'localityName', - value: 'Blacksburg' - }, { - name: 'organizationName', - value: 'Test' - }, { - shortName: 'OU', - value: 'Test' - }]; - cert.setSubject(attrs); - cert.setIssuer(attrs); - cert.setExtensions([{ - name: 'basicConstraints', - cA: true - }, { - name: 'keyUsage', - keyCertSign: true, - digitalSignature: true, - nonRepudiation: true, - keyEncipherment: true, - dataEncipherment: true - }, { - name: 'subjectAltName', - altNames: [{ - type: 6, // URI - value: 'http://example.org/webid#me' - }] - }]); - - // self-sign certificate - cert.sign(keys.privateKey); - console.log('Certificate created.'); - - // create PKCS12 - console.log('\nCreating PKCS#12...'); - var password = 'password'; - var newPkcs12Asn1 = forge.pkcs12.toPkcs12Asn1( - keys.privateKey, [cert], password, - {generateLocalKeyId: true, friendlyName: 'test'}); - var newPkcs12Der = forge.asn1.toDer(newPkcs12Asn1).getBytes(); - - console.log('\nBase64-encoded new PKCS#12:'); - console.log(forge.util.encode64(newPkcs12Der)); - - // create CA store (w/own certificate in this example) - var caStore = forge.pki.createCaStore([cert]); - - console.log('\nLoading new PKCS#12 to confirm...'); - loadPkcs12(newPkcs12Der, password, caStore); -} catch(ex) { - if(ex.stack) { - console.log(ex.stack); - } else { - console.log('Error', ex); - } -} - -function loadPkcs12(pkcs12Der, password, caStore) { - var pkcs12Asn1 = forge.asn1.fromDer(pkcs12Der); - var pkcs12 = forge.pkcs12.pkcs12FromAsn1(pkcs12Asn1, false, password); - - // load keypair and cert chain from safe content(s) and map to key ID - var map = {}; - for(var sci = 0; sci < pkcs12.safeContents.length; ++sci) { - var safeContents = pkcs12.safeContents[sci]; - console.log('safeContents ' + (sci + 1)); - - for(var sbi = 0; sbi < safeContents.safeBags.length; ++sbi) { - var safeBag = safeContents.safeBags[sbi]; - console.log('safeBag.type: ' + safeBag.type); - - var localKeyId = null; - if(safeBag.attributes.localKeyId) { - localKeyId = forge.util.bytesToHex( - safeBag.attributes.localKeyId[0]); - console.log('localKeyId: ' + localKeyId); - if(!(localKeyId in map)) { - map[localKeyId] = { - privateKey: null, - certChain: [] - }; - } - } else { - // no local key ID, skip bag - continue; - } - - // this bag has a private key - if(safeBag.type === forge.pki.oids.pkcs8ShroudedKeyBag) { - console.log('found private key'); - map[localKeyId].privateKey = safeBag.key; - } else if(safeBag.type === forge.pki.oids.certBag) { - // this bag has a certificate - console.log('found certificate'); - map[localKeyId].certChain.push(safeBag.cert); - } - } - } - - console.log('\nPKCS#12 Info:'); - - for(var localKeyId in map) { - var entry = map[localKeyId]; - console.log('\nLocal Key ID: ' + localKeyId); - if(entry.privateKey) { - var privateKeyP12Pem = forge.pki.privateKeyToPem(entry.privateKey); - var encryptedPrivateKeyP12Pem = forge.pki.encryptRsaPrivateKey( - entry.privateKey, password); - - console.log('\nPrivate Key:'); - console.log(privateKeyP12Pem); - console.log('Encrypted Private Key (password: "' + password + '"):'); - console.log(encryptedPrivateKeyP12Pem); - } else { - console.log(''); - } - if(entry.certChain.length > 0) { - console.log('Certificate chain:'); - var certChain = entry.certChain; - for(var i = 0; i < certChain.length; ++i) { - var certP12Pem = forge.pki.certificateToPem(certChain[i]); - console.log(certP12Pem); - } - - var chainVerified = false; - try { - chainVerified = forge.pki.verifyCertificateChain(caStore, certChain); - } catch(ex) { - chainVerified = ex; - } - console.log('Certificate chain verified: ', chainVerified); - } - } -} diff --git a/alarm/node_modules/node-forge/tests/nodejs-imap.js b/alarm/node_modules/node-forge/tests/nodejs-imap.js deleted file mode 100644 index ba024ef..0000000 --- a/alarm/node_modules/node-forge/tests/nodejs-imap.js +++ /dev/null @@ -1,46 +0,0 @@ -var forge = require('../js/forge'); -var net = require('net'); - -var socket = new net.Socket(); - -var client = forge.tls.createConnection({ - server: false, - verify: function(connection, verified, depth, certs) { - // skip verification for testing - return true; - }, - connected: function(connection) { - console.log('[tls] connected'); - }, - tlsDataReady: function(connection) { - // encrypted data is ready to be sent to the server - var data = connection.tlsData.getBytes(); - socket.write(data, 'binary'); - }, - dataReady: function(connection) { - // clear data from the server is ready - var data = connection.data.getBytes(); - console.log('[tls] received from the server: ' + data); - client.close(); - }, - closed: function() { - console.log('[tls] disconnected'); - }, - error: function(connection, error) { - console.log('[tls] error', error); - } -}); - -socket.on('connect', function() { - console.log('[socket] connected'); - client.handshake(); -}); -socket.on('data', function(data) { - client.process(data.toString('binary')); -}); -socket.on('end', function() { - console.log('[socket] disconnected'); -}); - -// connect to gmail's imap server -socket.connect(993, 'imap.gmail.com'); diff --git a/alarm/node_modules/node-forge/tests/nodejs-tls.js b/alarm/node_modules/node-forge/tests/nodejs-tls.js deleted file mode 100644 index 5be6acd..0000000 --- a/alarm/node_modules/node-forge/tests/nodejs-tls.js +++ /dev/null @@ -1,189 +0,0 @@ -var forge = require('../js/forge'); - -// function to create certificate -var createCert = function(cn, data) { - console.log( - 'Generating 512-bit key-pair and certificate for \"' + cn + '\".'); - var keys = forge.pki.rsa.generateKeyPair(512); - console.log('key-pair created.'); - - var cert = forge.pki.createCertificate(); - cert.serialNumber = '01'; - cert.validity.notBefore = new Date(); - cert.validity.notAfter = new Date(); - cert.validity.notAfter.setFullYear( - cert.validity.notBefore.getFullYear() + 1); - var attrs = [{ - name: 'commonName', - value: cn - }, { - name: 'countryName', - value: 'US' - }, { - shortName: 'ST', - value: 'Virginia' - }, { - name: 'localityName', - value: 'Blacksburg' - }, { - name: 'organizationName', - value: 'Test' - }, { - shortName: 'OU', - value: 'Test' - }]; - cert.setSubject(attrs); - cert.setIssuer(attrs); - cert.setExtensions([{ - name: 'basicConstraints', - cA: true - }, { - name: 'keyUsage', - keyCertSign: true, - digitalSignature: true, - nonRepudiation: true, - keyEncipherment: true, - dataEncipherment: true - }, { - name: 'subjectAltName', - altNames: [{ - type: 6, // URI - value: 'http://myuri.com/webid#me' - }] - }]); - // FIXME: add subjectKeyIdentifier extension - // FIXME: add authorityKeyIdentifier extension - cert.publicKey = keys.publicKey; - - // self-sign certificate - cert.sign(keys.privateKey); - - // save data - data[cn] = { - cert: forge.pki.certificateToPem(cert), - privateKey: forge.pki.privateKeyToPem(keys.privateKey) - }; - - console.log('certificate created for \"' + cn + '\": \n' + data[cn].cert); -}; - -var end = {}; -var data = {}; - -// create certificate for server and client -createCert('server', data); -createCert('client', data); - -var success = false; - -// create TLS client -end.client = forge.tls.createConnection({ - server: false, - caStore: [data.server.cert], - sessionCache: {}, - // supported cipher suites in order of preference - cipherSuites: [ - forge.tls.CipherSuites.TLS_RSA_WITH_AES_128_CBC_SHA, - forge.tls.CipherSuites.TLS_RSA_WITH_AES_256_CBC_SHA], - virtualHost: 'server', - verify: function(c, verified, depth, certs) { - console.log( - 'TLS Client verifying certificate w/CN: \"' + - certs[0].subject.getField('CN').value + - '\", verified: ' + verified + '...'); - return verified; - }, - connected: function(c) { - console.log('Client connected...'); - - // send message to server - setTimeout(function() { - c.prepareHeartbeatRequest('heartbeat'); - c.prepare('Hello Server'); - }, 1); - }, - getCertificate: function(c, hint) { - console.log('Client getting certificate ...'); - return data.client.cert; - }, - getPrivateKey: function(c, cert) { - return data.client.privateKey; - }, - tlsDataReady: function(c) { - // send TLS data to server - end.server.process(c.tlsData.getBytes()); - }, - dataReady: function(c) { - var response = c.data.getBytes(); - console.log('Client received \"' + response + '\"'); - success = (response === 'Hello Client'); - c.close(); - }, - heartbeatReceived: function(c, payload) { - console.log('Client received heartbeat: ' + payload.getBytes()); - }, - closed: function(c) { - console.log('Client disconnected.'); - if(success) { - console.log('PASS'); - } else { - console.log('FAIL'); - } - }, - error: function(c, error) { - console.log('Client error: ' + error.message); - } -}); - -// create TLS server -end.server = forge.tls.createConnection({ - server: true, - caStore: [data.client.cert], - sessionCache: {}, - // supported cipher suites in order of preference - cipherSuites: [ - forge.tls.CipherSuites.TLS_RSA_WITH_AES_128_CBC_SHA, - forge.tls.CipherSuites.TLS_RSA_WITH_AES_256_CBC_SHA], - connected: function(c) { - console.log('Server connected'); - c.prepareHeartbeatRequest('heartbeat'); - }, - verifyClient: true, - verify: function(c, verified, depth, certs) { - console.log( - 'Server verifying certificate w/CN: \"' + - certs[0].subject.getField('CN').value + - '\", verified: ' + verified + '...'); - return verified; - }, - getCertificate: function(c, hint) { - console.log('Server getting certificate for \"' + hint[0] + '\"...'); - return data.server.cert; - }, - getPrivateKey: function(c, cert) { - return data.server.privateKey; - }, - tlsDataReady: function(c) { - // send TLS data to client - end.client.process(c.tlsData.getBytes()); - }, - dataReady: function(c) { - console.log('Server received \"' + c.data.getBytes() + '\"'); - - // send response - c.prepare('Hello Client'); - c.close(); - }, - heartbeatReceived: function(c, payload) { - console.log('Server received heartbeat: ' + payload.getBytes()); - }, - closed: function(c) { - console.log('Server disconnected.'); - }, - error: function(c, error) { - console.log('Server error: ' + error.message); - } -}); - -console.log('created TLS client and server, doing handshake...'); -end.client.handshake(); diff --git a/alarm/node_modules/node-forge/tests/nodejs-ws-webid.js b/alarm/node_modules/node-forge/tests/nodejs-ws-webid.js deleted file mode 100644 index fae0b82..0000000 --- a/alarm/node_modules/node-forge/tests/nodejs-ws-webid.js +++ /dev/null @@ -1,491 +0,0 @@ -var forge = require('../js/forge'); -var fs = require('fs'); -var http = require('http'); -//var rdf = require('./rdflib'); -var sys = require('sys'); -var urllib = require('url'); -var ws = require('./ws'); - -// remove xmlns from input -var normalizeNs = function(input, ns) { - var rval = null; - - // primitive - if(typeof input === 'string' || - typeof input === 'number' || - typeof input === 'boolean') { - rval = input; - } - // array - else if(forge.util.isArray(input)) { - rval = []; - for(var i = 0; i < input.length; ++i) { - rval.push(normalizeNs(input[i], ns)); - } - } - // object - else { - if('@' in input) { - // copy namespace map - var newNs = {}; - for(var key in ns) { - newNs[key] = ns[key]; - } - ns = newNs; - - // update namespace map - for(var key in input['@']) { - if(key.indexOf('xmlns:') === 0) { - ns[key.substr(6)] = input['@'][key]; - } - } - } - - rval = {}; - for(var key in input) { - if(key.indexOf('xmlns:') !== 0) { - var value = input[key]; - var colon = key.indexOf(':'); - if(colon !== -1) { - var prefix = key.substr(0, colon); - if(prefix in ns) { - key = ns[prefix] + key.substr(colon + 1); - } - } - rval[key] = normalizeNs(value, ns); - } - } - } - - return rval; -}; - -// gets public key from WebID rdf -var getPublicKey = function(data, uri, callback) { - // FIXME: use RDF library to simplify code below - //var kb = new rdf.RDFParser(rdf.IndexedFormula(), uri).loadBuf(data); - //var CERT = rdf.Namespace('http://www.w3.org/ns/auth/cert#'); - //var RSA = rdf.Namespace('http://www.w3.org/ns/auth/rsa#'); - var RDF = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#'; - var CERT = 'http://www.w3.org/ns/auth/cert#'; - var RSA = 'http://www.w3.org/ns/auth/rsa#'; - var desc = RDF + 'Description'; - var about = RDF + 'about'; - var type = RDF + 'type'; - var resource = RDF + 'resource'; - var publicKey = RSA + 'RSAPublicKey'; - var modulus = RSA + 'modulus'; - var exponent = RSA + 'public_exponent'; - var identity = CERT + 'identity'; - var hex = CERT + 'hex'; - var decimal = CERT + 'decimal'; - - // gets a resource identifer from a node - var getResource = function(node, key) { - var rval = null; - - // special case 'about' - if(key === about) { - if('@' in node && about in node['@']) { - rval = node['@'][about]; - } - } - // any other resource - else if( - key in node && - typeof node[key] === 'object' && !forge.util.isArray(node[key]) && - '@' in node[key] && resource in node[key]['@']) { - rval = node[key]['@'][resource]; - } - - return rval; - }; - - // parse XML - uri = urllib.parse(uri); - var xml2js = require('./xml2js'); - var parser = new xml2js.Parser(); - parser.addListener('end', function(result) { - // normalize namespaces - result = normalizeNs(result, {}); - - // find grab all public keys whose identity matches hash from uri - var keys = []; - if(desc in result) { - // normalize RDF descriptions to array - if(!forge.util.isArray(result[desc])) { - desc = [result[desc]]; - } - else { - desc = result[desc]; - } - - // collect properties for all resources - var graph = {}; - for(var i = 0; i < desc.length; ++i) { - var node = desc[i]; - var res = {}; - for(var key in node) { - var obj = getResource(node, key); - res[key] = (obj === null) ? node[key] : obj; - } - graph[getResource(node, about) || ''] = res; - } - - // for every public key w/identity that matches the uri hash - // save the public key modulus and exponent - for(var r in graph) { - var props = graph[r]; - if(identity in props && - type in props && - props[type] === publicKey && - props[identity] === uri.hash && - modulus in props && - exponent in props && - props[modulus] in graph && - props[exponent] in graph && - hex in graph[props[modulus]] && - decimal in graph[props[exponent]]) { - keys.push({ - modulus: graph[props[modulus]][hex], - exponent: graph[props[exponent]][decimal] - }); - } - } - } - - sys.log('Public keys from RDF: ' + JSON.stringify(keys)); - callback(keys); - }); - parser.parseString(data); -}; - -// compares two public keys for equality -var comparePublicKeys = function(key1, key2) { - return key1.modulus === key2.modulus && key1.exponent === key2.exponent; -}; - -// gets the RDF data from a URL -var fetchUrl = function(url, callback, redirects) { - // allow 3 redirects by default - if(typeof(redirects) === 'undefined') { - redirects = 3; - } - - sys.log('Fetching URL: \"' + url + '\"'); - - // parse URL - url = forge.util.parseUrl(url); - var client = http.createClient( - url.port, url.fullHost, url.scheme === 'https'); - var request = client.request('GET', url.path, { - 'Host': url.host, - 'Accept': 'application/rdf+xml' - }); - request.addListener('response', function(response) { - var body = ''; - - // error, return empty body - if(response.statusCode >= 400) { - callback(body); - } - // follow redirect - else if(response.statusCode === 302) { - if(redirects > 0) { - // follow redirect - fetchUrl(response.headers.location, callback, --redirects); - } - else { - // return empty body - callback(body); - } - } - // handle data - else { - response.setEncoding('utf8'); - response.addListener('data', function(chunk) { - body += chunk; - }); - response.addListener('end', function() { - callback(body); - }); - } - }); - request.end(); -}; - -// does WebID authentication -var authenticateWebId = function(c, state) { - var auth = false; - - // get client-certificate - var cert = c.peerCertificate; - - // get public key from certificate - var publicKey = { - modulus: cert.publicKey.n.toString(16).toLowerCase(), - exponent: cert.publicKey.e.toString(10) - }; - - sys.log( - 'Server verifying certificate w/CN: \"' + - cert.subject.getField('CN').value + '\"\n' + - 'Public Key: ' + JSON.stringify(publicKey)); - - // build queue of subject alternative names to authenticate with - var altNames = []; - var ext = cert.getExtension({name: 'subjectAltName'}); - if(ext !== null && ext.altNames) { - for(var i = 0; i < ext.altNames.length; ++i) { - var altName = ext.altNames[i]; - if(altName.type === 6) { - altNames.push(altName.value); - } - } - } - - // create authentication processor - var authNext = function() { - if(!auth) { - // no more alt names, auth failed - if(altNames.length === 0) { - sys.log('WebID authentication FAILED.'); - c.prepare(JSON.stringify({ - success: false, - error: 'Not Authenticated' - })); - c.close(); - } - // try next alt name - else { - // fetch URL - var url = altNames.shift(); - fetchUrl(url, function(body) { - // get public key - getPublicKey(body, url, function(keys) { - // compare public keys from RDF until one matches - for(var i = 0; !auth && i < keys.length; ++i) { - auth = comparePublicKeys(keys[i], publicKey); - } - if(auth) { - // send authenticated notice to client - sys.log('WebID authentication PASSED.'); - state.authenticated = true; - c.prepare(JSON.stringify({ - success: true, - cert: forge.pki.certificateToPem(cert), - webID: url, - rdf: forge.util.encode64(body) - })); - } - else { - // try next alt name - authNext(); - } - }); - }); - } - } - }; - - // do auth - authNext(); -}; - -// creates credentials (private key + certificate) -var createCredentials = function(cn, credentials) { - sys.log('Generating 512-bit key-pair and certificate for \"' + cn + '\".'); - var keys = forge.pki.rsa.generateKeyPair(512); - sys.log('key-pair created.'); - - var cert = forge.pki.createCertificate(); - cert.serialNumber = '01'; - cert.validity.notBefore = new Date(); - cert.validity.notAfter = new Date(); - cert.validity.notAfter.setFullYear(cert.validity.notBefore.getFullYear() + 1); - var attrs = [{ - name: 'commonName', - value: cn - }, { - name: 'countryName', - value: 'US' - }, { - shortName: 'ST', - value: 'Virginia' - }, { - name: 'localityName', - value: 'Blacksburg' - }, { - name: 'organizationName', - value: 'Test' - }, { - shortName: 'OU', - value: 'Test' - }]; - cert.setSubject(attrs); - cert.setIssuer(attrs); - cert.setExtensions([{ - name: 'basicConstraints', - cA: true - }, { - name: 'keyUsage', - keyCertSign: true, - digitalSignature: true, - nonRepudiation: true, - keyEncipherment: true, - dataEncipherment: true - }, { - name: 'subjectAltName', - altNames: [{ - type: 6, // URI - value: 'http://myuri.com/webid#me' - }] - }]); - // FIXME: add subjectKeyIdentifier extension - // FIXME: add authorityKeyIdentifier extension - cert.publicKey = keys.publicKey; - - // self-sign certificate - cert.sign(keys.privateKey); - - // save credentials - credentials.key = forge.pki.privateKeyToPem(keys.privateKey); - credentials.cert = forge.pki.certificateToPem(cert); - - sys.log('Certificate created for \"' + cn + '\": \n' + credentials.cert); -}; - -// initialize credentials -var credentials = { - key: null, - cert: null -}; - -// read private key from file -var readPrivateKey = function(filename) { - credentials.key = fs.readFileSync(filename); - // try to parse from PEM as test - forge.pki.privateKeyFromPem(credentials.key); -}; - -// read certificate from file -var readCertificate = function(filename) { - credentials.cert = fs.readFileSync(filename); - // try to parse from PEM as test - forge.pki.certificateFromPem(credentials.cert); -}; - -// parse command line options -var opts = require('opts'); -var options = [ -{ short : 'v' -, long : 'version' -, description : 'Show version and exit' -, callback : function() { console.log('v1.0'); process.exit(1); } -}, -{ short : 'p' -, long : 'port' -, description : 'The port to listen for WebSocket connections on' -, value : true -}, -{ long : 'key' -, description : 'The server private key file to use in PEM format' -, value : true -, callback : readPrivateKey -}, -{ long : 'cert' -, description : 'The server certificate file to use in PEM format' -, value : true -, callback : readCertificate -} -]; -opts.parse(options, true); - -// create credentials for server -if(credentials.key === null || credentials.cert === null) { - createCredentials('server', credentials); -} - -// function to create TLS server connection -var createTls = function(websocket) { - var state = { - authenticated: false - }; - return forge.tls.createConnection({ - server: true, - caStore: [], - sessionCache: {}, - // supported cipher suites in order of preference - cipherSuites: [ - forge.tls.CipherSuites.TLS_RSA_WITH_AES_128_CBC_SHA, - forge.tls.CipherSuites.TLS_RSA_WITH_AES_256_CBC_SHA], - connected: function(c) { - sys.log('Server connected'); - - // do WebID authentication - try { - authenticateWebId(c, state); - } - catch(ex) { - c.close(); - } - }, - verifyClient: true, - verify: function(c, verified, depth, certs) { - // accept certs w/unknown-CA (48) - if(verified === 48) { - verified = true; - } - return verified; - }, - getCertificate: function(c, hint) { - sys.log('Server using certificate for \"' + hint[0] + '\"'); - return credentials.cert; - }, - getPrivateKey: function(c, cert) { - return credentials.key; - }, - tlsDataReady: function(c) { - // send base64-encoded TLS data over websocket - websocket.write(forge.util.encode64(c.tlsData.getBytes())); - }, - dataReady: function(c) { - // ignore any data until connection is authenticated - if(state.authenticated) { - sys.log('Server received \"' + c.data.getBytes() + '\"'); - } - }, - closed: function(c) { - sys.log('Server disconnected'); - websocket.end(); - }, - error: function(c, error) { - sys.log('Server error: ' + error.message); - } - }); -}; - -// create websocket server -var port = opts.get('port') || 8080; -ws.createServer(function(websocket) { - // create TLS server connection - var tls = createTls(websocket); - - websocket.addListener('connect', function(resource) { - sys.log('WebSocket connected: ' + resource); - - // close connection after 30 second timeout - setTimeout(websocket.end, 30 * 1000); - }); - - websocket.addListener('data', function(data) { - // base64-decode data and process it - tls.process(forge.util.decode64(data)); - }); - - websocket.addListener('close', function() { - sys.log('WebSocket closed'); - }); -}).listen(port); - -sys.log('WebSocket WebID server running on port ' + port); diff --git a/alarm/node_modules/node-forge/tests/nodejs-ws.js b/alarm/node_modules/node-forge/tests/nodejs-ws.js deleted file mode 100644 index 164962d..0000000 --- a/alarm/node_modules/node-forge/tests/nodejs-ws.js +++ /dev/null @@ -1,166 +0,0 @@ -var sys = require('sys'); -var ws = require('./ws'); -var forge = require('../js/forge'); - -// function to create certificate -var createCert = function(cn, data) -{ - sys.puts( - 'Generating 512-bit key-pair and certificate for \"' + cn + '\".'); - var keys = forge.pki.rsa.generateKeyPair(512); - sys.puts('key-pair created.'); - - var cert = forge.pki.createCertificate(); - cert.serialNumber = '01'; - cert.validity.notBefore = new Date(); - cert.validity.notAfter = new Date(); - cert.validity.notAfter.setFullYear( - cert.validity.notBefore.getFullYear() + 1); - var attrs = [{ - name: 'commonName', - value: cn - }, { - name: 'countryName', - value: 'US' - }, { - shortName: 'ST', - value: 'Virginia' - }, { - name: 'localityName', - value: 'Blacksburg' - }, { - name: 'organizationName', - value: 'Test' - }, { - shortName: 'OU', - value: 'Test' - }]; - cert.setSubject(attrs); - cert.setIssuer(attrs); - cert.setExtensions([{ - name: 'basicConstraints', - cA: true - }, { - name: 'keyUsage', - keyCertSign: true, - digitalSignature: true, - nonRepudiation: true, - keyEncipherment: true, - dataEncipherment: true - }, { - name: 'subjectAltName', - altNames: [{ - type: 6, // URI - value: 'http://myuri.com/webid#me' - }] - }]); - // FIXME: add subjectKeyIdentifier extension - // FIXME: add authorityKeyIdentifier extension - cert.publicKey = keys.publicKey; - - // self-sign certificate - cert.sign(keys.privateKey); - - // save data - data[cn] = { - cert: forge.pki.certificateToPem(cert), - privateKey: forge.pki.privateKeyToPem(keys.privateKey) - }; - - sys.puts('certificate created for \"' + cn + '\": \n' + data[cn].cert); -}; - -var data = {}; - -// create certificate for server -createCert('server', data); - -// function to create TLS server connection -var createTls = function(websocket) -{ - return forge.tls.createConnection( - { - server: true, - caStore: [], - sessionCache: {}, - // supported cipher suites in order of preference - cipherSuites: [ - forge.tls.CipherSuites.TLS_RSA_WITH_AES_128_CBC_SHA, - forge.tls.CipherSuites.TLS_RSA_WITH_AES_256_CBC_SHA], - connected: function(c) - { - sys.puts('Server connected'); - }, - verifyClient: true, - verify: function(c, verified, depth, certs) - { - sys.puts( - 'Server verifying certificate w/CN: \"' + - certs[0].subject.getField('CN').value + - '\", verified: ' + verified + '...'); - - // accept any certificate (could actually do WebID authorization from - // here within the protocol) - return true; - }, - getCertificate: function(c, hint) - { - sys.puts('Server getting certificate for \"' + hint[0] + '\"...'); - return data.server.cert; - }, - getPrivateKey: function(c, cert) - { - return data.server.privateKey; - }, - tlsDataReady: function(c) - { - // send base64-encoded TLS data over websocket - websocket.write(forge.util.encode64(c.tlsData.getBytes())); - }, - dataReady: function(c) - { - sys.puts('Server received \"' + c.data.getBytes() + '\"'); - - // send response - c.prepare('Hello Client'); - }, - closed: function(c) - { - sys.puts('Server disconnected.'); - websocket.end(); - }, - error: function(c, error) - { - sys.puts('Server error: ' + error.message); - } - }); -}; - -// create websocket server -var port = 8080; -ws.createServer(function(websocket) -{ - // create TLS server connection - var tls = createTls(websocket); - - websocket.addListener('connect', function(resource) - { - sys.puts('connected: ' + resource); - - // close connection after 10 seconds - setTimeout(websocket.end, 10 * 1000); - }); - - websocket.addListener('data', function(data) - { - // base64-decode data and process it - tls.process(forge.util.decode64(data)); - }); - - websocket.addListener('close', function() - { - sys.puts('closed'); - }); -}).listen(port); - -sys.puts('server running on port ' + port); diff --git a/alarm/node_modules/node-forge/tests/performance.html b/alarm/node_modules/node-forge/tests/performance.html deleted file mode 100644 index 9acbcc5..0000000 --- a/alarm/node_modules/node-forge/tests/performance.html +++ /dev/null @@ -1,550 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" - "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> - <head> - <title>Forge Performance Tests</title> - <link type="text/css" rel="stylesheet" media="all" href="screen.css" /> - <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script> - <script type="text/javascript" src="forge/debug.js"></script> - <script type="text/javascript" src="forge/util.js"></script> - <script type="text/javascript" src="forge/log.js"></script> - <script type="text/javascript" src="forge/task.js"></script> - <script type="text/javascript" src="forge/md5.js"></script> - <script type="text/javascript" src="forge/sha1.js"></script> - <script type="text/javascript" src="forge/sha256.js"></script> - <script type="text/javascript" src="forge/hmac.js"></script> - <script type="text/javascript" src="forge/aes.js"></script> - <script type="text/javascript" src="forge/pem.js"></script> - <script type="text/javascript" src="forge/asn1.js"></script> - <script type="text/javascript" src="forge/jsbn.js"></script> - <script type="text/javascript" src="forge/prng.js"></script> - <script type="text/javascript" src="forge/random.js"></script> - <script type="text/javascript" src="forge/oids.js"></script> - <script type="text/javascript" src="forge/rsa.js"></script> - <script type="text/javascript" src="forge/pbe.js"></script> - <script type="text/javascript" src="forge/x509.js"></script> - <script type="text/javascript" src="forge/pki.js"></script> - <script type="text/javascript" src="forge/tls.js"></script> - <script type="text/javascript" src="forge/aesCipherSuites.js"></script> - - <script type="text/javascript"> - //<![CDATA[ - // logging category - var cat = 'forge.tests.performance'; - - var test_random = function() - { - forge.log.debug(cat, 'painting canvas...'); - setTimeout(function() - { - var canvas = document.getElementById("canvas"); - var ctx = canvas.getContext("2d"); - var imgData = ctx.createImageData(canvas.width, canvas.height); - - // generate random bytes - var bytes = forge.random.getBytes(canvas.width * canvas.height * 3); - var n = 0; - for(var x = 0; x < imgData.width; x++) - { - for(var y = 0; y < imgData.height; y++) - { - // index of the pixel in the array - var idx = (x + y * imgData.width) * 4; - - // set values - imgData.data[idx + 0] = bytes.charCodeAt(n++); // Red - imgData.data[idx + 1] = bytes.charCodeAt(n++); // Green - imgData.data[idx + 2] = bytes.charCodeAt(n++); // Blue - imgData.data[idx + 3] = 255; // Alpha - } - } - - ctx.putImageData(imgData, 0, 0); - forge.log.debug(cat, 'done'); - }, 0); - }; - - var canvas_clear = function() - { - var canvas = document.getElementById("canvas"); - var ctx = canvas.getContext("2d"); - ctx.clearRect(0, 0, canvas.width, canvas.height); - }; - - var test_buffer_fill = function() - { - forge.log.debug(cat, - 'buffer fill optimized vs. slow running for about 5 seconds...'); - - setTimeout(function() - { - // run slow fill for 2.5 seconds - var st, et; - var b = ''; - var passed = 0; - while(passed < 2500) - { - st = +new Date(); - b += 'b'; - et = +new Date(); - passed += (et - st); - } - - // do optimized fill - var buf = forge.util.createBuffer(); - st = +new Date(); - buf.fillWithByte('b'.charCodeAt(0), b.length); - et = +new Date(); - - forge.log.debug(cat, 'fill times', (et - st) + ' < ' + passed); - }); - }; - - var test_buffer_xor = function() - { - forge.log.debug(cat, - 'buffer xor optimized vs. slow running for about 5 seconds...'); - - setTimeout(function() - { - // run slow xor for 2.5 seconds - var st, et; - var output = forge.util.createBuffer(); - var passed = 0; - while(passed < 2500) - { - st = +new Date(); - output.putByte(0x01 ^ 0x02); - et = +new Date(); - passed += (et - st); - } - - // do optimized xor - var count = output.length(); - var b1 = forge.util.createBuffer(); - b1.fillWithByte(0x01, count); - var b2 = forge.util.createBuffer(); - b2.fillWithByte(0x02, count); - - st = +new Date(); - output = forge.util.xorBytes(b1.getBytes(), b2.getBytes(), count); - et = +new Date(); - - forge.log.debug(cat, 'xor times', (et - st) + ' < ' + passed); - }); - }; - - // TODO: follow the same format as the hash tests - var test_base64_encode = function() - { - forge.log.debug(cat, 'base64 encode running for about 5 seconds...'); - - setTimeout(function() - { - // get starting time to make test run for only 5 seconds - var start = +new Date(); - - // build data to encode - var str = ''; - for(var i = 0; i < 100; i++) - { - str += '00010203050607080A0B0C0D0F1011121415161719'; - } - - // keep encoding for 5 seconds, keep track of total and count - var total = 0, count = 0, st, et; - var passed = 0; - while(passed < 5000) - { - st = +new Date(); - forge.util.encode64(str); - et = +new Date(); - ++count; - total += (et - st); - passed = +new Date() - start; - } - - total /= 1000; - var kb = 4200/1024; - forge.log.debug(cat, - 'encode:', (count*kb/total) + ' KiB/s'); - }); - }; - - // TODO: follow the same format as the hash tests - var test_base64_decode = function() - { - forge.log.debug(cat, 'base64 decode running for about 5 seconds...'); - - setTimeout(function() - { - // get starting time to make test run for only 5 seconds - var start = +new Date(); - - // build data to decode - var str = ''; - for(var i = 0; i < 100; i++) - { - str += - 'MDAwMTAyMDMwNTA2MDcwODBBMEIwQzBEMEYxMDExMTIxNDE1MTYxNzE5'; - } - - // keep encoding for 5 seconds, keep track of total and count - var total = 0, count = 0, st, et; - var passed = 0; - while(passed < 5000) - { - st = +new Date(); - forge.util.decode64(str); - et = +new Date(); - ++count; - total += (et - st); - passed = +new Date() - start; - } - - total /= 1000; - var kb = 5600/1024; - forge.log.debug(cat, - 'decode:', (count*kb/total) + ' KiB/s'); - }); - }; - - var test_md5 = function() - { - // create input data - var input = ['0123456789abcdef', '', '', '', '']; - for(var i = 0; i < 4; ++i) - { - input[1] += input[0]; - } - for(var i = 0; i < 4; ++i) - { - input[2] += input[1]; - } - for(var i = 0; i < 4; ++i) - { - input[3] += input[2]; - } - for(var i = 0; i < 8; ++i) - { - input[4] += input[3]; - } - - var md = forge.md.md5.create(); - - forge.log.debug(cat, 'md5 times in 1000s of bytes/sec processed:'); - - var st, et; - var output = - [' 16 bytes: ', - ' 64 bytes: ', - ' 256 bytes: ', - '1024 bytes: ', - '8192 bytes: ']; - var s = [16, 64, 256, 1024, 8192]; - var t = [0, 0, 0, 0, 0]; - for(var n = 0; n < 5; ++n) - { - var f = function(n) - { - setTimeout(function() - { - // run for 2 seconds each - var count = 0; - while(t[n] < 2000) - { - md.start(); - st = +new Date(); - md.update(input[n]); - md.digest(); - et = +new Date(); - t[n] = t[n] + (et - st); - ++count; - } - t[n] /= 1000; - forge.log.debug(cat, - output[n], (count*s[n]/t[n]/1000) + 'k/sec'); - }, 0); - }(n); - } - }; - - var test_sha1 = function() - { - // create input data - var input = ['0123456789abcdef', '', '', '', '']; - for(var i = 0; i < 4; ++i) - { - input[1] += input[0]; - } - for(var i = 0; i < 4; ++i) - { - input[2] += input[1]; - } - for(var i = 0; i < 4; ++i) - { - input[3] += input[2]; - } - for(var i = 0; i < 8; ++i) - { - input[4] += input[3]; - } - - var md = forge.md.sha1.create(); - - forge.log.debug(cat, 'sha-1 times in 1000s of bytes/sec processed:'); - - var st, et; - var output = - [' 16 bytes: ', - ' 64 bytes: ', - ' 256 bytes: ', - '1024 bytes: ', - '8192 bytes: ']; - var s = [16, 64, 256, 1024, 8192]; - var t = [0, 0, 0, 0, 0]; - for(var n = 0; n < 5; ++n) - { - var f = function(n) - { - setTimeout(function() - { - // run for 2 seconds each - var count = 0; - while(t[n] < 2000) - { - md.start(); - st = +new Date(); - md.update(input[n]); - md.digest(); - et = +new Date(); - t[n] = t[n] + (et - st); - ++count; - } - t[n] /= 1000; - forge.log.debug(cat, - output[n], (count*s[n]/t[n]/1000) + 'k/sec'); - }, 0); - }(n); - } - }; - - var test_sha256 = function() - { - // create input data - var input = ['0123456789abcdef', '', '', '', '']; - for(var i = 0; i < 4; ++i) - { - input[1] += input[0]; - } - for(var i = 0; i < 4; ++i) - { - input[2] += input[1]; - } - for(var i = 0; i < 4; ++i) - { - input[3] += input[2]; - } - for(var i = 0; i < 8; ++i) - { - input[4] += input[3]; - } - - var md = forge.md.sha256.create(); - - forge.log.debug(cat, 'sha-256 times in 1000s of bytes/sec processed:'); - - var st, et; - var output = - [' 16 bytes: ', - ' 64 bytes: ', - ' 256 bytes: ', - '1024 bytes: ', - '8192 bytes: ']; - var s = [16, 64, 256, 1024, 8192]; - var t = [0, 0, 0, 0, 0]; - for(var n = 0; n < 5; ++n) - { - var f = function(n) - { - setTimeout(function() - { - // run for 2 seconds each - var count = 0; - while(t[n] < 2000) - { - md.start(); - st = +new Date(); - md.update(input[n]); - md.digest(); - et = +new Date(); - t[n] = t[n] + (et - st); - ++count; - } - t[n] /= 1000; - forge.log.debug(cat, - output[n], (count*s[n]/t[n]/1000) + 'k/sec'); - }, 0); - }(n); - } - }; - - // TODO: follow the same format as the hash tests - var aes_128 = function() - { - forge.log.debug(cat, 'running AES-128 for 5 seconds...'); - - var block = []; - block.push(0x00112233); - block.push(0x44556677); - block.push(0x8899aabb); - block.push(0xccddeeff); - - var key = []; - key.push(0x00010203); - key.push(0x04050607); - key.push(0x08090a0b); - key.push(0x0c0d0e0f); - - setTimeout(function() - { - // run for 5 seconds - var start = +new Date(); - var now; - var totalEncrypt = 0; - var totalDecrypt = 0; - var count = 0; - var passed = 0; - while(passed < 5000) - { - var output = []; - var w = forge.aes._expandKey(key, false); - now = +new Date(); - forge.aes._updateBlock(w, block, output, false); - totalEncrypt += +new Date() - now; - - block = output; - output = []; - w = forge.aes._expandKey(key, true); - now = +new Date(); - forge.aes._updateBlock(w, block, output, true); - totalDecrypt += +new Date() - now; - - ++count; - passed = +new Date() - start; - } - - count = count * 16 / 1000; - totalEncrypt /= 1000; - totalDecrypt /= 1000; - forge.log.debug(cat, 'times in 1000s of bytes/sec processed.'); - forge.log.debug(cat, - 'encrypt: ' + (count*16 / totalEncrypt) + ' k/sec'); - forge.log.debug(cat, - 'decrypt: ' + (count*16 / totalDecrypt) + ' k/sec'); - }, 0); - }; - - // TODO: follow the same format as the hash tests - var aes_128_cbc = function() - { - forge.log.debug(cat, 'running AES-128 CBC for 5 seconds...'); - - var key = forge.random.getBytes(16); - var iv = forge.random.getBytes(16); - var plain = forge.random.getBytes(16); - - setTimeout(function() - { - // run for 5 seconds - var start = +new Date(); - var now; - var totalEncrypt = 0; - var totalDecrypt = 0; - var cipher; - var count = 0; - var passed = 0; - while(passed < 5000) - { - var input = forge.util.createBuffer(plain); - - // encrypt, only measuring update() and finish() - cipher = forge.aes.startEncrypting(key, iv); - now = +new Date(); - cipher.update(input); - cipher.finish(); - totalEncrypt += +new Date() - now; - - // decrypt, only measuring update() and finish() - var ct = cipher.output; - cipher = forge.aes.startDecrypting(key, iv); - now = +new Date(); - cipher.update(ct); - cipher.finish(); - totalDecrypt += +new Date() - now; - - ++count; - passed = +new Date() - start; - } - - // 32 bytes encrypted because of 16 bytes of padding - count = count * 32 / 1000; - totalEncrypt /= 1000; - totalDecrypt /= 1000; - forge.log.debug(cat, 'times in 1000s of bytes/sec processed.'); - forge.log.debug(cat, - 'encrypt: ' + (count / totalEncrypt) + ' k/sec'); - forge.log.debug(cat, - 'decrypt: ' + (count / totalDecrypt) + ' k/sec'); - }, 0); - }; - - //]]> - </script> - </head> - <body> - <div class="nav"><a href="index.html">Forge Tests</a> / Performance</div> - - <div class="header"> - <h1>Performance Tests</h1> - </div> - - <div class="content"> - - <fieldset class="section"> - <ul> - <li>Use the controls below to run Forge performance tests.</li> - <li>You currently need a JavaScript console to view the output.</li> - </ul> - </fieldset> - - <fieldset class="section"> - <legend>Tests</legend> - - <div id="random_controls"> - <button id="random" onclick="javascript:return test_random();">paint random</button> - <button id="clear" onclick="javascript:return canvas_clear();">clear</button> - </div> - <canvas id="canvas" width="100" height="100"></canvas> - <div id="buffer_controls"> - <button id="buffer_fill" onclick="javascript:return test_buffer_fill();">buffer fill</button> - <button id="buffer_xor" onclick="javascript:return test_buffer_xor();">buffer xor</button> - </div> - <div id="base64_controls"> - <button id="base64_encode" onclick="javascript:return test_base64_encode();">base64 encode</button> - <button id="base64_decode" onclick="javascript:return test_base64_decode();">base64 decode</button> - </div> - <div id="hash_controls"> - <button id="md5" onclick="javascript:return test_md5();">md5</button> - <button id="sha1" onclick="javascript:return test_sha1();">sha1</button> - <button id="sha256" onclick="javascript:return test_sha256();">sha256</button> - </div> - <div id="aes_controls"> - <button id="aes_128" onclick="javascript:return aes_128();">aes-128</button> - <button id="aes_128_cbc" onclick="javascript:return aes_128_cbc();">aes-128 cbc</button> - </div> - </fieldset> - </div> - </body> -</html> diff --git a/alarm/node_modules/node-forge/tests/policyserver.py b/alarm/node_modules/node-forge/tests/policyserver.py deleted file mode 100755 index bda8afe..0000000 --- a/alarm/node_modules/node-forge/tests/policyserver.py +++ /dev/null @@ -1,112 +0,0 @@ -#!/usr/bin/env python - -""" -Flash Socket Policy Server. - -- Starts Flash socket policy file server. -- Defaults to port 843. -- NOTE: Most operating systems require administrative privileges to use - ports under 1024. - - $ ./policyserver.py [options] -""" - -""" -Also consider Adobe's solutions: -http://www.adobe.com/devnet/flashplayer/articles/socket_policy_files.html -""" - -from multiprocessing import Process -from optparse import OptionParser -import SocketServer -import logging - -# Set address reuse for all TCPServers -SocketServer.TCPServer.allow_reuse_address = True - -# Static socket policy file string. -# NOTE: This format is very strict. Edit with care. -socket_policy_file = """\ -<?xml version="1.0"?>\ -<!DOCTYPE cross-domain-policy\ - SYSTEM "http://www.adobe.com/xml/dtds/cross-domain-policy.dtd">\ -<cross-domain-policy>\ -<allow-access-from domain="*" to-ports="*"/>\ -</cross-domain-policy>\0""" - - -class PolicyHandler(SocketServer.BaseRequestHandler): - """ - The RequestHandler class for our server. - - Returns a policy file when requested. - """ - - def handle(self): - """Send policy string if proper request string is received.""" - # get some data - # TODO: make this more robust (while loop, etc) - self.data = self.request.recv(1024).rstrip('\0') - logging.debug("%s wrote:%s" % (self.client_address[0], repr(self.data))) - # if policy file request, send the file. - if self.data == "<policy-file-request/>": - logging.info("Policy server request from %s." % (self.client_address[0])) - self.request.send(socket_policy_file) - else: - logging.info("Policy server received junk from %s: \"%s\"" % \ - (self.client_address[0], repr(self.data))) - - -class ThreadedTCPServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer): - def serve_forever(self): - """Handle one request at a time until shutdown or keyboard interrupt.""" - try: - SocketServer.BaseServer.serve_forever(self) - except KeyboardInterrupt: - return - - -def main(): - """Run socket policy file servers.""" - usage = "Usage: %prog [options]" - parser = OptionParser(usage=usage) - parser.add_option("", "--host", dest="host", metavar="HOST", - default="localhost", help="bind to HOST") - parser.add_option("-p", "--port", dest="port", metavar="PORT", - default=843, type="int", help="serve on PORT") - parser.add_option("-d", "--debug", dest="debug", action="store_true", - default=False, help="debugging output") - parser.add_option("-v", "--verbose", dest="verbose", action="store_true", - default=False, help="verbose output") - (options, args) = parser.parse_args() - - # setup logging - if options.debug: - lvl = logging.DEBUG - elif options.verbose: - lvl = logging.INFO - else: - lvl = logging.WARNING - logging.basicConfig(level=lvl, format="%(levelname)-8s %(message)s") - - # log basic info - logging.info("Flash Socket Policy Server. Use ctrl-c to exit.") - - # create policy server - logging.info("Socket policy serving on %s:%d." % (options.host, options.port)) - policyd = ThreadedTCPServer((options.host, options.port), PolicyHandler) - - # start server - policy_p = Process(target=policyd.serve_forever) - policy_p.start() - - while policy_p.is_alive(): - try: - policy_p.join(1) - except KeyboardInterrupt: - logging.info("Stopping test server...") - - -if __name__ == "__main__": - main() - diff --git a/alarm/node_modules/node-forge/tests/result.txt b/alarm/node_modules/node-forge/tests/result.txt deleted file mode 100644 index 7cb007c..0000000 --- a/alarm/node_modules/node-forge/tests/result.txt +++ /dev/null @@ -1 +0,0 @@ -expected result diff --git a/alarm/node_modules/node-forge/tests/screen.css b/alarm/node_modules/node-forge/tests/screen.css deleted file mode 100644 index 365a39f..0000000 --- a/alarm/node_modules/node-forge/tests/screen.css +++ /dev/null @@ -1,61 +0,0 @@ -/* CSS for Forge tests */ -body { - background: white; - color: black; - margin: 0; - padding: 0; -} -.warning { - border: thin solid red; - background: #7FF; -} -div.nav { - background: white; - border-bottom: thin solid black; - padding: .5em; - padding-top: .2em; - padding-bottom: .2em; -} -div.header { - border-bottom: thin solid black; - padding: .5em; -} -div.content { - padding: .5em; - background: #DDD; -} -div.footer { - border-top: thin solid black; - font-size: 80%; - padding: .5em; -} -canvas { - background: black; -} -table, td, th { - border: thin solid black; - border-collapse: collapse; -} -td, th { - padding: .2em; -} -span.sp-state-on { - font-weight: bold; -} -table#feedback { - width: 100%; -} -table#feedback th, table#feedback td { - width: 33%; -} -fieldset.section { - margin: .5em; - border: 2px solid black; - background: #FFF; -} -fieldset.section legend { - padding: .2em; - border: 2px solid black; - background: #DDF; - font-weight: bold; -} diff --git a/alarm/node_modules/node-forge/tests/server.crt b/alarm/node_modules/node-forge/tests/server.crt deleted file mode 100644 index 6952426..0000000 --- a/alarm/node_modules/node-forge/tests/server.crt +++ /dev/null @@ -1,26 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIEaDCCA1CgAwIBAgIJAJuj0AjEWncuMA0GCSqGSIb3DQEBBQUAMH8xCzAJBgNV -BAYTAlVTMREwDwYDVQQIEwhWaXJnaW5pYTETMBEGA1UEBxMKQmxhY2tzYnVyZzEd -MBsGA1UEChMURGlnaXRhbCBCYXphYXIsIEluYy4xGjAYBgNVBAsTEUZvcmdlIFRl -c3QgU2VydmVyMQ0wCwYDVQQDEwR0ZXN0MB4XDTEwMDcxMzE3MjAzN1oXDTMwMDcw -ODE3MjAzN1owfzELMAkGA1UEBhMCVVMxETAPBgNVBAgTCFZpcmdpbmlhMRMwEQYD -VQQHEwpCbGFja3NidXJnMR0wGwYDVQQKExREaWdpdGFsIEJhemFhciwgSW5jLjEa -MBgGA1UECxMRRm9yZ2UgVGVzdCBTZXJ2ZXIxDTALBgNVBAMTBHRlc3QwggEiMA0G -CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCm/FobjqK8CVP/Xbnpyhf1tpoyaiFf -ShUOmlWqL5rLe0Q0dDR/Zur+sLMUv/1T4wOfFkjjxvZ0Sk5NIjK3Wy2UA41a+M3J -RTbCFrg4ujsovFaD4CDmV7Rek0qJB3m5Gp7hgu5vfL/v+WrwxnQObNq+IrTMSA15 -cO4LzNIPj9K1LN2dB+ucT7xTQFHAfvLLgLlCLiberoabF4rEhgTMTbmMtFVKSt+P -xgQIYPnhw1WuAvE9hFesRQFdfARLqIZk92FeHkgtHv9BAunktJemcidbowTCTBaM -/njcgi1Tei/LFkph/FCVyGER0pekJNHX626bAQSLo/srsWfmcll9rK6bAgMBAAGj -geYwgeMwHQYDVR0OBBYEFCau5k6jxezjULlLuo/liswJlBF8MIGzBgNVHSMEgasw -gaiAFCau5k6jxezjULlLuo/liswJlBF8oYGEpIGBMH8xCzAJBgNVBAYTAlVTMREw -DwYDVQQIEwhWaXJnaW5pYTETMBEGA1UEBxMKQmxhY2tzYnVyZzEdMBsGA1UEChMU -RGlnaXRhbCBCYXphYXIsIEluYy4xGjAYBgNVBAsTEUZvcmdlIFRlc3QgU2VydmVy -MQ0wCwYDVQQDEwR0ZXN0ggkAm6PQCMRady4wDAYDVR0TBAUwAwEB/zANBgkqhkiG -9w0BAQUFAAOCAQEAnP/2mzFWaoGx6+KAfY8pcgnF48IoyKPx5cAQyzpMo+uRwrln -INcDGwNx6p6rkjFbK27TME9ReCk+xQuVGaKOtqErKECXWDtD+0M35noyaOwWIFu2 -7gPZ0uGJ1n9ZMe/S9yZmmusaIrc66rX4o+fslUlH0g3SrH7yf83M8aOC2pEyCsG0 -mNNfwSFWfmu+1GMRHXJQ/qT8qBX8ZPhzRY2BAS6vr+eh3gwXR6yXLA8Xm1+e+iDU -gGTQoYkixDIL2nhvd4AFFlE977BiE+0sMS1eJKUUbQ36MLAWb5oOZKHrphEvqMKA -eGDO3qoDqB5TkZC3x38DXBDvAZ01d9s0fvveag== ------END CERTIFICATE----- diff --git a/alarm/node_modules/node-forge/tests/server.key b/alarm/node_modules/node-forge/tests/server.key deleted file mode 100644 index 4024097..0000000 --- a/alarm/node_modules/node-forge/tests/server.key +++ /dev/null @@ -1,27 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -MIIEowIBAAKCAQEApvxaG46ivAlT/1256coX9baaMmohX0oVDppVqi+ay3tENHQ0 -f2bq/rCzFL/9U+MDnxZI48b2dEpOTSIyt1stlAONWvjNyUU2wha4OLo7KLxWg+Ag -5le0XpNKiQd5uRqe4YLub3y/7/lq8MZ0DmzaviK0zEgNeXDuC8zSD4/StSzdnQfr -nE+8U0BRwH7yy4C5Qi4m3q6GmxeKxIYEzE25jLRVSkrfj8YECGD54cNVrgLxPYRX -rEUBXXwES6iGZPdhXh5ILR7/QQLp5LSXpnInW6MEwkwWjP543IItU3ovyxZKYfxQ -lchhEdKXpCTR1+tumwEEi6P7K7Fn5nJZfayumwIDAQABAoIBAFGPbEuNbXq+a6KN -GuNP7Ef9em8pW0d5nbNWOoU3XzoH6RZds86ObDUeBTobVBaHCRvI/K0UXwgJyxjt -nSvlguuKmJ5Ya9rkzYwbILvEamTJKNCcxjT7nYOcGYm4dwGsOPIYy3D006LYhh04 -MTNig6zessQcZUhtmjd1QRyMuPP4PaWVO79ic01jxZR/ip6tN/FjCYclPRi/FRi8 -bQVuGEVLW2qHgQbDKPpcXFyFjIqt7c9dL97/3eeIDp+SgdQ6bPi80J7v9p2MRyBP -7OPhX8ZDsAiZr4G4N0EbEzmWWpVSjAI3Nlmk8SLT4lu42KKyoZLtuKPjEOVI3/TR -0ktsc/ECgYEA27AHLnsv07Yqe7Z2bmv+GP8PKlwrPSHwqU/3Z5/1V590N+jo15N4 -lb7gvBUwwvXIxQQQVYJqRimqNQYVfT6+xRtQdtdqInxv2hvhc/cKPEiIHNpRh7OI -w7I59yNMlCnqLeRBiCOmd7ruCWoMGw+VLhsyArwUTXuqUK2oYN9qWm8CgYEAwpZF -XNm8xCFa+YeqP+WQzwK/0yUxHmYZs7ofh9ZIgHtqwHNKO/OA8+nGsZBaIl5xiyT4 -uZ/qZi2EkYzOmx0iSathiWQpSyc9kB+nOTdMHyhBOj8CgbTRRXIMjDQ6bz78Z09F -Nxenhwk2gSVr3oB2FG/BWc1rlmVlmGJIIX3QtJUCgYBfLhLOdpywExqw4srI6Iz8 -c3U0mx44rD3CfVzpTopTXkhR+Nz4mXIDHuHrWxr3PNmxUiNpiMlWgLK3ql0hGFA6 -wazI8GeRbWxgiPfS8FNE7v/Z0FTGgGhesRcgFfEVuFs3as9hlmCHOzvqZEG+b6/o -e+vc93OsZknSDosG/YTsjQKBgHrb7HGinLftI4a3rLvpU1QRNVK4gdnit0muM6hN -mLtesVlPschGh935ddW5Ad//Z4tmTZDOMm5PQQuxLuXrMDH5fn0D+7qSzSEJi0jp -7Csj/IMtM4T3yMYjK17+vwJsb2s/NsGBMupk28ARA5mZ3HQs15S+ybZM0Se0rjxP -Nw49AoGBAKrLTOtZta0DSGt7tURwQK1mERuGM8ZZdXjvIVTJIIknohD2u3/T+O4+ -ekFTUd6GQKOFd/hZ52t4wcRs7c7KE1Xen7vRHc8c6c3TkF9ldpLmK2AWT8WifQO6 -9Fjx2Wf8HM+CbrokQYH/OHSV9Xft8BRTOPHGUJlp1UsYikSwp4fW ------END RSA PRIVATE KEY----- diff --git a/alarm/node_modules/node-forge/tests/server.py b/alarm/node_modules/node-forge/tests/server.py deleted file mode 100755 index b5a5f06..0000000 --- a/alarm/node_modules/node-forge/tests/server.py +++ /dev/null @@ -1,184 +0,0 @@ -#!/usr/bin/env python - -""" -SSL server for Forge tests. - -- The server changes to the directory of the server script. -- SSL uses "server.key" and "server.crt". -- Sever performs basic static file serving. -- Starts Flash cross domain policy file server. -- Defaults to HTTP/HTTPS port 19400. -- Defaults to Flash socket policy port 19945. - - $ ./server.py [options] - -If you just need a simple HTTP server, also consider: - $ python -m SimpleHTTPServer 19400 -""" - -from multiprocessing import Process -from optparse import OptionParser -import SimpleHTTPServer -import SocketServer -import os -import sys -import time - -# Try to import special Forge SSL module with session cache support -# Using the built directory directly -python_version = "python" + sys.version[:3] -sys.path.insert(0, os.path.join( - os.path.dirname(os.path.realpath(__file__)), - "..", "dist", "forge_ssl", "lib", python_version, "site-packages")) -try: - from forge import ssl - have_ssl_sessions = True - have_ssl = True -except ImportError: - have_ssl_sessions = False - try: - import ssl - have_ssl = True - except ImportError: - have_ssl = False - -# Set address reuse for all TCPServers -SocketServer.TCPServer.allow_reuse_address = True - -# The policy file -# NOTE: This format is very strict. Edit with care. -policy_file = """\ -<?xml version="1.0"?>\ -<!DOCTYPE cross-domain-policy\ - SYSTEM "http://www.adobe.com/xml/dtds/cross-domain-policy.dtd">\ -<cross-domain-policy>\ -<allow-access-from domain="*" to-ports="*"/>\ -</cross-domain-policy>\0""" - - -class PolicyHandler(SocketServer.BaseRequestHandler): - """ - The RequestHandler class for our server. - - Returns a policy file when requested. - """ - - def handle(self): - # get some data - # TODO: make this more robust (while loop, etc) - self.data = self.request.recv(1024).rstrip('\0') - #print "%s wrote:" % self.client_address[0] - #print repr(self.data) - # if policy file request, send the file. - if self.data == "<policy-file-request/>": - print "Policy server request from %s." % (self.client_address[0]) - self.request.send(policy_file) - else: - print "Policy server received junk from %s: \"%s\"" % \ - (self.client_address[0], repr(self.data)) - - -def create_policy_server(options): - """Start a policy server""" - print "Policy serving from %d." % (options.policy_port) - policyd = SocketServer.TCPServer((options.host, options.policy_port), PolicyHandler) - return policyd - - -class ThreadedTCPServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer): - pass - - -def create_http_server(options, script_dir): - """Start a static file server""" - # use UTF-8 encoding for javascript files - m = SimpleHTTPServer.SimpleHTTPRequestHandler.extensions_map - m['.js'] = 'application/javascript;charset=UTF-8' - - Handler = SimpleHTTPServer.SimpleHTTPRequestHandler -# httpd = SocketServer.TCPServer((options.host, options.port), Handler) - httpd = ThreadedTCPServer((options.host, options.port), Handler) - if options.tls: - if not have_ssl: - raise Exception("SSL support from Python 2.7 or later is required.") - - # setup session args if we session support - sess_args = {} - if have_ssl_sessions: - sess_args["sess_id_ctx"] = "forgetest" - else: - print "Forge SSL with session cache not available, using standard version." - - httpd.socket = ssl.wrap_socket( - httpd.socket, - keyfile="server.key", - certfile="server.crt", - server_side=True, - **sess_args) - - print "Serving from \"%s\"." % (script_dir) - print "%s://%s:%d/" % \ - (("https" if options.tls else "http"), - httpd.server_address[0], - options.port) - return httpd - - -def serve_forever(server): - """Serve until shutdown or keyboard interrupt.""" - try: - server.serve_forever() - except KeyboardInterrupt: - return - - -def main(): - """Start static file and policy servers""" - usage = "Usage: %prog [options]" - parser = OptionParser(usage=usage) - parser.add_option("", "--host", dest="host", metavar="HOST", - default="localhost", help="bind to HOST") - parser.add_option("-p", "--port", dest="port", type="int", - help="serve on PORT", metavar="PORT", default=19400) - parser.add_option("-P", "--policy-port", dest="policy_port", type="int", - help="serve policy file on PORT", metavar="PORT", default=19945) - parser.add_option("", "--tls", dest="tls", action="store_true", - help="serve HTTPS", default=False) - (options, args) = parser.parse_args() - - # Change to script dir so SSL and test files are in current dir. - script_dir = os.path.dirname(os.path.realpath(__file__)) - os.chdir(script_dir) - - print "Forge Test Server. Use ctrl-c to exit." - - # create policy and http servers - httpd = create_http_server(options, script_dir) - policyd = create_policy_server(options) - - # start servers - server_p = Process(target=serve_forever, args=(httpd,)) - policy_p = Process(target=serve_forever, args=(policyd,)) - server_p.start() - policy_p.start() - - processes = [server_p, policy_p] - - while len(processes) > 0: - try: - for p in processes: - if p.is_alive(): - p.join(1) - else: - processes.remove(p) - except KeyboardInterrupt: - print "\nStopping test server..." - # processes each receive interrupt - # so no need to shutdown - #httpd.shutdown(); - #policyd.shutdown(); - - -if __name__ == "__main__": - main() - diff --git a/alarm/node_modules/node-forge/tests/socketPool.html b/alarm/node_modules/node-forge/tests/socketPool.html deleted file mode 100644 index 33a095f..0000000 --- a/alarm/node_modules/node-forge/tests/socketPool.html +++ /dev/null @@ -1,299 +0,0 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" - "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml"> - <head> - <link type="text/css" rel="stylesheet" media="all" href="screen.css" /> - <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script> - <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js"></script> - <script type="text/javascript" src="forge/util.js"></script> - <script type="text/javascript" src="forge/socket.js"></script> - <script type="text/javascript" src="forge/log.js"></script> - - <script type="text/javascript"> - //<![CDATA[ - // logging category - var cat = 'forge.tests.socketPool'; - - // feedback types - var ERROR = ''; - var USER = 'user'; - var SOCKETPOOL = 'socketpool' - var SOCKET = 'socket' - - function addFeedback(type, text) - { - var row = $('<tr/>') - .append($('<td/>').html(' ')) - .append($('<td/>').html(' ')) - .append($('<td/>').html(' ')); - switch(type) - { - case USER: - row.children().eq(0).html(text); - break; - case SOCKETPOOL: - row.children().eq(1).html(text); - break; - case SOCKET: - row.children().eq(2).html(text); - break; - default: - var msg = 'ERROR: bad feedback type:' + type; - row.children().eq(1).html(msg); - forge.log.error(cat, msg); - } - $('#feedback').append(row); - forge.log.debug(cat, '[' + type + ']', text); - }; - - function _setState(stateSel) - { - $('.sp-control').filter(stateSel).removeAttr('disabled'); - $('.sp-control').filter(':not(' + stateSel + ')').attr('disabled', 'disabled'); - $('.sp-state').filter(stateSel).addClass('sp-state-on'); - $('.sp-state').filter(':not(' + stateSel + ')').removeClass('sp-state-on'); - }; - - function setState(state) - { - switch(state) - { - case 'ready': - _setState('.sp-ready'); - break; - case 'initialized': - _setState('.sp-ready,.sp-initialized'); - break; - case 'created': - _setState('.sp-ready,.sp-initialized,.sp-created'); - break; - case 'connected': - _setState('.sp-ready,.sp-initialized,.sp-created,.sp-connected'); - break; - default: - addFeedback(ERROR, 'ERROR: bad state: ' + state); - }; - }; - - window.forge.socketPool = - { - ready: function() - { - $(document).ready(function() { - addFeedback(SOCKETPOOL, 'Ready'); - setState('ready'); - }); - } - }; - - swfobject.embedSWF( - "forge/SocketPool.swf", "socketPool", "0", "0", "9.0.0", - false, {}, {allowscriptaccess: 'always'}, {}); - - // local alias - var net = window.forge.net; - - // socket to use - var socket; - - $(document).ready(function() { - addFeedback(USER, 'Ready'); - $('#host').val(window.location.hostname); - $('#port').val(window.location.port); - }); - - function sp_init() - { - net.createSocketPool({ - flashId: 'socketPool', - policyPort: parseInt($('#policyPort').val()), - msie: false - }); - addFeedback(SOCKETPOOL, 'Initialized'); - setState('initialized'); - return false; - }; - - function sp_cleanup() - { - net.destroySocketPool({flashId: 'socketPool'}); - addFeedback(SOCKETPOOL, 'Cleaned up'); - setState('ready'); - return false; - }; - - function sp_create() - { - socket = net.createSocket({ - flashId: 'socketPool', - connected: function(e) - { - forge.log.debug(cat, 'connected', e); - addFeedback(SOCKET, 'Connected'); - }, - closed: function(e) - { - forge.log.debug(cat, 'closed', e); - addFeedback(SOCKET, 'Closed. Type: ' + e.type); - setState('created'); - }, - data: function(e) - { - forge.log.debug(cat, 'data received', e); - forge.log.debug(cat, 'bytes available', socket.bytesAvailable()); - addFeedback(SOCKET, - 'Data available: ' + - socket.bytesAvailable() +' bytes'); - var bytes = socket.receive(e.bytesAvailable); - forge.log.debug(cat, 'bytes received', bytes); - }, - error: function(e) - { - forge.log.error(cat, 'error', e); - addFeedback(SOCKET, 'Error: ' + e); - } - }); - addFeedback(SOCKETPOOL, 'Created socket'); - setState('created'); - return false; - }; - - function sp_destroy() - { - socket.destroy(); - addFeedback(USER, 'Request socket destroy'); - setState('initialized'); - return false; - }; - - function sp_connect() - { - socket.connect({ - host: $('#host').val(), - port: parseInt($('#port').val()), - policyPort: parseInt($('#policyPort').val()) - }); - addFeedback(USER, 'Request socket connect'); - setState('connected'); - }; - - function sp_isConnected() - { - var connected = socket.isConnected(); - addFeedback(USER, 'Socket connected check: ' + connected); - }; - - function sp_send() - { - socket.send('GET ' + $('#path').val() + ' HTTP/1.0\r\n\r\n'); - addFeedback(USER, 'Send GET request'); - }; - - function sp_close() - { - socket.close(); - addFeedback(USER, 'Requst socket close'); - setState('created'); - }; - //]]> - </script> - </head> - <body> - <div class="nav"><a href="index.html">Forge Tests</a> / SocketPool</div> - - <div class="header"> - <h1>SocketPool Test</h1> - </div> - - <div class="content"> - <!-- div used to hold the flash socket pool implemenation --> - <div id="socketPool"> - <p>Could not load the flash SocketPool.</p> - </div> - - <fieldset class="section"> - <ul> - <li>This page tests a single socket connection to the local test server.</li> - <li>Note that the selected server must serve a Flash cross-domain policy file on the selected policy port.</li> - <li>Additional output available in the JavaScript console.</li> - </ul> - </fieldset> - - <fieldset class="section"> - <legend>State</legend> - <p>State: - <span class="sp-state sp-ready">Ready</span> » - <span class="sp-state sp-initialized">Initialized</span> » - <span class="sp-state sp-created">Created</span> » - <span class="sp-state sp-connected">Connected</span> - </p> - </fieldset> - - <fieldset class="section"> - <legend>Controls</legend> - <div id="controls"> - <table> - <tr><th>Action</th><th>Description</th></tr> - <tr> - <td><button id="init" disabled="disabled" class="sp-control sp-ready" - onclick="javascript:return sp_init();">init</button></td> - <td>Initialize SocketPool system.</td> - </tr> - <tr> - <td><button id="cleanup" disabled="disabled" class="sp-control sp-initialized" - onclick="javascript:return sp_cleanup();">cleanup</button></td> - <td>Cleanup SocketPool system.</td> - </tr> - <tr> - <td><button id="create" disabled="disabled" class="sp-control sp-initialized" - onclick="javascript:return sp_create();">create socket</button></td> - <td>Create a new test socket.</td> - </tr> - <tr> - <td><button id="destroy" disabled="disabled" class="sp-control sp-created" - onclick="javascript:return sp_destroy();">destroy socket</button></td> - <td>Destroy the test socket.</td> - </tr> - <tr> - <td><button id="connect" disabled="disabled" class="sp-control sp-created" - onclick="javascript:return sp_connect();">connect</button></td> - <td>Connect the socket to - host: <input id="host"/> - port: <input id="port"/> - policy port: <input id="policyPort" value="19945"/> - </td> - </tr> - <tr> - <td><button id="isConnected" disabled="disabled" class="sp-control sp-created" - onclick="javascript:return sp_isConnected();">is connected</button></td> - <td>Check if socket is connected.</td> - </tr> - <tr> - <td><button id="send" disabled="disabled" class="sp-control sp-connected" - onclick="javascript:return sp_send();">send</button></td> - <td>Send a GET request for - path: <input id="path" value="/"/> - </td> - </tr> - <tr> - <td><button id="close" disabled="disabled" class="sp-control sp-connected" - onclick="javascript:return sp_close();">close</button></td> - <td>Close the test socket.</td> - </tr> - </table> - </div> - </fieldset> - - <fieldset class="section"> - <legend>Feedback</legend> - <table id="feedback"> - <tr> - <th>User</th> - <th>SocketPool</th> - <th>Socket</th> - </tr> - </table> - </fieldset> - </div> - </body> -</html> diff --git a/alarm/node_modules/node-forge/tests/tasks.html b/alarm/node_modules/node-forge/tests/tasks.html deleted file mode 100644 index eba0173..0000000 --- a/alarm/node_modules/node-forge/tests/tasks.html +++ /dev/null @@ -1,53 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" - "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> - <head> - <title>Forge Tasks Test</title> - <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script> - <script type="text/javascript" src="forge/debug.js"></script> - <script type="text/javascript" src="forge/util.js"></script> - <script type="text/javascript" src="forge/log.js"></script> - <script type="text/javascript" src="forge/task.js"></script> - <script type="text/javascript" src="tasks.js"></script> - <link type="text/css" rel="stylesheet" media="all" href="screen.css" /> - <style type="text/css"> - .ready { color: inherit; background: inherit; } - .testing { color: black; background: yellow; } - .pass{ color: white; background: green; } - .fail{ color: white; background: red; } - </style> - </head> -<body> -<div class="nav"><a href="index.html">Forge Tests</a> / Tasks</div> - -<div class="header"> - <h1>Task Tests</h1> -</div> - -<div class="content"> - -<fieldset class="section"> -<legend>Control</legend> - <button id="start">Start</button> - <button id="reset">Reset</button> - <br/> - <input id="scroll" type="checkbox" checked="checked" />Scroll Tests -</fieldset> - -<fieldset class="section"> -<legend>Progress</legend> -Status: <span id="status">?</span><br/> -Pass: <span id="pass">?</span>/<span id="total">?</span><br/> -Fail: <span id="fail">?</span> -</fieldset> - -<fieldset class="section"> -<legend>Tests</legend> -<div id="tests"></div> -</fieldset> - -</div> - -</body> -</html> diff --git a/alarm/node_modules/node-forge/tests/tasks.js b/alarm/node_modules/node-forge/tests/tasks.js deleted file mode 100644 index dd3ffde..0000000 --- a/alarm/node_modules/node-forge/tests/tasks.js +++ /dev/null @@ -1,378 +0,0 @@ -/** - * Forge Tasks Test - * - * @author David I. Lehn <dlehn@digitalbazaar.com> - * - * Copyright (c) 2009-2010 Digital Bazaar, Inc. All rights reserved. - */ -jQuery(function($) -{ - var cat = 'forge.tests.tasks'; - - var tests = []; - var passed = 0; - var failed = 0; - - var init = function() { - passed = failed = 0; - $('.ready,.testing,.pass,.fail') - .removeClass('ready testing pass fail'); - $('#status') - .text('Ready.') - .addClass('ready'); - $('#total').text(tests.length); - $('#pass').text(passed); - $('#fail').text(failed); - $('.expect').empty(); - $('.result').empty(); - $('.time').empty(); - $('#start').removeAttr('disabled'); - }; - - var start = function() - { - $('#start').attr('disabled', 'disabled'); - // meta! use tasks to run the task tests - forge.task.start({ - type: 'test', - run: function(task) { - task.next('starting', function(task) { - forge.log.debug(cat, 'start'); - $('#status') - .text('Testing...') - .addClass('testing') - .removeClass('idle'); - }); - $.each(tests, function(i, test) { - task.next('test', function(task) { - var title = $('li:first', test.container); - if($('#scroll:checked').length === 1) - { - $('html,body').animate({scrollTop: title.offset().top}); - } - title.addClass('testing'); - test.run(task, test); - }); - task.next('test', function(task) { - $('li:first', test.container).removeClass('testing'); - }); - }); - task.next('success', function(task) { - forge.log.debug(cat, 'done'); - if(failed === 0) { - $('#status') - .text('PASS') - .addClass('pass') - .removeClass('testing'); - } else { - // FIXME: should just be hitting failure() below - $('#status') - .text('FAIL') - .addClass('fail') - .removeClass('testing'); - } - }); - }, - failure: function() { - $('#status') - .text('FAIL') - .addClass('fail') - .removeClass('testing'); - } - }); - }; - - $('#start').click(function() { - start(); - }); - - $('#reset').click(function() { - init(); - }); - - var addTest = function(name, run) - { - var container = $('<ul><li>Test ' + name + '</li><ul/></ul>'); - var expect = $('<li>Expect: <span class="expect"/></li>'); - var result = $('<li>Result: <span class="result"/></li>'); - var time = $('<li>Time: <span class="time"/></li>'); - $('ul', container).append(expect).append(result).append(time); - $('#tests').append(container); - var test = { - container: container, - startTime: null, - run: function(task, test) { - test.startTime = new Date(); - run(task, test); - }, - expect: $('span', expect), - result: $('span', result), - check: function() { - var e = test.expect.text(); - var r = test.result.text(); - (e == r) ? test.pass() : test.fail(); - }, - pass: function() { - passed += 1; - $('#pass').text(passed); - $('li:first', container).addClass('pass'); - var dt = new Date() - test.startTime; - $('span.time', container).html(dt); - }, - fail: function() { - failed += 1; - $('#fail').text(failed); - $('li:first', container).addClass('fail'); - var dt = new Date() - test.startTime; - $('span.time', container).html(dt); - } - }; - tests.push(test); - }; - - addTest('pass', function(task, test) { - test.pass(); - }); - - addTest('check', function(task, test) { - test.check(); - }); - - addTest('task 1', function(task, test) { - task.next(function(task) { - test.pass(); - }); - }); - - addTest('task check()', function(task, test) { - test.expect.append('check'); - task.next(function(task) { - test.result.append('check'); - }); - task.next(function(task) { - test.check(); - }); - }); - - addTest('serial 20', function(task, test) { - // total - var n = 20; - // counter used in the tasks - var taskn = 0; - for(var i = 0; i < n; ++i) { - test.expect.append(i + ' '); - task.next(function(task) { - test.result.append(taskn++ + ' '); - }); - } - task.next(function(task) { - test.check(); - }); - }); - - addTest('ajax block', function(task, test) { - test.expect.append('.'); - task.next(function(task) { - task.parent.block(); - $.ajax({ - type: 'GET', - url: 'tasks.html', - success: function() { - test.result.append('.'); - task.parent.unblock(); - } - }); - }); - task.next(function(task) { - test.check(); - }); - }); - - addTest('serial ajax', function(task, test) { - var n = 10; - for(var i = 0; i < n; ++i) - { - test.expect.append(i + ' '); - } - task.next(function(task) { - // create parallel functions - task.parent.block(n); - for(var i = 0; i < n; ++i) - { - // pass value into closure - (function(i) - { - // serial tasks - task.next(function(ajaxTask) - { - $.ajax({ - type: 'GET', - url: 'tasks.html', - success: function() { - // results use top level task - test.result.append(i + ' '); - task.parent.unblock(); - } - }); - }); - })(i); - } - }); - task.next(function(task) { - test.check(); - }); - }); - - addTest('parallel ajax', function(task, test) { - task.next(function(task) { - var n = 10; - // create parallel functions - var tasks = []; - for(var i = 0; i < n; ++i) - { - // pass value into closure - (function(i) - { - tasks.push(function(ajaxTask) - { - $.ajax({ - type: 'GET', - url: 'tasks.html', - success: function() { - // results use top level task - test.result.append(i + ' '); - } - }); - }); - })(i); - } - // launch in parallel - task.parallel(tasks); - }); - task.next(function(task) { - test.pass(); - }); - }); - - addTest('linear empty tasks rate', function(task, test) { - test.expect.append('-'); - // total - var n = 100; - var start = new Date(); - for(var i = 0; i < n; ++i) { - // empty task - task.next(function(task) {}); - } - task.next(function(task) { - var dt = (new Date() - start) / 1000; - var res = $('<ul/>') - .append('<li>Tasks: ' + n + '</li>') - .append('<li>Time: ' + dt + 's</li>') - .append('<li>Rate: ' + n/dt + ' tasks/s</li>') - .append('<li>Task Time: ' + 1000*dt/n + ' ms/tasks</li>'); - test.result.html(res); - test.pass(); - }); - }); - - addTest('sleep', function(task, test) { - test.expect.append('-'); - var st = 1000; - var start = new Date(); - task.next(function(task) { - task.sleep(st); - }); - task.next(function(task) { - var dt = new Date() - start; - var res = $('<ul/>') - .append('<li>Sleep Time : ' + st + 'ms</li>') - .append('<li>Real Time: ' + dt + 'ms</li>') - .append('<li>Diff: ' + (dt-st) + 'ms</li>'); - test.result.html(res); - test.pass(); - }); - }); - - addTest('serial 20 + sleep', function(task, test) { - // total - var n = 20; - // counter used in the tasks - var taskn = 0; - for(var i = 0; i < n; ++i) { - test.expect.append(i + ' '); - task.next(function(task) { - task.sleep(20); - test.result.append(taskn++ + ' '); - }); - } - task.next(function(task) { - test.check(); - }); - }); - - addTest('concurrent tasks', function(task, test) - { - var colors = [ - 'red', - 'green', - 'blue', - 'black', - 'purple', - 'goldenrod', - 'maroon', - 'gray', - 'teal', - 'magenta' - ]; - var count = colors.length; - task.next(function(task) - { - var main = task; - task.block(count); - - var tasks = []; - for(var i = 0; i < count; ++i) - { - var makefunction = function(index) - { - return function(task) - { - // total - var n = 20; - // counter used in the tasks - var taskn = 0; - for(var j = 0; j < n; j++) - { - task.next(function(task) - { - test.result.append( - '<span style=\"color:' + colors[index] + ';\">' + - taskn++ + '</span> '); - }); - } - task.next(function(task) - { - main.unblock(); - }); - }; - }; - tasks.push( - { - type: 'concurrent' + i, - run: makefunction(i) - }); - } - - for(var i = 0; i < count; ++i) - { - forge.task.start(tasks[i]); - } - }); - - task.next(function(task) { - test.pass(); - }); - }); - - init(); -}); diff --git a/alarm/node_modules/node-forge/tests/tls.html b/alarm/node_modules/node-forge/tests/tls.html deleted file mode 100644 index 92501b8..0000000 --- a/alarm/node_modules/node-forge/tests/tls.html +++ /dev/null @@ -1,426 +0,0 @@ -<html> - <head> - <link type="text/css" rel="stylesheet" media="all" href="screen.css" /> - <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js"></script> - <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script> - <script type="text/javascript" src="forge/debug.js"></script> - <script type="text/javascript" src="forge/util.js"></script> - <script type="text/javascript" src="forge/log.js"></script> - <script type="text/javascript" src="forge/socket.js"></script> - <script type="text/javascript" src="forge/md5.js"></script> - <script type="text/javascript" src="forge/sha1.js"></script> - <script type="text/javascript" src="forge/hmac.js"></script> - <script type="text/javascript" src="forge/aes.js"></script> - <script type="text/javascript" src="forge/pem.js"></script> - <script type="text/javascript" src="forge/asn1.js"></script> - <script type="text/javascript" src="forge/jsbn.js"></script> - <script type="text/javascript" src="forge/prng.js"></script> - <script type="text/javascript" src="forge/random.js"></script> - <script type="text/javascript" src="forge/oids.js"></script> - <script type="text/javascript" src="forge/rsa.js"></script> - <script type="text/javascript" src="forge/pbe.js"></script> - <script type="text/javascript" src="forge/x509.js"></script> - <script type="text/javascript" src="forge/pki.js"></script> - <script type="text/javascript" src="forge/tls.js"></script> - <script type="text/javascript" src="forge/aesCipherSuites.js"></script> - <script type="text/javascript" src="forge/tlssocket.js"></script> - <script type="text/javascript" src="forge/http.js"></script> - <script type="text/javascript" src="ws-webid.js"></script> - - <script type="text/javascript"> - //<![CDATA[ - // logging category - var cat = 'forge.tests.tls'; - - swfobject.embedSWF( - 'forge/SocketPool.swf', 'socketPool', '0', '0', '9.0.0', - false, {}, {allowscriptaccess: 'always'}, {}); - - // CA certificate for test server - var certificatePem = - '-----BEGIN CERTIFICATE-----\r\n' + - 'MIIEaDCCA1CgAwIBAgIJAJuj0AjEWncuMA0GCSqGSIb3DQEBBQUAMH8xCzAJBgNV\r\n' + - 'BAYTAlVTMREwDwYDVQQIEwhWaXJnaW5pYTETMBEGA1UEBxMKQmxhY2tzYnVyZzEd\r\n' + - 'MBsGA1UEChMURGlnaXRhbCBCYXphYXIsIEluYy4xGjAYBgNVBAsTEUZvcmdlIFRl\r\n' + - 'c3QgU2VydmVyMQ0wCwYDVQQDEwR0ZXN0MB4XDTEwMDcxMzE3MjAzN1oXDTMwMDcw\r\n' + - 'ODE3MjAzN1owfzELMAkGA1UEBhMCVVMxETAPBgNVBAgTCFZpcmdpbmlhMRMwEQYD\r\n' + - 'VQQHEwpCbGFja3NidXJnMR0wGwYDVQQKExREaWdpdGFsIEJhemFhciwgSW5jLjEa\r\n' + - 'MBgGA1UECxMRRm9yZ2UgVGVzdCBTZXJ2ZXIxDTALBgNVBAMTBHRlc3QwggEiMA0G\r\n' + - 'CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCm/FobjqK8CVP/Xbnpyhf1tpoyaiFf\r\n' + - 'ShUOmlWqL5rLe0Q0dDR/Zur+sLMUv/1T4wOfFkjjxvZ0Sk5NIjK3Wy2UA41a+M3J\r\n' + - 'RTbCFrg4ujsovFaD4CDmV7Rek0qJB3m5Gp7hgu5vfL/v+WrwxnQObNq+IrTMSA15\r\n' + - 'cO4LzNIPj9K1LN2dB+ucT7xTQFHAfvLLgLlCLiberoabF4rEhgTMTbmMtFVKSt+P\r\n' + - 'xgQIYPnhw1WuAvE9hFesRQFdfARLqIZk92FeHkgtHv9BAunktJemcidbowTCTBaM\r\n' + - '/njcgi1Tei/LFkph/FCVyGER0pekJNHX626bAQSLo/srsWfmcll9rK6bAgMBAAGj\r\n' + - 'geYwgeMwHQYDVR0OBBYEFCau5k6jxezjULlLuo/liswJlBF8MIGzBgNVHSMEgasw\r\n' + - 'gaiAFCau5k6jxezjULlLuo/liswJlBF8oYGEpIGBMH8xCzAJBgNVBAYTAlVTMREw\r\n' + - 'DwYDVQQIEwhWaXJnaW5pYTETMBEGA1UEBxMKQmxhY2tzYnVyZzEdMBsGA1UEChMU\r\n' + - 'RGlnaXRhbCBCYXphYXIsIEluYy4xGjAYBgNVBAsTEUZvcmdlIFRlc3QgU2VydmVy\r\n' + - 'MQ0wCwYDVQQDEwR0ZXN0ggkAm6PQCMRady4wDAYDVR0TBAUwAwEB/zANBgkqhkiG\r\n' + - '9w0BAQUFAAOCAQEAnP/2mzFWaoGx6+KAfY8pcgnF48IoyKPx5cAQyzpMo+uRwrln\r\n' + - 'INcDGwNx6p6rkjFbK27TME9ReCk+xQuVGaKOtqErKECXWDtD+0M35noyaOwWIFu2\r\n' + - '7gPZ0uGJ1n9ZMe/S9yZmmusaIrc66rX4o+fslUlH0g3SrH7yf83M8aOC2pEyCsG0\r\n' + - 'mNNfwSFWfmu+1GMRHXJQ/qT8qBX8ZPhzRY2BAS6vr+eh3gwXR6yXLA8Xm1+e+iDU\r\n' + - 'gGTQoYkixDIL2nhvd4AFFlE977BiE+0sMS1eJKUUbQ36MLAWb5oOZKHrphEvqMKA\r\n' + - 'eGDO3qoDqB5TkZC3x38DXBDvAZ01d9s0fvveag==\r\n' + - '-----END CERTIFICATE-----'; - - // local aliases - var net = window.forge.net; - var tls = window.forge.tls; - var http = window.forge.http; - var util = window.forge.util; - - var client; - - function client_init(primed) - { - try - { - var sp = net.createSocketPool({ - flashId: 'socketPool', - policyPort: 19945, - msie: false - }); - client = http.createClient({ - //url: 'https://localhost:4433', - url: 'https://' + window.location.host, - socketPool: sp, - connections: 10, - caCerts: [certificatePem], - // optional cipher suites in order of preference - cipherSuites: [ - tls.CipherSuites.TLS_RSA_WITH_AES_128_CBC_SHA, - tls.CipherSuites.TLS_RSA_WITH_AES_256_CBC_SHA], - verify: function(c, verified, depth, certs) - { - forge.log.debug(cat, - 'TLS certificate ' + depth + ' verified', verified); - // Note: change to always true to test verifying without cert - //return verified; - // FIXME: temporarily accept any cert to allow hitting any bpe - if(verified !== true) - { - forge.log.warning(cat, - 'Certificate NOT verified. Ignored for test.'); - } - return true; - }, - primeTlsSockets: primed - }); - document.getElementById('feedback').innerHTML = - 'http client created'; - } - catch(ex) - { - forge.log.error(cat, ex); - } - - return false; - } - - function client_cleanup() - { - var sp = client.socketPool; - client.destroy(); - sp.destroy(); - document.getElementById('feedback').innerHTML = - 'http client cleaned up'; - return false; - } - - function client_send() - { - /* - var request = http.createRequest({ - method: 'POST', - path: '/', - body: 'echo=foo', - headers: [{'Content-Type': 'application/x-www-form-urlencoded'}] - }); - */ - var request = http.createRequest({ - method: 'GET', - path: '/' - }); - - client.send({ - request: request, - connected: function(e) - { - forge.log.debug(cat, 'connected', e); - }, - headerReady: function(e) - { - forge.log.debug(cat, 'header ready', e); - }, - bodyReady: function(e) - { - forge.log.debug(cat, 'body ready', e); - - // FIXME: current test server doesn't seem to handle keep-alive - // correctly, so close connection - e.socket.close(); - }, - error: function(e) - { - forge.log.error(cat, 'error', e); - } - }); - document.getElementById('feedback').innerHTML = - 'http request sent'; - return false; - } - - function client_send_10() - { - for(var i = 0; i < 10; ++i) - { - client_send(); - } - return false; - } - - function client_stress() - { - for(var i = 0; i < 10; ++i) - { - setTimeout(function() - { - for(var i = 0; i < 10; ++i) - { - client_send(); - } - }, 0); - } - return false; - } - - function client_cookies() - { - var cookie = - { - name: 'test-cookie', - value: 'test-value', - maxAge: -1, - secure: true, - path: '/' - }; - client.setCookie(cookie); - forge.log.debug(cat, 'cookie', client.getCookie('test-cookie')); - } - - function client_clear_cookies() - { - client.clearCookies(); - } - - function websocket_test() - { - // create certificate - var cn = 'client'; - console.log( - 'Generating 512-bit key-pair and certificate for \"' + cn + '\".'); - var keys = forge.pki.rsa.generateKeyPair(512); - console.log('key-pair created.'); - - var cert = forge.pki.createCertificate(); - cert.serialNumber = '01'; - cert.validity.notBefore = new Date(); - cert.validity.notAfter = new Date(); - cert.validity.notAfter.setFullYear( - cert.validity.notBefore.getFullYear() + 1); - var attrs = [{ - name: 'commonName', - value: cn - }, { - name: 'countryName', - value: 'US' - }, { - shortName: 'ST', - value: 'Virginia' - }, { - name: 'localityName', - value: 'Blacksburg' - }, { - name: 'organizationName', - value: 'Test' - }, { - shortName: 'OU', - value: 'Test' - }]; - cert.setSubject(attrs); - cert.setIssuer(attrs); - cert.setExtensions([{ - name: 'basicConstraints', - cA: true - }, { - name: 'keyUsage', - keyCertSign: true, - digitalSignature: true, - nonRepudiation: true, - keyEncipherment: true, - dataEncipherment: true - }, { - name: 'subjectAltName', - altNames: [{ - type: 6, // URI - value: 'http://myuri.com/webid#me' - }] - }]); - // FIXME: add subjectKeyIdentifier extension - // FIXME: add authorityKeyIdentifier extension - cert.publicKey = keys.publicKey; - - // self-sign certificate - cert.sign(keys.privateKey); - - // save cert and private key in PEM format - cert = forge.pki.certificateToPem(cert); - privateKey = forge.pki.privateKeyToPem(keys.privateKey); - console.log('certificate created for \"' + cn + '\": \n' + cert); - - // create websocket - var ws = new WebSocket('ws://localhost:8080'); - console.log('created websocket', ws); - - // create TLS client - var success = false; - var tls = forge.tls.createConnection( - { - server: false, - caStore: [], - sessionCache: {}, - // supported cipher suites in order of preference - cipherSuites: [ - forge.tls.CipherSuites.TLS_RSA_WITH_AES_128_CBC_SHA, - forge.tls.CipherSuites.TLS_RSA_WITH_AES_256_CBC_SHA], - virtualHost: 'server', - verify: function(c, verified, depth, certs) - { - console.log( - 'TLS Client verifying certificate w/CN: \"' + - certs[0].subject.getField('CN').value + - '\", verified: ' + verified + '...'); - // accept any certificate from the server for this test - return true; - }, - connected: function(c) - { - console.log('Client connected...'); - - // send message to server - setTimeout(function() - { - c.prepare('Hello Server'); - }, 1); - }, - getCertificate: function(c, hint) - { - console.log('Client getting certificate ...'); - return cert; - }, - getPrivateKey: function(c, cert) - { - return privateKey; - }, - tlsDataReady: function(c) - { - // send base64-encoded TLS data to server - ws.send(forge.util.encode64(c.tlsData.getBytes())); - }, - dataReady: function(c) - { - var response = c.data.getBytes(); - console.log('Client received \"' + response + '\"'); - success = (response === 'Hello Client'); - c.close(); - }, - closed: function(c) - { - console.log('Client disconnected.'); - if(success) - { - console.log('PASS'); - } - else - { - console.log('FAIL'); - } - }, - error: function(c, error) - { - console.log('Client error: ' + error.message); - } - }); - - ws.onopen = function(evt) - { - console.log('websocket connected'); - - // do TLS handshake - tls.handshake(); - }; - ws.onmessage = function(evt) - { - // base64-decode data and process it - tls.process(forge.util.decode64(evt.data)); - }; - ws.onclose = function(evt) - { - console.log('websocket closed'); - }; - } - - //]]> - </script> - </head> - <body> - <div class="nav"><a href="index.html">Forge Tests</a> / TLS</div> - - <div class="header"> - <h1>TLS Test</h1> - </div> - - <div class="content"> - - <!-- div used to hold the flash socket pool implemenation --> - <div id="socketPool"> - <p>Could not load the flash SocketPool.</p> - </div> - - <fieldset class="section"> - <ul> - <li>Use the controls below to test the HTTP client over TLS.</li> - <li>You currently need a JavaScript console to view the output.</li> - <li>This test connects to a TLS server so you must have one running. The easiest way to run this test is to start the test server with --tls and load this page over HTTPS.</li> - </ul> - </fieldset> - - <fieldset class="section"> - <legend>Controls</legend> - <div id="controls"> - <button id="init" onclick="javascript:return client_init(false);">init</button> - <button id="init_primed" onclick="javascript:return client_init(true);">init primed</button> - <button id="cleanup" onclick="javascript:return client_cleanup();">cleanup</button> - <button id="send" onclick="javascript:return client_send();">send</button> - <button id="send10" onclick="javascript:return client_send_10();">send 10</button> - <button id="stress" onclick="javascript:return client_stress();">stress</button> - <button id="client_cookies" onclick="javascript:return client_cookies();">cookies</button> - <button id="clear_cookies" onclick="javascript:return client_clear_cookies();">clear cookies</button> - <button id="websocket" onclick="javascript:return websocket_test();">websocket test</button> - <button id="websocket-webid" onclick="javascript:return websocket_webid('localhost', 8080);">websocket webid test</button> - </div> - </fieldset> - - <fieldset class="section"> - <legend>Feedback</legend> - <p>Feedback from the flash SocketPool:</p> - <div id="feedback"> - None - </div> - </fieldset> - - </div> - </body> -</html> diff --git a/alarm/node_modules/node-forge/tests/webid.html b/alarm/node_modules/node-forge/tests/webid.html deleted file mode 100644 index 8c8d795..0000000 --- a/alarm/node_modules/node-forge/tests/webid.html +++ /dev/null @@ -1,110 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" - "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> - <head> - <title>Web ID Test</title> - <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js"></script> - <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script> - <script type="text/javascript" src="forge/debug.js"></script> - <script type="text/javascript" src="forge/util.js"></script> - <script type="text/javascript" src="forge/log.js"></script> - <script type="text/javascript" src="forge/task.js"></script> - <script type="text/javascript" src="forge/socket.js"></script> - <script type="text/javascript" src="forge/md5.js"></script> - <script type="text/javascript" src="forge/sha1.js"></script> - <script type="text/javascript" src="forge/hmac.js"></script> - <script type="text/javascript" src="forge/aes.js"></script> - <script type="text/javascript" src="forge/pem.js"></script> - <script type="text/javascript" src="forge/asn1.js"></script> - <script type="text/javascript" src="forge/jsbn.js"></script> - <script type="text/javascript" src="forge/prng.js"></script> - <script type="text/javascript" src="forge/random.js"></script> - <script type="text/javascript" src="forge/oids.js"></script> - <script type="text/javascript" src="forge/rsa.js"></script> - <script type="text/javascript" src="forge/pbe.js"></script> - <script type="text/javascript" src="forge/x509.js"></script> - <script type="text/javascript" src="forge/pki.js"></script> - <script type="text/javascript" src="forge/tls.js"></script> - <script type="text/javascript" src="forge/aesCipherSuites.js"></script> - <script type="text/javascript" src="forge/tlssocket.js"></script> - <script type="text/javascript" src="forge/http.js"></script> - <script type="text/javascript" src="forge/xhr.js"></script> - <script type="text/javascript" src="webid.js"></script> - - <link type="text/css" rel="stylesheet" media="all" href="screen.css" /> - <style type="text/css"> - .ready { color: inherit; background: inherit; } - .testing { color: black; background: yellow; } - .pass{ color: white; background: green; } - .fail{ color: white; background: red; } - </style> - </head> -<body> -<div class="nav"><a href="index.html">Forge Tests</a> / Web ID</div> - -<div class="header"> - <h1>Web ID Tests</h1> -</div> - -<div class="content"> - -<!-- div used to hold the flash socket pool implementation --> -<div id="socketPool"> - <p>Could not load the flash SocketPool.</p> -</div> - -<fieldset class="section"> - <ul> - <li>Use the controls below to test Web ID.</li> - <li>Use 512 bits or less on slower JavaScript implementations.</li> - </ul> -</fieldset> - -<fieldset class="section"> -<legend>Control</legend> - <table> - <tr> - <td rowspan="3"><button id="create">Create Web ID</button></td> - <td>Bits</td> - <td><input id="bits" size=8 value="1024"/></td> - </tr> - <tr> - <td>URI</td> - <td><input id="uri" size=60 value="http://localhost/dataspace/person/myname#this"/></td> - </tr> - <tr> - <td>Common Name</td> - <td><input id="commonName" size=20 value="mycert"/></td> - </tr> - <tr> - <td><button id="show">Show Web IDs</button></td> - <td> </td> - <td> </td> - </tr> - <tr> - <td><button id="clear">Delete Web IDs</button></td> - <td> </td> - <td> </td> - </tr> - <tr> - <td><button id="authenticate">Authenticate using Web ID</button></td> - <td>URI</td> - <td><input id="webid" size=60 value="http://localhost/dataspace/person/myname#this"/></td> - </tr> - </table> -</fieldset> - -<fieldset class="section"> -<legend>Progress</legend> - <div id="progress"></div> -</fieldset> - -<fieldset class="section"> -<legend>Available Web IDs</legend> -<div id="webids"></div> -</fieldset> - -</div> -</body> -</html> diff --git a/alarm/node_modules/node-forge/tests/webid.js b/alarm/node_modules/node-forge/tests/webid.js deleted file mode 100644 index 7c07ab9..0000000 --- a/alarm/node_modules/node-forge/tests/webid.js +++ /dev/null @@ -1,313 +0,0 @@ -/** - * Forge Web ID Tests - * - * @author Dave Longley - * - * Copyright (c) 2010 Digital Bazaar, Inc. All rights reserved. - */ -(function($) -{ - // load flash socket pool - window.forge.socketPool = {}; - window.forge.socketPool.ready = function() - { - // init forge xhr - forge.xhr.init({ - flashId: 'socketPool', - policyPort: 19945, - msie: $.browser.msie, - connections: 10, - caCerts: [], - verify: function(c, verified, depth, certs) - { - // don't care about cert verification for test - return true; - } - }); - }; - swfobject.embedSWF( - 'forge/SocketPool.swf', 'socketPool', '0', '0', '9.0.0', - false, {}, {allowscriptaccess: 'always'}, {}); -})(jQuery); - -jQuery(function($) -{ - var cat = 'forge.tests.webid'; - - // local alias - var forge = window.forge; - - $('#create').click(function() - { - var bits = $('#bits')[0].value; - var uri = $('#uri')[0].value; - var commonName = $('#commonName')[0].value; - forge.log.debug(cat, 'generating ' + bits + - '-bit RSA key-pair and certificate...'); - - // function to create cert - var createCert = function(keys) - { - try - { - var cert = forge.pki.createCertificate(); - cert.serialNumber = '01'; - cert.validity.notBefore = new Date(); - cert.validity.notAfter = new Date(); - cert.validity.notAfter.setFullYear( - cert.validity.notBefore.getFullYear() + 1); - var attrs = [{ - name: 'commonName', - value: commonName - }, { - name: 'countryName', - value: 'US' - }, { - shortName: 'ST', - value: 'Virginia' - }, { - name: 'localityName', - value: 'Blacksburg' - }, { - name: 'organizationName', - value: 'Test' - }, { - shortName: 'OU', - value: 'Test' - }]; - cert.setSubject(attrs); - cert.setIssuer(attrs); - cert.setExtensions([{ - name: 'basicConstraints', - cA: true - }, { - name: 'keyUsage', - keyCertSign: true, - digitalSignature: true, - nonRepudiation: true, - keyEncipherment: true, - dataEncipherment: true - }, { - name: 'subjectAltName', - altNames: [{ - type: 6, // URI - value: uri - }] - }]); - // FIXME: add subjectKeyIdentifier extension - // FIXME: add authorityKeyIdentifier extension - cert.publicKey = keys.publicKey; - - // self-sign certificate - cert.sign(keys.privateKey); - - // verify certificate - forge.log.debug('verified', cert.verify(cert)); - - forge.log.debug(cat, 'certificate:', cert); - //forge.log.debug(cat, - // forge.asn1.prettyPrint(forge.pki.certificateToAsn1(cert))); - var keyPem = forge.pki.privateKeyToPem(keys.privateKey); - var certPem = forge.pki.certificateToPem(cert); - forge.log.debug(cat, keyPem); - forge.log.debug(cat, certPem); - - forge.log.debug(cat, 'storing certificate and private key...'); - try - { - // get flash API - var flashApi = document.getElementById('socketPool'); - - // get web ids collection - var webids = forge.util.getItem( - flashApi, 'forge.test.webid', 'webids'); - webids = webids || {}; - - // add web id - webids[uri] = { - certificate: certPem, - privateKey: keyPem - }; - - // update web ids collection - forge.util.setItem( - flashApi, 'forge.test.webid', 'webids', webids); - - forge.log.debug(cat, 'certificate and private key stored'); - $('#show').click(); - } - catch(ex) - { - forge.log.error(cat, ex); - } - } - catch(ex) - { - forge.log.error(cat, ex, ex.message ? ex.message : ''); - } - }; - - // create key-generation state and function to step algorithm - var progress = $('#progress'); - progress.html('Generating ' + bits + '-bit key-pair.'); - var state = forge.pki.rsa.createKeyPairGenerationState(bits); - var kgTime = +new Date(); - var step = function() - { - // step key-generation - if(!forge.pki.rsa.stepKeyPairGenerationState(state, 1000)) - { - progress.html(progress.html() + '.'); - setTimeout(step, 1); - } - // key-generation complete - else - { - kgTime = +new Date() - kgTime; - forge.log.debug(cat, 'Total key-gen time', kgTime + 'ms'); - createCert(state.keys); - progress.html(progress.html() + 'done. Time=' + kgTime + 'ms'); - } - }; - - // run key-gen algorithm - setTimeout(step, 0); - }); - - $('#show').click(function() - { - forge.log.debug(cat, 'get stored web IDs...'); - try - { - // get flash API - var flashApi = document.getElementById('socketPool'); - - // get web ids collection - var webids = forge.util.getItem( - flashApi, 'forge.test.webid', 'webids'); - webids = webids || {}; - - var html = '<ul>'; - var webid, cert; - for(var key in webids) - { - webid = webids[key]; - cert = forge.pki.certificateFromPem(webid.certificate); - html += '<li><p>' + key + '</p>'; - - var attr; - for(var n = 0; n < cert.subject.attributes.length; ++n) - { - attr = cert.subject.attributes[n]; - html += attr.name + ': ' + attr.value + '<br/>'; - } - - //html += '<p>' + webid.certificate + '</p></li>'; - html += '</li>'; - } - if(html === '<ul>') - { - html = 'None'; - } - else - { - html += '</ul>'; - } - - $('#webids').html(html); - - forge.log.debug(cat, 'Web IDs retrieved'); - } - catch(ex) - { - forge.log.error(cat, ex); - } - }); - - $('#clear').click(function() - { - forge.log.debug(cat, 'clearing all web IDs...'); - try - { - // get flash API - var flashApi = document.getElementById('socketPool'); - forge.util.clearItems(flashApi, 'forge.test.webid'); - $('#webids').html('None'); - forge.log.debug(cat, 'Web IDs cleared'); - } - catch(ex) - { - forge.log.error(cat, ex); - } - }); - - $('#authenticate').click(function() - { - forge.log.debug(cat, 'doing Web ID authentication...'); - - try - { - // get flash API - var flashApi = document.getElementById('socketPool'); - - // get web ids collection - var webids = forge.util.getItem( - flashApi, 'forge.test.webid', 'webids'); - webids = webids || {}; - - var uri = $('#webid')[0].value; - var webid = webids[uri]; - - $.ajax( - { - type: 'GET', - url: '/', - success: function(data, textStatus, xhr) - { - if(data !== '') - { - forge.log.debug(cat, 'authentication completed'); - forge.log.debug(cat, data); - } - else - { - forge.log.error(cat, 'authentication failed'); - } - }, - error: function(xhr, textStatus, errorThrown) - { - forge.log.error(cat, 'authentication failed'); - }, - xhr: function() - { - return forge.xhr.create({ - // FIXME: change URL - url: 'https://localhost:4433', - connections: 10, - caCerts: [], - verify: function(c, verified, depth, certs) - { - // don't care about cert verification for test - return true; - }, - getCertificate: function(c) - { - //forge.log.debug(cat, 'using cert', webid.certificate); - return webid.certificate; - }, - getPrivateKey: function(c) - { - //forge.log.debug(cat, - // 'using private key', webid.privateKey); - return webid.privateKey; - } - }); - } - }); - } - catch(ex) - { - forge.log.error(cat, ex); - } - }); -}); diff --git a/alarm/node_modules/node-forge/tests/ws-webid.js b/alarm/node_modules/node-forge/tests/ws-webid.js deleted file mode 100644 index 2ce5816..0000000 --- a/alarm/node_modules/node-forge/tests/ws-webid.js +++ /dev/null @@ -1,132 +0,0 @@ -var websocket_webid = function(host, port) -{ - var cat = 'ws'; - - // TODO: get private key and certificate from local storage - var privateKey = - '-----BEGIN RSA PRIVATE KEY-----\r\n' + -'MIICXAIBAAKBgQCTmE8QLARsC57Z1OrOaLM6AS3fn70N7BvlU7z7yw8UpcJA/jOl\r\n' + -'NWu7eS9uzuckdVZ9FE0+x3DRvhtDI6K+18dcrUWtl5ADWXcs1QS3/7bGh7IybFyY\r\n' + -'0xT4VzLHcx6K4PNmfkjAQdyOz/EsuRqZ/ngIQ2tdHdkkzdQPECbTvFeG2wIDAQAB\r\n' + -'AoGAds3l7l2QHaxo7GzfqNBMXEdwto2tLxS8C6eQ+pkkBXm72HcF+Vj75AcTMD2p\r\n' + -'fwZYXQxHdV4yqRI+fZeku7uTA/3yBAAvNobbEN5jtHnq0ZTO/HO8HuHkKrCvD8c3\r\n' + -'0rJV6lNIuaARI9jZFf6HVchW3PMjKUpYhTs/sFhRxmsMpTkCQQDu8TPzXRmN1aw8\r\n' + -'tSI2Nyn8QUy9bw/12tlVaZIhrcVCiJl7JHGqSCowTqZlwmJIjd4W0zWjTvS7tEeO\r\n' + -'FaZHtP8lAkEAniGvm8S9zyzmhWRRIuU6EE2dtTbeAa5aSOK3nBaaNu2cHUxWle+J\r\n' + -'8lE4uequ9wqDG1AfOLobPmHReccmOI6N/wJAIP/I1/RkohT/a4bsiaZGsyLlkUf0\r\n' + -'YVTvLP+ege44zv6Ei+A1nnnG8dL64hTdc/27zVUwFDTEUeQM+c99nmudzQJBAApY\r\n' + -'qeTHOqQTjAGuTqC53tKyQV9Z96yke8PJEbpkwDJX2Z8RH5kv0xbHua5wbII9bdab\r\n' + -'p29OvfmW7N3K6fVJXoECQHK8FDC0i8v1Ui8FoBmt+Z1c1+/9TCEE0abUQ6rfOUbm\r\n' + -'XHMMac/n4qDs0OoCjR4u46dpoK+WN7zcg56tToFPVow=\r\n' + -'-----END RSA PRIVATE KEY-----'; - var certificate = - '-----BEGIN CERTIFICATE-----\r\n' + -'MIICgDCCAemgAwIBAgIBATANBgkqhkiG9w0BAQUFADBYMRMwEQYDVQQDEwpKb2hu\r\n' + -'IFNtaXRoMRMwEQYDVQQHEwpCbGFja3NidXJnMREwDwYDVQQIEwhWaXJnaW5pYTEL\r\n' + -'MAkGA1UEBhMCVVMxDDAKBgNVBAoTA0ZvbzAeFw0xMDExMjYxNzUxMzJaFw0xMTEx\r\n' + -'MjYxNzUxMzJaMFgxEzARBgNVBAMTCkpvaG4gU21pdGgxEzARBgNVBAcTCkJsYWNr\r\n' + -'c2J1cmcxETAPBgNVBAgTCFZpcmdpbmlhMQswCQYDVQQGEwJVUzEMMAoGA1UEChMD\r\n' + -'Rm9vMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCTmE8QLARsC57Z1OrOaLM6\r\n' + -'AS3fn70N7BvlU7z7yw8UpcJA/jOlNWu7eS9uzuckdVZ9FE0+x3DRvhtDI6K+18dc\r\n' + -'rUWtl5ADWXcs1QS3/7bGh7IybFyY0xT4VzLHcx6K4PNmfkjAQdyOz/EsuRqZ/ngI\r\n' + -'Q2tdHdkkzdQPECbTvFeG2wIDAQABo1owWDAMBgNVHRMEBTADAQH/MAsGA1UdDwQE\r\n' + -'AwIC9DA7BgNVHREENDAyhjBodHRwOi8vd2ViaWQuZGlnaXRhbGJhemFhci5jb20v\r\n' + -'aWRzLzE1MzQ1NzI2NDcjbWUwDQYJKoZIhvcNAQEFBQADgYEAPNm8albI4w6anynw\r\n' + -'XE/+00sCVks9BbgTcIpRqZPGqSuTRwoYW35isNLDqFqIUdVREMvFrEn3nOlOyKi0\r\n' + -'29G8JtLHFSXZsqf38Zou/bGAhtEH1AVEbM2bRtEnG8IW24jL8hiciz4htxmjnkHN\r\n' + -'JnQ8SQtUSWplGnz0vMFEOv6JbnI=\r\n' + -'-----END CERTIFICATE-----'; - - // create websocket - var ws = new WebSocket('ws://' + host + ':' + port); - forge.log.debug(cat, 'Created WebSocket', ws); - - // create TLS client - var success = false; - var tls = forge.tls.createConnection( - { - server: false, - caStore: [], - sessionCache: {}, - // supported cipher suites in order of preference - cipherSuites: [ - forge.tls.CipherSuites.TLS_RSA_WITH_AES_128_CBC_SHA, - forge.tls.CipherSuites.TLS_RSA_WITH_AES_256_CBC_SHA], - virtualHost: host, - verify: function(c, verified, depth, certs) - { - forge.log.debug(cat, - 'TLS Client verifying certificate w/CN: \"' + - certs[0].subject.getField('CN').value + '\"'); - // accept any certificate from the server for this test - return true; - }, - connected: function(c) - { - forge.log.debug(cat, 'Client connected'); - }, - getCertificate: function(c, hint) - { - forge.log.debug(cat, 'Client using client-certificate'); - return certificate; - }, - getPrivateKey: function(c, cert) - { - return privateKey; - }, - tlsDataReady: function(c) - { - // send base64-encoded TLS data to server - ws.send(forge.util.encode64(c.tlsData.getBytes())); - }, - dataReady: function(c) - { - var response = c.data.getBytes(); - forge.log.debug(cat, 'Client received \"' + response + '\"'); - try - { - response = JSON.parse(response); - success = response.success; - - // TODO: call window.authenticate on response json, just like - // w/flash version - } - catch(ex) {} - c.close(); - }, - closed: function(c) - { - forge.log.debug(cat, 'Client disconnected'); - if(success) - { - forge.log.debug(cat, 'PASS'); - } - else - { - forge.log.debug(cat, 'FAIL'); - } - }, - error: function(c, error) - { - forge.log.debug(cat, 'Client error: ' + error.message); - } - }); - - ws.onopen = function(evt) - { - forge.log.debug(cat, 'WebSocket connected'); - - // do TLS handshake - tls.handshake(); - }; - ws.onmessage = function(evt) - { - // base64-decode data and process it - tls.process(forge.util.decode64(evt.data)); - }; - ws.onclose = function(evt) - { - forge.log.debug(cat, 'WebSocket closed'); - }; -}; - diff --git a/alarm/node_modules/node-forge/tests/ws.js b/alarm/node_modules/node-forge/tests/ws.js deleted file mode 100644 index ba0b39d..0000000 --- a/alarm/node_modules/node-forge/tests/ws.js +++ /dev/null @@ -1,237 +0,0 @@ -// Github: http://github.com/ncr/node.ws.js -// Compatible with node v0.1.91 -// Author: Jacek Becela -// Contributors: -// Michael Stillwell http://github.com/ithinkihaveacat -// Nick Chapman http://github.com/nchapman -// Dmitriy Shalashov http://github.com/skaurus -// Johan Dahlberg -// Andreas Kompanez -// Samuel Cyprian http://github.com/samcyp -// License: MIT -// Based on: http://github.com/Guille/node.websocket.js - -function nano(template, data) { - return template.replace(/\{([\w\.]*)}/g, function (str, key) { - var keys = key.split("."), value = data[keys.shift()]; - keys.forEach(function (key) { value = value[key];}); - return value; - }); -} - -function pack(num) { - var result = ''; - result += String.fromCharCode(num >> 24 & 0xFF); - result += String.fromCharCode(num >> 16 & 0xFF); - result += String.fromCharCode(num >> 8 & 0xFF); - result += String.fromCharCode(num & 0xFF); - return result; -} - -var sys = require("sys"), - net = require("net"), - crypto = require("crypto"), - requiredHeaders = { - 'get': /^GET (\/[^\s]*)/, - 'upgrade': /^WebSocket$/, - 'connection': /^Upgrade$/, - 'host': /^(.+)$/, - 'origin': /^(.+)$/ - }, - handshakeTemplate75 = [ - 'HTTP/1.1 101 Web Socket Protocol Handshake', - 'Upgrade: WebSocket', - 'Connection: Upgrade', - 'WebSocket-Origin: {origin}', - 'WebSocket-Location: {protocol}://{host}{resource}', - '', - '' - ].join("\r\n"), - handshakeTemplate76 = [ - 'HTTP/1.1 101 WebSocket Protocol Handshake', // note a diff here - 'Upgrade: WebSocket', - 'Connection: Upgrade', - 'Sec-WebSocket-Origin: {origin}', - 'Sec-WebSocket-Location: {protocol}://{host}{resource}', - '', - '{data}' - ].join("\r\n"), - flashPolicy = '<cross-domain-policy><allow-access-from domain="*" to-ports="*" /></cross-domain-policy>'; - - - -exports.createSecureServer = function (websocketListener, credentials, options) { - if (!options) options = {}; - options.secure = credentials; - return this.createServer(websocketListener, options); -}; - -exports.createServer = function (websocketListener, options) { - if (!options) options = {}; - if (!options.flashPolicy) options.flashPolicy = flashPolicy; - // The value should be a crypto credentials - if (!options.secure) options.secure = null; - - return net.createServer(function (socket) { - //Secure WebSockets - var wsProtocol = 'ws'; - if(options.secure) { - wsProtocol = 'wss'; - socket.setSecure(options.secure); - } - socket.setTimeout(0); - socket.setNoDelay(true); - socket.setKeepAlive(true, 0); - - var emitter = new process.EventEmitter(), - handshaked = false, - buffer = ""; - - function handle(data) { - buffer += data; - - var chunks = buffer.split("\ufffd"), - count = chunks.length - 1; // last is "" or a partial packet - - for(var i = 0; i < count; i++) { - var chunk = chunks[i]; - if(chunk[0] == "\u0000") { - emitter.emit("data", chunk.slice(1)); - } else { - socket.end(); - return; - } - } - - buffer = chunks[count]; - } - - function handshake(data) { - var _headers = data.split("\r\n"); - - if ( /<policy-file-request.*>/.exec(_headers[0]) ) { - socket.write( options.flashPolicy ); - socket.end(); - return; - } - - // go to more convenient hash form - var headers = {}, upgradeHead, len = _headers.length; - if ( _headers[0].match(/^GET /) ) { - headers["get"] = _headers[0]; - } else { - socket.end(); - return; - } - if ( _headers[ _headers.length - 1 ] ) { - upgradeHead = _headers[ _headers.length - 1 ]; - len--; - } - while (--len) { // _headers[0] will be skipped - var header = _headers[len]; - if (!header) continue; - - var split = header.split(": ", 2); // second parameter actually seems to not work in node - headers[ split[0].toLowerCase() ] = split[1]; - } - - // check if we have all needed headers and fetch data from them - var data = {}, match; - for (var header in requiredHeaders) { - // regexp actual header value - if ( match = requiredHeaders[ header ].exec( headers[header] ) ) { - data[header] = match; - } else { - socket.end(); - return; - } - } - - // draft auto-sensing - if ( headers["sec-websocket-key1"] && headers["sec-websocket-key2"] && upgradeHead ) { // 76 - var strkey1 = headers["sec-websocket-key1"] - , strkey2 = headers["sec-websocket-key2"] - - , numkey1 = parseInt(strkey1.replace(/[^\d]/g, ""), 10) - , numkey2 = parseInt(strkey2.replace(/[^\d]/g, ""), 10) - - , spaces1 = strkey1.replace(/[^\ ]/g, "").length - , spaces2 = strkey2.replace(/[^\ ]/g, "").length; - - if (spaces1 == 0 || spaces2 == 0 || numkey1 % spaces1 != 0 || numkey2 % spaces2 != 0) { - socket.end(); - return; - } - - var hash = crypto.createHash("md5") - , key1 = pack(parseInt(numkey1/spaces1)) - , key2 = pack(parseInt(numkey2/spaces2)); - - hash.update(key1); - hash.update(key2); - hash.update(upgradeHead); - - socket.write(nano(handshakeTemplate76, { - protocol: wsProtocol, - resource: data.get[1], - host: data.host[1], - origin: data.origin[1], - data: hash.digest("binary") - }), "binary"); - - } else { // 75 - socket.write(nano(handshakeTemplate75, { - protocol: wsProtocol, - resource: data.get[1], - host: data.host[1], - origin: data.origin[1] - })); - - } - - handshaked = true; - emitter.emit("connect", data.get[1]); - } - - socket.addListener("data", function (data) { - if(handshaked) { - handle(data.toString("utf8")); - } else { - handshake(data.toString("binary")); // because of draft76 handshakes - } - }).addListener("end", function () { - socket.end(); - }).addListener("close", function () { - if (handshaked) { // don't emit close from policy-requests - emitter.emit("close"); - } - }).addListener("error", function (exception) { - if (emitter.listeners("error").length > 0) { - emitter.emit("error", exception); - } else { - throw exception; - } - }); - - emitter.remoteAddress = socket.remoteAddress; - - emitter.write = function (data) { - try { - socket.write('\u0000', 'binary'); - socket.write(data, 'utf8'); - socket.write('\uffff', 'binary'); - } catch(e) { - // Socket not open for writing, - // should get "close" event just before. - socket.end(); - } - }; - - emitter.end = function () { - socket.end(); - }; - - websocketListener(emitter); // emits: "connect", "data", "close", provides: write(data), end() - }); -}; - diff --git a/alarm/node_modules/node-forge/tests/xhr.html b/alarm/node_modules/node-forge/tests/xhr.html deleted file mode 100644 index aaa721c..0000000 --- a/alarm/node_modules/node-forge/tests/xhr.html +++ /dev/null @@ -1,87 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" - "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> - <head> - <title>Forge XmlHttpRequest Test</title> - <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js"></script> - <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script> - <script type="text/javascript" src="forge/debug.js"></script> - <script type="text/javascript" src="forge/util.js"></script> - <script type="text/javascript" src="forge/log.js"></script> - <script type="text/javascript" src="forge/task.js"></script> - <script type="text/javascript" src="forge/socket.js"></script> - <script type="text/javascript" src="forge/md5.js"></script> - <script type="text/javascript" src="forge/sha1.js"></script> - <script type="text/javascript" src="forge/hmac.js"></script> - <script type="text/javascript" src="forge/aes.js"></script> - <script type="text/javascript" src="forge/pem.js"></script> - <script type="text/javascript" src="forge/asn1.js"></script> - <script type="text/javascript" src="forge/jsbn.js"></script> - <script type="text/javascript" src="forge/prng.js"></script> - <script type="text/javascript" src="forge/random.js"></script> - <script type="text/javascript" src="forge/oids.js"></script> - <script type="text/javascript" src="forge/rsa.js"></script> - <script type="text/javascript" src="forge/pbe.js"></script> - <script type="text/javascript" src="forge/x509.js"></script> - <script type="text/javascript" src="forge/pki.js"></script> - <script type="text/javascript" src="forge/tls.js"></script> - <script type="text/javascript" src="forge/aesCipherSuites.js"></script> - <script type="text/javascript" src="forge/tlssocket.js"></script> - <script type="text/javascript" src="forge/http.js"></script> - <script type="text/javascript" src="forge/xhr.js"></script> - <script type="text/javascript" src="xhr.js"></script> - - <link type="text/css" rel="stylesheet" media="all" href="screen.css" /> - <style type="text/css"> - .ready { color: inherit; background: inherit; } - .testing { color: black; background: yellow; } - .pass{ color: white; background: green; } - .fail{ color: white; background: red; } - </style> - </head> -<body> -<div class="nav"><a href="index.html">Forge Tests</a> / XHR</div> - -<div class="header"> - <h1>XmlHttpRequest Tests</h1> -</div> - -<div class="content"> - -<!-- div used to hold the flash socket pool implemenation --> -<div id="socketPool"> - <p>Could not load the flash SocketPool.</p> -</div> - -<fieldset class="section"> - <ul> - <li>Use the controls below to test the XHR wrapper.</li> - </ul> -</fieldset> - -<fieldset class="section"> -<legend>Control</legend> - <button id="start">Start</button> - <button id="reset">Reset</button> - <br/> - <input id="scroll" type="checkbox" checked="checked" />Scroll Tests - <br/> - <button id="stress">Stress</button> -</fieldset> - -<fieldset class="section"> -<legend>Progress</legend> -Status: <span id="status">?</span><br/> -Pass: <span id="pass">?</span>/<span id="total">?</span><br/> -Fail: <span id="fail">?</span> -</fieldset> - -<fieldset class="section"> -<legend>Tests</legend> -<div id="tests"></div> -</fieldset> - -</div> -</body> -</html> diff --git a/alarm/node_modules/node-forge/tests/xhr.js b/alarm/node_modules/node-forge/tests/xhr.js deleted file mode 100644 index 78f91ad..0000000 --- a/alarm/node_modules/node-forge/tests/xhr.js +++ /dev/null @@ -1,590 +0,0 @@ -/** - * Forge XmlHttpRequest Test - * - * @author Dave Longley - * @author David I. Lehn <dlehn@digitalbazaar.com> - * - * Copyright (c) 2009-2010 Digital Bazaar, Inc. All rights reserved. - */ -(function($) -{ - // load flash socket pool - window.forge.socketPool = {}; - window.forge.socketPool.ready = function() - { - // init forge xhr - forge.xhr.init({ - flashId: 'socketPool', - policyPort: 19945, - msie: $.browser.msie, - connections: 10, - caCerts: [], - verify: function(c, verified, depth, certs) - { - // don't care about cert verification for test - return true; - } - }); - }; - swfobject.embedSWF( - 'forge/SocketPool.swf', 'socketPool', '0', '0', '9.0.0', - false, {}, {allowscriptaccess: 'always'}, {}); -})(jQuery); - -jQuery(function($) -{ - var cat = 'forge.tests.xhr'; - - var tests = []; - var passed = 0; - var failed = 0; - - var init = function() { - passed = failed = 0; - $('.ready,.testing,.pass,.fail') - .removeClass('ready testing pass fail'); - $('#status') - .text('Ready.') - .addClass('ready'); - $('#total').text(tests.length); - $('#pass').text(passed); - $('#fail').text(failed); - $('.expect').empty(); - $('.result').empty(); - $('.time').empty(); - $('.timePer').empty(); - $('#start').removeAttr('disabled'); - }; - - var start = function() - { - $('#start').attr('disabled', 'disabled'); - // meta! use tasks to run the task tests - forge.task.start({ - type: 'test', - run: function(task) { - task.next('starting', function(task) { - forge.log.debug(cat, 'start'); - $('#status') - .text('Testing...') - .addClass('testing') - .removeClass('idle'); - }); - $.each(tests, function(i, test) { - task.next('test', function(task) { - var title = $('li:first', test.container); - if($('#scroll:checked').length === 1) - { - $('html,body').animate({scrollTop: title.offset().top}); - } - title.addClass('testing'); - test.run(task, test); - }); - task.next('test', function(task) { - $('li:first', test.container).removeClass('testing'); - }); - }); - task.next('success', function(task) { - forge.log.debug(cat, 'done'); - if(failed === 0) { - $('#status') - .text('PASS') - .addClass('pass') - .removeClass('testing'); - } else { - // FIXME: should just be hitting failure() below - $('#status') - .text('FAIL') - .addClass('fail') - .removeClass('testing'); - } - }); - }, - failure: function() { - $('#status') - .text('FAIL') - .addClass('fail') - .removeClass('testing'); - } - }); - }; - - $('#start').click(function() { - start(); - }); - - $('#reset').click(function() { - init(); - }); - - var stressStats = - { - sent: 0, - success: 0, - error: 0 - }; - var stressStatsMessage = function() - { - return 'received:' + (stressStats.success + stressStats.error) + '/' + - stressStats.sent + ' errors:' + stressStats.error; - }; - - $('#stress').click(function() { - for(var i = 1; i <= 100; ++i) - { - (function(seqnum) - { - setTimeout(function() - { - $.ajax( - { - type: 'GET', - url: '/result.txt?seq=' + seqnum, - beforeSend: function(xhr) - { - ++stressStats.sent; - xhr.setRequestHeader('Connection', 'close'); - }, - success: function(data, textStatus, xhr) - { - ++stressStats.success; - forge.log.debug(cat, 'xhr connection completed' + - ' seq:' + seqnum + - ' datalen:' + data.length + ' ' + - stressStatsMessage()); - }, - error: function(xhr, textStatus, errorThrown) - { - ++stressStats.error; - forge.log.error(cat, 'xhr connection failed' + - ' seq:' + seqnum + ' ' + - stressStatsMessage(), arguments); - }, - xhr: forge.xhr.create - }); - }, 0); - })(i); - } - return false; - }); - - /** - * Creates a simple XMLHttpRequest wrapper. For testing. - */ - var createWrapper = function() - { - var UNSENT = 0; - var OPENED = 1; - var HEADERS_RECEIVED = 2; - var LOADING = 3; - var DONE = 4; - - var toWrap = new XMLHttpRequest(); - - // create xhr wrapper object - var xhr = - { - // FIXME: an EventListener - onreadystatechange: null, - // FIXME: readonly - readyState: UNSENT, - // FIXME: a string - responseText: null, - // FIXME: a document - responseXML: null, - // FIXME: readonly, returns the HTTP status code - status: 0, - // FIXME: readonly, returns the HTTP status message - statusText: null, - - // FIXME: async, user, and password are optional - open: function(method, url, async, user, password) - { - toWrap.open(method, url, async, user, password); - }, - - setRequestHeader: function(header, value) - { - toWrap.setRequestHeader(header, value); - }, - - // FIXME: data can be a string or a document - send: function(data) - { - toWrap.send(data); - }, - - abort: function() - { - toWrap.abort(); - toWrap.onreadystatechange = null; - toWrap = null; - }, - - // FIXME: return all response headers as a string - getAllResponseHeaders: function() - { - return toWrap.getAllResponseHeaders(); - }, - - // FIXME: return header field value - getResponseHeader: function(header) - { - return toWrap.getResponseHeader(header); - } - }; - - toWrap.onreadystatechange = function() - { - // copy attributes - xhr.readyState = toWrap.readyState; - xhr.responseText = toWrap.responseText; - xhr.responseXML = toWrap.responseXML; - - if(toWrap.readyState == HEADERS_RECEIVED) - { - xhr.status = toWrap.status; - xhr.statusText = toWrap.statusText; - } - - if(xhr.onreadystatechange) - { - //forge.log.debug(cat, 'wrapper orsc', toWrap); - xhr.onreadystatechange(); - } - }; - - return xhr; - }; - - var addTest = function(name, run) - { - var container = $('<ul><li>Test ' + name + '</li><ul/></ul>'); - var expect = $('<li>Expect: <span class="expect"/></li>'); - var result = $('<li>Result: <span class="result"/></li>'); - var time = $('<li>Time: <span class="time"/></li>'); - var timePer = $('<li>Time Per Iteration: <span class="timePer"/></li>'); - $('ul', container) - .append(expect) - .append(result) - .append(time) - .append(timePer); - $('#tests').append(container); - var test = { - container: container, - startTime: null, - run: function(task, test) { - test.startTime = new Date(); - run(task, test); - }, - expect: $('span', expect), - result: $('span', result), - check: function() { - var e = test.expect.text(); - var r = test.result.text(); - (e == r) ? test.pass() : test.fail(); - }, - pass: function(iterations) { - var dt = new Date() - test.startTime; - if(!iterations) - { - iterations = 1; - } - var dti = (dt / iterations); - passed += 1; - $('#pass').text(passed); - $('li:first', container).addClass('pass'); - $('span.time', container).html(dt + 'ms'); - $('span.timePer', container).html(dti + 'ms'); - }, - fail: function(iterations) { - var dt = new Date() - test.startTime; - if(!iterations) - { - iterations = 1; - } - var dti = (dt / iterations); - failed += 1; - $('#fail').text(failed); - $('li:first', container).addClass('fail'); - $('span.time', container).html(dt + 'ms'); - $('span.timePer', container).html(dti + 'ms'); - } - }; - tests.push(test); - }; - - addTest('builtin xhr', function(task, test) - { - task.block(); - - $.ajax( - { - type: 'GET', - url: '/result.txt', - success: function(data) - { - test.expect.html('expected result'); - test.result.html(data); - task.unblock(); - }, - error: function() - { - task.fail(); - } - }); - - task.next(function(task) - { - test.pass(); - }); - }); - - addTest('builtin xhr (10 serial)', function(task, test) - { - var N = 10; - for(var i = 0; i < N; i++) - { - task.next(function(task) - { - task.parent.block(); - - $.ajax( - { - type: 'GET', - url: '/result.txt', - success: function(data, textStatus) - { - test.result.append('.'); - task.parent.unblock(); - }, - error: function(xhr, textStatus, errorThrown) - { - task.fail(N); - } - }); - }); - } - - task.next(function(task) - { - test.pass(N); - }); - }); - - addTest('builtin xhr (10 parallel)', function(task, test) - { - var N = 10; - task.block(N); - for(var i = 0; i < N; i++) - { - $.ajax( - { - type: 'GET', - url: '/result.txt', - success: function(data, textStatus) - { - test.result.append('.'); - task.unblock(); - }, - error: function(xhr, textStatus, errorThrown) - { - task.fail(N); - } - }); - } - - task.next(function(task) - { - test.pass(N); - }); - }); - - // test only works with non-IE - if(!$.browser.msie) - { - addTest('generic wrapper xhr', function(task, test) - { - task.block(); - - $.ajax( - { - type: 'GET', - url: '/result.txt', - success: function(data) - { - test.expect.html('expected result'); - test.result.html(data); - task.unblock(); - }, - error: function() - { - task.fail(); - }, - xhr: createWrapper - }); - - task.next(function(task) - { - test.pass(); - }); - }); - - addTest('generic wrapper xhr (10 serial)', function(task, test) - { - var N = 10; - for(var i = 0; i < N; i++) - { - task.next(function(task) - { - task.parent.block(); - - $.ajax( - { - type: 'GET', - url: '/result.txt', - success: function(data, textStatus) - { - test.result.append('.'); - task.parent.unblock(); - }, - error: function(xhr, textStatus, errorThrown) - { - task.fail(N); - }, - xhr: createWrapper - }); - }); - } - - task.next(function(task) - { - test.pass(N); - }); - }); - - addTest('generic wrapper xhr (10 parallel)', function(task, test) - { - var N = 10; - task.block(N); - for(var i = 0; i < N; i++) - { - $.ajax( - { - type: 'GET', - url: '/result.txt', - success: function(data, textStatus) - { - test.result.append('.'); - task.unblock(); - }, - error: function(xhr, textStatus, errorThrown) - { - task.fail(N); - }, - xhr: createWrapper - }); - } - - task.next(function(task) - { - test.pass(N); - }); - }); - } - - for(var i = 0; i < 3; i++) { - addTest('TLS xhr ' + i, function(task, test) - { - task.block(); - - $.ajax( - { - type: 'GET', - url: '/result.txt', - success: function(data, textStatus, xhr) - { - test.expect.html('expected result'); - test.result.html(data); - task.unblock(); - }, - error: function(xhr, textStatus, errorThrown) - { - task.fail(); - }, - xhr: forge.xhr.create - }); - - task.next(function(task) - { - test.pass(); - }); - }); - } - - addTest('TLS xhr (10 serial)', function(task, test) - { - var N = 10; - for(var i = 0; i < N; i++) - { - task.next(function(task) - { - task.parent.block(); - - $.ajax( - { - type: 'GET', - url: '/result.txt', - success: function(data, textStatus, xhr) - { - test.result.append('.'); - task.parent.unblock(); - }, - error: function(xhr, textStatus, errorThrown) - { - task.fail(N); - }, - xhr: forge.xhr.create - }); - }); - } - - task.next(function(task) - { - test.pass(N); - }); - }); - - addTest('TLS xhr (10 parallel) ' + - '(hit "Reset" then "Start" to speed up - uses SSL session cache)', - function(task, test) - { - var N = 10; - task.block(N); - for(var i = 0; i < N; i++) - { - $.ajax( - { - type: 'GET', - url: '/result.txt', - success: function(data, textStatus, xhr) - { - test.result.append('.'); - task.unblock(); - }, - error: function(xhr, textStatus, errorThrown) - { - task.fail(N); - }, - xhr: forge.xhr.create - }); - } - - task.next(function(task) - { - test.pass(N); - }); - }); - - init(); -}); |