├── .gitignore ├── .npmignore ├── CHANGELOG ├── LICENSE ├── Makefile ├── README.markdown ├── bin └── 1pass ├── index.coffee ├── lib ├── app.coffee ├── contents.coffee ├── database.coffee ├── encryption_keys.coffee ├── password_server.coffee ├── password_server_child.coffee └── renderer.coffee ├── package.json ├── test ├── app_test.coffee ├── contents_test.coffee ├── data │ ├── 1Password.agilekeychain │ │ ├── 1Password.html │ │ ├── a │ │ │ └── default │ │ │ │ ├── files │ │ │ │ ├── 0628D24B0D42482E849CE7FBA52F1C74 │ │ │ │ │ ├── B5BA5EECA36648A4B6F745CF340F93FF │ │ │ │ │ ├── B5BA5EECA36648A4B6F745CF340F93FF.def │ │ │ │ │ └── B5BA5EECA36648A4B6F745CF340F93FF.icn │ │ │ │ ├── 0FAE93A1943E4437AD662A81976811DB │ │ │ │ │ ├── 081BDB815B2B467BBDFCAFE4BE2F7F23 │ │ │ │ │ ├── 081BDB815B2B467BBDFCAFE4BE2F7F23.def │ │ │ │ │ └── 081BDB815B2B467BBDFCAFE4BE2F7F23.icn │ │ │ │ ├── 1EEE501364B843F3B6518597A7999D12 │ │ │ │ │ ├── EF54A0F813B849EEBB14CE6A5E8A8836 │ │ │ │ │ ├── EF54A0F813B849EEBB14CE6A5E8A8836.def │ │ │ │ │ └── EF54A0F813B849EEBB14CE6A5E8A8836.icn │ │ │ │ ├── 3A29ED972AA248EC8CA8D76A8A8021A5 │ │ │ │ │ ├── D0B243177F1842C2ADABEE30F6E03830 │ │ │ │ │ ├── D0B243177F1842C2ADABEE30F6E03830.def │ │ │ │ │ └── D0B243177F1842C2ADABEE30F6E03830.icn │ │ │ │ ├── 3F08E10EBB3248FC8EBCCD443CF1736F │ │ │ │ │ ├── E3DE48839EA3472F9D0124084B73553A │ │ │ │ │ ├── E3DE48839EA3472F9D0124084B73553A.def │ │ │ │ │ └── E3DE48839EA3472F9D0124084B73553A.icn │ │ │ │ ├── 4E8E2C81F2894A819BB508E60B5F337A │ │ │ │ │ ├── 03F3EF9D0F5E48ADBC2B40495E9E3087 │ │ │ │ │ ├── 03F3EF9D0F5E48ADBC2B40495E9E3087.def │ │ │ │ │ └── 03F3EF9D0F5E48ADBC2B40495E9E3087.icn │ │ │ │ ├── 54B92A743AF74FD4ABA18500C80439E6 │ │ │ │ │ ├── 104C280FE94D44759B21920AFC5BD7C8 │ │ │ │ │ ├── 104C280FE94D44759B21920AFC5BD7C8.def │ │ │ │ │ └── 104C280FE94D44759B21920AFC5BD7C8.icn │ │ │ │ ├── 63DF9D8619A544208F9CBCACDA1D5B31 │ │ │ │ │ ├── FC854B9E2D4F45FABFEF1242D9D22E91 │ │ │ │ │ ├── FC854B9E2D4F45FABFEF1242D9D22E91.def │ │ │ │ │ └── FC854B9E2D4F45FABFEF1242D9D22E91.icn │ │ │ │ ├── 65D231DECAAE45AAB9FA9B7523788C1E │ │ │ │ │ ├── D40918B6C4064B2EBAAE10F5083D3F37 │ │ │ │ │ ├── D40918B6C4064B2EBAAE10F5083D3F37.def │ │ │ │ │ └── D40918B6C4064B2EBAAE10F5083D3F37.icn │ │ │ │ ├── 6E29104AB35B409C8D3B0AC0423DA753 │ │ │ │ │ ├── F7E6B5602DA3452D986C9332E4613C93 │ │ │ │ │ ├── F7E6B5602DA3452D986C9332E4613C93.def │ │ │ │ │ └── F7E6B5602DA3452D986C9332E4613C93.icn │ │ │ │ ├── 7AD1A9D39350460D8FE26C70D6A58D96 │ │ │ │ │ ├── 95836378AEF140A5B7A03A42C7C30F0A │ │ │ │ │ ├── 95836378AEF140A5B7A03A42C7C30F0A.def │ │ │ │ │ └── 95836378AEF140A5B7A03A42C7C30F0A.icn │ │ │ │ ├── 81765FA9CA7E408C8C4E24E9201F5D92 │ │ │ │ │ ├── C1A72F0FCF6F4461A844F0B3600D966F │ │ │ │ │ ├── C1A72F0FCF6F4461A844F0B3600D966F.def │ │ │ │ │ └── C1A72F0FCF6F4461A844F0B3600D966F.icn │ │ │ │ ├── A3AD6F1B94B64344823146E5D25C653A │ │ │ │ │ ├── 8AAABA437FF34114B8A11E375977BB06 │ │ │ │ │ ├── 8AAABA437FF34114B8A11E375977BB06.def │ │ │ │ │ └── 8AAABA437FF34114B8A11E375977BB06.icn │ │ │ │ ├── A3D3354DB935478CA162646CAA021D59 │ │ │ │ │ ├── FB912BF2ADC54ACA9166EF1186DE8104 │ │ │ │ │ ├── FB912BF2ADC54ACA9166EF1186DE8104.def │ │ │ │ │ └── FB912BF2ADC54ACA9166EF1186DE8104.icn │ │ │ │ ├── AC5EFDF9FBB4450389F67E497CC15A3A │ │ │ │ │ ├── E183BCCDB0C8448D8179BE15ECB24C4C │ │ │ │ │ ├── E183BCCDB0C8448D8179BE15ECB24C4C.def │ │ │ │ │ └── E183BCCDB0C8448D8179BE15ECB24C4C.icn │ │ │ │ ├── BF64712D60544E3ABE715968C8B92BDA │ │ │ │ │ ├── 58A1367D4BC54E5CAA7DBC63034D7D4D │ │ │ │ │ ├── 58A1367D4BC54E5CAA7DBC63034D7D4D.def │ │ │ │ │ └── 58A1367D4BC54E5CAA7DBC63034D7D4D.icn │ │ │ │ ├── C08769365FB845358516CF63460BA818 │ │ │ │ │ ├── 8EEAFBB5137945D78CEAAF07DE396F98 │ │ │ │ │ ├── 8EEAFBB5137945D78CEAAF07DE396F98.def │ │ │ │ │ └── 8EEAFBB5137945D78CEAAF07DE396F98.icn │ │ │ │ ├── C6B2359919054C32A5747899F736C4B2 │ │ │ │ │ ├── 23D1BE0272344BBFB02262C42667779B │ │ │ │ │ ├── 23D1BE0272344BBFB02262C42667779B.def │ │ │ │ │ └── 23D1BE0272344BBFB02262C42667779B.icn │ │ │ │ ├── DD24D449A13546428423687FEF1C03D4 │ │ │ │ │ ├── 6B8272652C7E48139FF4F86B9BD57F33 │ │ │ │ │ ├── 6B8272652C7E48139FF4F86B9BD57F33.def │ │ │ │ │ └── 6B8272652C7E48139FF4F86B9BD57F33.icn │ │ │ │ ├── EC1C2C874CB444C3BEE538A0EEEF3DFB │ │ │ │ │ ├── BDB6A76A0FB741489C523E838B168671 │ │ │ │ │ ├── BDB6A76A0FB741489C523E838B168671.def │ │ │ │ │ └── BDB6A76A0FB741489C523E838B168671.icn │ │ │ │ ├── F1D5DEC910FC40E3B0C260DF582CF1E5 │ │ │ │ │ ├── 543A923DE7F44418AE7F8CE40E26E169 │ │ │ │ │ ├── 543A923DE7F44418AE7F8CE40E26E169.def │ │ │ │ │ └── 543A923DE7F44418AE7F8CE40E26E169.icn │ │ │ │ ├── F690937594BE40D78F79B9B3B56F35A7 │ │ │ │ │ ├── 42416B0002FF46E59C22ECC91B1DA4BE │ │ │ │ │ ├── 42416B0002FF46E59C22ECC91B1DA4BE.def │ │ │ │ │ └── 42416B0002FF46E59C22ECC91B1DA4BE.icn │ │ │ │ └── FB4C784BA70741FEA47522E984D8BD34 │ │ │ │ │ ├── 6130C132BCBA4ED6BF18018AB28A6D1A │ │ │ │ │ ├── 6130C132BCBA4ED6BF18018AB28A6D1A.def │ │ │ │ │ └── 6130C132BCBA4ED6BF18018AB28A6D1A.icn │ │ │ │ └── thumb │ │ │ │ ├── l │ │ │ │ ├── 3A29ED972AA248EC8CA8D76A8A8021A5 │ │ │ │ └── 3A29ED972AA248EC8CA8D76A8A8021A5.def │ │ │ │ ├── m │ │ │ │ ├── 3A29ED972AA248EC8CA8D76A8A8021A5 │ │ │ │ └── 3A29ED972AA248EC8CA8D76A8A8021A5.def │ │ │ │ └── s │ │ │ │ ├── 3A29ED972AA248EC8CA8D76A8A8021A5 │ │ │ │ └── 3A29ED972AA248EC8CA8D76A8A8021A5.def │ │ ├── config │ │ │ ├── buildnum │ │ │ ├── newsletter │ │ │ └── use-thumbnails │ │ └── data │ │ │ └── default │ │ │ ├── .1password.keys │ │ │ ├── .password.hint │ │ │ ├── 0628D24B0D42482E849CE7FBA52F1C74.1password │ │ │ ├── 0FAE93A1943E4437AD662A81976811DB.1password │ │ │ ├── 1EEE501364B843F3B6518597A7999D12.1password │ │ │ ├── 1password.keys │ │ │ ├── 3A29ED972AA248EC8CA8D76A8A8021A5.1password │ │ │ ├── 3D500EBABDC443168A5601D3081FBEB6.1password │ │ │ ├── 3F08E10EBB3248FC8EBCCD443CF1736F.1password │ │ │ ├── 45EFDC1D10E345C4B6EFB5C9F9D029DE.1password │ │ │ ├── 4E8E2C81F2894A819BB508E60B5F337A.1password │ │ │ ├── 52A31E6F7F2D45E49FEDE7F1AE08BAF3.1password │ │ │ ├── 54B92A743AF74FD4ABA18500C80439E6.1password │ │ │ ├── 5E9DFE25726E4AEE8E1A2F01F6667B77.1password │ │ │ ├── 63DF9D8619A544208F9CBCACDA1D5B31.1password │ │ │ ├── 65D231DECAAE45AAB9FA9B7523788C1E.1password │ │ │ ├── 6D025BB9F3A5432DBB9163A3B5F67C4B.1password │ │ │ ├── 6E29104AB35B409C8D3B0AC0423DA753.1password │ │ │ ├── 7AD1A9D39350460D8FE26C70D6A58D96.1password │ │ │ ├── 81765FA9CA7E408C8C4E24E9201F5D92.1password │ │ │ ├── 81790CA860ED45329CA9E9BF9D0C0804.1password │ │ │ ├── 9E6C4144CC6C45749967D56CF0B72673.1password │ │ │ ├── 9E7429A62EE04DFFBFDCAEFF84A82E80.1password │ │ │ ├── A3AD6F1B94B64344823146E5D25C653A.1password │ │ │ ├── A3D3354DB935478CA162646CAA021D59.1password │ │ │ ├── AC5EFDF9FBB4450389F67E497CC15A3A.1password │ │ │ ├── BF64712D60544E3ABE715968C8B92BDA.1password │ │ │ ├── C08769365FB845358516CF63460BA818.1password │ │ │ ├── C6B2359919054C32A5747899F736C4B2.1password │ │ │ ├── DD24D449A13546428423687FEF1C03D4.1password │ │ │ ├── EC1C2C874CB444C3BEE538A0EEEF3DFB.1password │ │ │ ├── F1D5DEC910FC40E3B0C260DF582CF1E5.1password │ │ │ ├── F32475F595734B16904804137B1FCAF1.1password │ │ │ ├── F690937594BE40D78F79B9B3B56F35A7.1password │ │ │ ├── FB4C784BA70741FEA47522E984D8BD34.1password │ │ │ ├── contents.js │ │ │ └── encryptionKeys.js │ ├── make_dangling_socket.js │ └── renderings.txt ├── database_test.coffee ├── encryption_keys_test.coffee ├── password_server_test.coffee └── renderer_test.coffee ├── vendor ├── gibberish-aes.js ├── sha1.js └── sha256.js └── vendor_exports.js /.gitignore: -------------------------------------------------------------------------------- 1 | /index.js 2 | /lib/*.js 3 | /node_modules 4 | /test/*.js 5 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | /Makefile 2 | /index.coffee 3 | /lib/*.coffee 4 | /node_modules 5 | /test 6 | /vendor 7 | /vendor_exports.js 8 | -------------------------------------------------------------------------------- /CHANGELOG: -------------------------------------------------------------------------------- 1 | == 0.1.0 2013-03-11 2 | 3 | * Allow up to 3 password attempts. 4 | * Remember password for 5 minutes by default (use -r to change). 5 | * Render raw output with -R rather than -r. 6 | 7 | == 0.0.1 2012-09-26 8 | 9 | * Tilde expansion is performed on database path when prompted. 10 | 11 | == 0.0.0 2012-09-26 12 | 13 | * Hi. 14 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License 2 | 3 | Copyright (c) George Ogata 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining 6 | a copy of this software and associated documentation files (the 7 | "Software"), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, 9 | distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so, subject to 11 | the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be 14 | included in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 20 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 22 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | LIBS = $(wildcard index.coffee lib/*.coffee) 2 | LIB_JS = $(LIBS:%.coffee=%.js) 3 | TESTS = $(wildcard test/*.coffee) 4 | TEST_JS = $(TESTS:%.coffee=%.js) 5 | VENDOR_JS = lib/vendor.js 6 | 7 | .DEFAULT_TARGET = default 8 | default: $(LIB_JS) $(VENDOR_JS) 9 | 10 | .PHONY: default test clean 11 | 12 | test: default $(TEST_JS) 13 | mocha --ignore-leaks $(TEST_JS) 14 | 15 | clean: 16 | rm -f $(LIB_JS) 17 | rm -f $(TEST_JS) 18 | rm -f $(VENDOR_JS) 19 | 20 | %.js: %.coffee 21 | coffee -c $< 22 | 23 | $(VENDOR_JS): vendor/*.js vendor_exports.js 24 | cat $^ > $@ 25 | -------------------------------------------------------------------------------- /README.markdown: -------------------------------------------------------------------------------- 1 | # 1Pass 2 | 3 | Unofficial [1Password][1password] reader for the command line. 4 | 5 | [1password]: https://agilebits.com/onepassword 6 | 7 | ## Installation 8 | 9 | Install [NPM], then: 10 | 11 | npm install -g 1pass 12 | 13 | [npm]: https://npmjs.org/ 14 | 15 | ## Usage 16 | 17 | 1pass list [QUERY] 18 | 19 | Lists the items in your keychain. If a QUERY is given, only items matching QUERY 20 | are shown. Otherwise all items are listed. 21 | 22 | 1pass show QUERY 23 | 24 | Lists the full details of all items matching the given QUERY. `show` is the 25 | default command, so unless there's ambiguity, you can shorten this to: 26 | 27 | 1pass QUERY 28 | 29 | ### Queries 30 | 31 | `1pass` lets you be brief with your queries. Try just giving a substring, or 32 | omitting characters in the middle of key names. For example `1pass haw` will 33 | match an item named "howaboutwe.com" (as well as anything else containing 'h', 34 | 'a', 'w' in that order). 35 | 36 | ### Your Keychain 37 | 38 | By default, `1pass` will look for your data in common locations: 39 | 40 | * ~/Library/Application Support/1Password/1Password.agilekeychain 41 | * ~/Dropbox/1Password.agilekeychain 42 | 43 | If there's nothing there, it'll ask. 44 | 45 | You can point `1pass` to your keychain with a `-d` option. 46 | 47 | 1pass -d /path/to/secrets.agilekeychain list 48 | 49 | `1pass` does not remember your selection, nor is there a configuration file 50 | yet. For now, please use a shell alias. 51 | 52 | ## Help 53 | 54 | As always: 55 | 56 | 1pass --help 57 | 58 | ## Disclaimer 59 | 60 | 1Pass is not developed, maintained, or endorsed by Agile Bits, creator of 61 | 1Password. Use at your own risk. 62 | 63 | ## Contributing 64 | 65 | * [Bug reports](https://github.com/oggy/1pass/issues) 66 | * [Source](https://github.com/oggy/1pass) 67 | * Patches: Fork on Github, send pull request. 68 | * Include tests where practical. 69 | * Leave the version alone, or bump it in a separate commit. 70 | 71 | ## Copyright 72 | 73 | Copyright (c) George Ogata. See LICENSE for details. 74 | -------------------------------------------------------------------------------- /bin/1pass: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | var OnePass = require('1pass'); 4 | var app = new OnePass.App(process.argv, process.stdout, process.stderr); 5 | app.run(function(status) { 6 | process.exit(status); 7 | }); 8 | -------------------------------------------------------------------------------- /index.coffee: -------------------------------------------------------------------------------- 1 | Vendor = require './lib/vendor' 2 | Vendor.GibberishAES.size(128) 3 | 4 | module.exports = 5 | App: require './lib/app' 6 | Contents: require './lib/contents' 7 | Database: require './lib/database' 8 | EncryptionKeys: require './lib/encryption_keys' 9 | PasswordServer: require './lib/password_server' 10 | Renderer: require './lib/renderer' 11 | 12 | for name, value of Vendor 13 | module.exports[name] = value 14 | -------------------------------------------------------------------------------- /lib/app.coffee: -------------------------------------------------------------------------------- 1 | util = require 'util' 2 | fs = require 'fs' 3 | pathlib = require 'path' 4 | Commander = require 'commander' 5 | Database = require './database' 6 | PasswordServer = require './password_server' 7 | Renderer = require './renderer' 8 | 9 | class App 10 | constructor: (args, @output, @error, @prompter) -> 11 | @configuration = @parseArgs(args) 12 | @prompter ?= Commander 13 | @defaultDatabasePaths ?= [ 14 | '~/Library/Application Support/1Password/1Password.agilekeychain' 15 | '~/Dropbox/1Password.agilekeychain' 16 | ] 17 | 18 | run: (done) -> 19 | @findDatabase (path) => 20 | @databasePath = path 21 | if path 22 | @database = new Database(path) 23 | command = @configuration.args.shift() 24 | switch command 25 | when 'show', 'list' 26 | this[command](@configuration.args, done) 27 | else 28 | @show([command].concat(@configuration.args), done) 29 | else 30 | done(1) 31 | 32 | show: (args, done) -> 33 | @requirePassword done, => 34 | items = @database.search(args[0]) 35 | i = 0 36 | for item in items 37 | i += 1 38 | renderer = new Renderer(item) 39 | if @configuration.raw 40 | renderer.renderRaw(@output) 41 | else 42 | @output.write("#{i}. ") 43 | renderer.render(@output) 44 | done(0) 45 | 46 | list: (args, done) -> 47 | items = @database.search(args[0]) 48 | for item in items 49 | @output.write((item.name ? '(unnamed)') + '\n') 50 | done(0) 51 | 52 | requirePassword: (done, callback) -> 53 | @getPasswordServer().get (password) => 54 | if password and @database.unlock(password) 55 | callback(true) 56 | else 57 | @promptForPassword(done, callback) 58 | 59 | promptForPassword: (done, callback, attempt=1) -> 60 | @prompter.password 'Password: ', (password) => 61 | if @database.unlock(password) 62 | @getPasswordServer().start password, @configuration.remember * 1000, -> 63 | callback(true) 64 | else 65 | if attempt == 3 66 | @error.write('Sorry.\n') 67 | done(1) 68 | else 69 | @error.write('Try again.\n') 70 | @promptForPassword(done, callback, attempt + 1) 71 | 72 | getPasswordServer: -> 73 | if !@passwordServer 74 | @passwordServer = new PasswordServer(@configuration.config, @configuration.data) 75 | @passwordServer 76 | 77 | parseArgs: (args) -> 78 | version = JSON.parse(fs.readFileSync(__dirname + '/../package.json')).version 79 | # Create a new Commander instance so tests don't share state. 80 | commander = new Commander.constructor() 81 | .version(version) 82 | .usage('[options] [ show | list ] [ QUERY ]') 83 | .description('1Password command line client.') 84 | .option('-d, --data ', 'path to keychain') 85 | .option('-c, --config ', 'path to config dir (default: ~/.1pass)') 86 | .option('-r, --remember ', 'remember password for this long (default: 5min)', Number, 300) 87 | .option('-R, --raw', 'show raw item data (for bug reports)') 88 | .parse(args) 89 | commander.config = @expandPath(commander.config or '~/.1pass') 90 | commander 91 | 92 | findDatabase: (callback) -> 93 | if (explicitPath = @configuration.data) 94 | if fs.existsSync(explicitPath) 95 | callback(explicitPath) 96 | else 97 | @error.write("can't find keychain: #{explicitPath}\n") 98 | callback(null) 99 | else 100 | for path in @defaultDatabasePaths 101 | path = @expandPath(path) 102 | if fs.existsSync(path) 103 | return callback(path) 104 | 105 | @error.write "Cannot find your keychain in the standard locations:\n\n" 106 | for path in @defaultDatabasePaths 107 | @error.write " * #{path}\n" 108 | @error.write "\nThis is typically a folder that ends in .agilekeychain.\n" 109 | 110 | @prompter.prompt "Where is your keychain? ", (response) => 111 | path = @expandPath(response) 112 | if fs.existsSync(path) 113 | callback(path) 114 | else 115 | @error.write("can't find keychain: #{path}\n") 116 | callback(null) 117 | 118 | expandPath: (path) -> 119 | path = path.replace(/^~/, process.env.HOME) 120 | if path[0] != '/' 121 | path = process.cwd() + '/' + path 122 | pathlib.normalize(path) 123 | 124 | module.exports = App 125 | -------------------------------------------------------------------------------- /lib/contents.coffee: -------------------------------------------------------------------------------- 1 | {GibberishAES} = require './vendor' 2 | 3 | class Contents 4 | constructor: (data, fetcher) -> 5 | @items = (new Contents.Item(row, fetcher) for row in data) 6 | 7 | search: (query) -> 8 | matchers = if query then [@matchExact, @matchInclude, @matchFuzzy] else [-> true] 9 | for matcher in matchers 10 | matches = [] 11 | for item in @items 12 | continue if item.trashed == 'Y' 13 | if matcher.call(this, query, item.name) 14 | matches.push(item) 15 | return matches if matches.length > 0 16 | [] 17 | 18 | matchExact: (query, string) -> 19 | string.toLowerCase() == query.toLowerCase() 20 | 21 | matchInclude: (query, string) -> 22 | string.toLowerCase().indexOf(query.toLowerCase()) != -1 23 | 24 | matchFuzzy: (query, string) -> 25 | @matchFuzzyFrom(query.toLowerCase(), string.toLowerCase(), 0, 0) 26 | 27 | matchFuzzyFrom: (query, string, queryIndex, stringIndex) -> 28 | return true if queryIndex >= query.length 29 | i = string.indexOf(query.charAt(queryIndex), stringIndex) 30 | return false if i == -1 31 | @matchFuzzyFrom(query, string, queryIndex + 1, i + 1) 32 | 33 | class Contents.Item 34 | constructor: (row, fetcher) -> 35 | @fetcher = fetcher 36 | [@uuid, @type, @name, @url, @timestamp, @folder, @strength, @trashed] = row 37 | 38 | unlock: (key) -> 39 | return true if @decrypted 40 | raw = GibberishAES.decryptBase64UsingKey(@detail().encrypted, GibberishAES.s2a(key)) 41 | @decrypted = JSON.parse(decodeURIComponent(escape(raw))) 42 | 43 | locked: -> 44 | !@decrypted 45 | 46 | securityLevel: -> 47 | @detail().openContents.securityLevel || 'SL5' 48 | 49 | detail: -> 50 | return @_detail if @_detail 51 | @_detail = @fetcher(@uuid) 52 | 53 | module.exports = Contents 54 | -------------------------------------------------------------------------------- /lib/database.coffee: -------------------------------------------------------------------------------- 1 | fs = require 'fs' 2 | EncryptionKeys = require './encryption_keys' 3 | Contents = require './contents' 4 | 5 | readJSONFile = (path) -> 6 | buffer = fs.readFileSync(path) 7 | JSON.parse(buffer.toString()) 8 | 9 | class Database 10 | constructor: (root) -> 11 | expandPath = (baseName) -> root + '/data/default/' + baseName 12 | 13 | encryptionKeysData = readJSONFile(expandPath('encryptionKeys.js')) 14 | @encryptionKeys = new EncryptionKeys(encryptionKeysData) 15 | 16 | contentsData = readJSONFile(expandPath('contents.js')) 17 | fetcher = (uuid) -> readJSONFile(expandPath(uuid + '.1password')) 18 | @contents = new Contents(contentsData, fetcher) 19 | 20 | unlock: (password) -> 21 | @encryptionKeys.unlock(password) 22 | 23 | locked: -> 24 | @encryptionKeys.locked() 25 | 26 | search: (query) -> 27 | items = @contents.search(query) 28 | if !@locked() 29 | for item in items 30 | securityLevel = item.securityLevel() 31 | key = @encryptionKeys.get(securityLevel) 32 | item.unlock(key.value) 33 | items 34 | 35 | module.exports = Database 36 | -------------------------------------------------------------------------------- /lib/encryption_keys.coffee: -------------------------------------------------------------------------------- 1 | {GibberishAES} = require './vendor' 2 | 3 | class EncryptionKeys 4 | constructor: (data) -> 5 | @masterPassword = null 6 | @keys = {} 7 | for item in data.list 8 | if data[item.level] == item.identifier 9 | @keys[item.level] = new EncryptionKeys.Key(item) 10 | @keys 11 | 12 | unlock: (password) -> 13 | return false if !@keys.SL5 14 | success = @keys.SL5.unlock(password) 15 | @masterPassword = password if success 16 | success 17 | 18 | locked: -> 19 | !@masterPassword 20 | 21 | get: (securityLevel) -> 22 | throw 'database is locked' if @locked() 23 | key = @keys[securityLevel] 24 | return null if !key 25 | key.unlock(@masterPassword) 26 | key 27 | 28 | class EncryptionKeys.Key 29 | constructor: (data) -> 30 | for name, value of data 31 | this[name] = value 32 | 33 | unlock: (password) -> 34 | iterations = Math.max(1000, parseInt(@iterations || 0, 10)) 35 | decrypted = GibberishAES.decryptUsingPBKDF2(@data, password, iterations) 36 | return false if !decrypted 37 | 38 | verification = GibberishAES.decryptBase64UsingKey(@validation, GibberishAES.s2a(decrypted)) 39 | success = verification == decrypted 40 | @value = decrypted if success 41 | success 42 | 43 | module.exports = EncryptionKeys 44 | -------------------------------------------------------------------------------- /lib/password_server.coffee: -------------------------------------------------------------------------------- 1 | fs = require 'fs' 2 | path = require 'path' 3 | net = require 'net' 4 | child_process = require 'child_process' 5 | 6 | class PasswordServer 7 | constructor: (@rcDir, @databasePath) -> 8 | @socketPath = (rcDir + '/sockets/' + databasePath).replace(/\/+/g, '/') 9 | 10 | start: (password, lifetime, callback) -> 11 | @stop => 12 | child = child_process.fork(__dirname + '/password_server_child') 13 | child.on 'message', -> 14 | callback(child.pid) if callback 15 | child.send 16 | rcDir: @rcDir 17 | databasePath: @databasePath 18 | password: password 19 | lifetime: lifetime 20 | 21 | stop: (callback) -> 22 | buffer = [] 23 | fs.exists @socketPath, (exists) => 24 | return callback() if !exists 25 | @_read (pid, pass) => 26 | if !pid 27 | fs.unlink @socketPath, callback 28 | else 29 | @_killAndWait pid, 'SIGTERM', 2000, (result) => 30 | if result 31 | callback() if callback 32 | else 33 | @_killAndWait pid, 'SIGKILL', 2000, => 34 | callback() if callback 35 | 36 | get: (callback) -> 37 | @_read (pid, pass) -> 38 | callback(pass) 39 | 40 | _makeDirs: (dir) -> 41 | unless fs.existsSync(dir) 42 | @_makeDirs path.dirname(dir) 43 | fs.mkdirSync(dir) 44 | 45 | _exec: (password, lifetime, readyCallback) -> 46 | cleanUp = => 47 | fs.unlinkSync(@socketPath) if fs.existsSync(@socketPath) 48 | process.exit() 49 | process.on 'SIGINT' , cleanUp 50 | process.on 'SIGTERM', cleanUp 51 | process.on 'SIGALRM', cleanUp 52 | 53 | server = net.createServer (socket) => 54 | socket.end("#{process.pid}\n#{password}") 55 | server.on 'close', cleanUp 56 | @_makeDirs path.dirname(@socketPath) 57 | setTimeout (-> process.kill(process.pid, 'SIGALRM')), lifetime 58 | server.listen @socketPath, => 59 | fs.chmodSync(@socketPath, 0o600) 60 | readyCallback() 61 | 62 | _read: (callback) -> 63 | buffer = [] 64 | socket = new net.Socket(type: 'unix') 65 | socket.on 'error', -> # don't throw error if connect fails 66 | socket.on 'data', (data) -> buffer.push data 67 | socket.on 'close', -> 68 | [pid, pass] = buffer.join('').split(/\n/) 69 | callback(pid or null, pass or null) 70 | socket.connect path: @socketPath, -> 71 | socket.end() 72 | 73 | _killAndWait: (pid, signal, timeout, callback) -> 74 | return if !pid 75 | process.kill(pid, signal) 76 | @_waitFor 77 | timeout: timeout 78 | condition: (done) => 79 | fs.exists @socketPath, (exists) -> done !exists 80 | complete: callback 81 | 82 | _waitFor: ({timeout, condition, complete}) -> 83 | condition (result) => 84 | if result 85 | complete true 86 | else 87 | if timeout <= 0 88 | complete false 89 | else 90 | sleep = 100 91 | setTimeout (=> 92 | @_waitFor 93 | timeout: timeout - sleep 94 | condition: condition 95 | complete: complete 96 | ), sleep 97 | 98 | module.exports = PasswordServer 99 | -------------------------------------------------------------------------------- /lib/password_server_child.coffee: -------------------------------------------------------------------------------- 1 | PasswordServer = require './password_server' 2 | 3 | process.on 'message', ({rcDir, databasePath, password, lifetime}) -> 4 | server = new PasswordServer(rcDir, databasePath) 5 | server._exec password, lifetime, -> 6 | process.send ready: true 7 | -------------------------------------------------------------------------------- /lib/renderer.coffee: -------------------------------------------------------------------------------- 1 | util = require 'util' 2 | 3 | METADATA = [ 4 | ["Logins", [ 5 | ['webforms.WebForm', "Login", [ 6 | ]] 7 | ]] 8 | 9 | ["Accounts", [ 10 | ['wallet.onlineservices.AmazonS3', "Amazon Web Service", [ 11 | ['path', "Path"] 12 | ['email', "Email"] 13 | ['password', "Password"] 14 | ['access_key_id', "Access Key Id"] 15 | ['access_key', "Secret Access Key"] 16 | ]] 17 | ['wallet.computer.Database', "Database", [ 18 | ['database_type', "Type"] 19 | null 20 | ['hostname', "Server"] 21 | ['port', "Port"] 22 | ['database', "Database"] 23 | ['username', "Username"] 24 | ['password', "Password"] 25 | null 26 | ['sid', "SID"] 27 | ['alias', "Alias"] 28 | ['options', "Connection Options"] 29 | ]] 30 | ['wallet.onlineservices.Email.v2', "Email Account", [ 31 | ['pop_type', "Type"] 32 | ['pop_username', "Username"] 33 | ['pop_server', "Server"] 34 | ['pop_port', "Port Number"] 35 | ['pop_password', "Password"] 36 | ['pop_security', "Security"] 37 | ['pop_authentication', "Authentication Method"] 38 | null 39 | ['smtp_server', "SMTP Server"] 40 | ['smtp_port', "Port Number"] 41 | ['smtp_username', "Username"] 42 | ['smtp_password', "Password"] 43 | ['smtp_security', "Security"] 44 | ['smtp_authentication', "Authentication Method"] 45 | null 46 | ['provider', "Provider"] 47 | ['provider_website', "Provider's Website"] 48 | ['phone_local', "Phone Number (Local)"] 49 | ['phone_tollfree', "Phone Number (Toll Free)"] 50 | ]] 51 | ['wallet.onlineservices.FTP', "FTP Account", [ 52 | ['server', "Server"] 53 | ['path', "Path"] 54 | ['username', "User Name"] 55 | ['password', "Password"] 56 | null 57 | ['provider', "Provider"] 58 | ['provider_website', "Provider's Website"] 59 | ['phone_local', "Phone Number (Local)"] 60 | ['phone_tollfree', "Phone Number (Toll Free)"] 61 | ]] 62 | ['wallet.onlineservices.GenericAccount', "Generic Account", [ 63 | ['username', "Username"] 64 | ['password', "Password"] 65 | ]] 66 | ['wallet.onlineservices.InstantMessenger', "Instant Messenger", [ 67 | ['account_type', "Account Type"] 68 | ['username', "User Name / Email / ID"] 69 | ['password', "Password"] 70 | ['server', "Server"] 71 | ['port', "Port"] 72 | ]] 73 | ['wallet.onlineservices.ISP', "Internet Provider", [ 74 | ['userid', "User ID"] 75 | ['password', "Password"] 76 | ['pin', "PIN"] 77 | ['dialup_number', "Dialup Access Number"] 78 | null 79 | ['website', "Website"] 80 | ['phone_local', "Phone (Local)"] 81 | ['phone_tollfree', "Phone (Toll Free)"] 82 | ]] 83 | ['wallet.onlineservices.DotMac', "MobileMe", [ 84 | ['email', "Apple ID (email)"] 85 | ['member_name', "Member"] 86 | ['password', "Password"] 87 | ['idisk_storage', "Available iDisk Storage"] 88 | ['renewal_date', "Renewal Date", 'date'] 89 | ['activation_key', "Activation Key"] 90 | ]] 91 | ['wallet.computer.UnixServer', "Server", [ 92 | ['url', "URL"] 93 | ['username', "Username"] 94 | ['password', "Password"] 95 | null 96 | ['admin_console_url', "Admin Console URL"] 97 | ['admin_console_username', "Admin Console Username"] 98 | ['admin_console_password', "Console Password"] 99 | null 100 | ['name', "Name"] 101 | ['website', "Website"] 102 | ['support_contact_url', "Support URL"] 103 | ['support_contact_phone', "Support Phone #"] 104 | ]] 105 | ['wallet.computer.Router', "Wireless Router", [ 106 | ['name', "Base Station Name"] 107 | ['password', "Base Station Password"] 108 | ['server', "Server / IP Address"] 109 | ['airport_id', "AirPort ID"] 110 | ['network_name', "Network Name"] 111 | ['wireless_security', "Wireless Security"] 112 | ['wireless_password', "Wireless Network Password"] 113 | ['disk_password', "Attached Storage Password"] 114 | ]] 115 | ['wallet.onlineservices.iTunes', "iTunes", [ 116 | ['username', "Apple ID (email)"] 117 | ['password', "Password"] 118 | ['question', "Security Question"] 119 | ['answer', "Security Answer"] 120 | ]] 121 | ]] 122 | 123 | ["Identities", [ 124 | ['identities.Identity', "Identity", [ 125 | ['firstname', "First Name"] 126 | ['initial', "Initial"] 127 | ['lastname', "Last Name"] 128 | ['sex', "Sex"] 129 | ['birthdate', "Birth Date", 'date'] 130 | ['occupation', "Occupation"] 131 | ['company', "Company"] 132 | ['department', "Department"] 133 | ['jobtitle', "Job Title"] 134 | null 135 | ['country', "Country"] 136 | ['state', "State/Province"] 137 | ['address1', "Address Line 1"] 138 | ['address2', "Address Line 2"] 139 | ['city', "City/Town/Suburb"] 140 | ['zip', "Zip/Postal Code"] 141 | null 142 | ['defphone_local', "DefaultPhone"] 143 | ['homephone_local', "Home"] 144 | ['cellphone_local', "Cell"] 145 | ['busphone_local', "Business"] 146 | null 147 | ['username', "Username"] 148 | ['reminderq', "Reminder Question"] 149 | ['remindera', "Reminder Answer"] 150 | ['email', "Email"] 151 | ['website', "Website"] 152 | ['icq', "ICQ"] 153 | ['skype', "Skype"] 154 | ['aim', "AOL/AIM"] 155 | ['yahoo', "Yahoo"] 156 | ['msn', "MSN"] 157 | ['forumsig', "Forum Signature"] 158 | ]] 159 | ]] 160 | 161 | ["Secure Notes", [ 162 | ['securenotes.SecureNote', "Secure Note", [ 163 | ]] 164 | ]] 165 | 166 | ["Software", [ 167 | ['wallet.computer.License', "Software", [ 168 | ['reg_code', "License Key"] 169 | null 170 | ['reg_name', "Licensed To"] 171 | ['reg_email', "Registered Email"] 172 | ['company', "Company"] 173 | ['download_link', "Download Page"] 174 | null 175 | ['publisher_name', "Publisher"] 176 | ['publisher_website', "Website"] 177 | ['retail_price', "Retail Price"] 178 | ['support_email', "Support Email"] 179 | null 180 | ['order_date', "Purchase Date", 'date'] 181 | ['order_number', "Order Number"] 182 | ['order_total', "Order Total"] 183 | ]] 184 | ]] 185 | 186 | ["Wallet", [ 187 | ['wallet.financial.BankAccountUS', "Bank Account", [ 188 | ['bankName', "Bank Name"] 189 | ['owner', "Name on Account"] 190 | ['accountType', "Type"] 191 | ['routingNo', "Routing Number"] 192 | ['accountNo', "Account Number"] 193 | ['swift', "SWIFT Code"] 194 | ['iban', "IBAN Number"] 195 | ['telephonePin', "PIN"] 196 | null 197 | ['branchPhone', "Phone"] 198 | ['branchAddress', "Address"] 199 | ]] 200 | ['wallet.financial.CreditCard', "Credit Card", [ 201 | ['cardholder', "Cardholder's Name"] 202 | ['type', "Type"] 203 | ['ccnum', "Number"] 204 | ['cvv', "Verification Number"] 205 | ['expiry', "Expiry Date", 'month'] 206 | ['validFrom', "Valid From", 'month'] 207 | null 208 | ['bank', "Issuing Bank"] 209 | ['phoneLocal', "Phone (Local)"] 210 | ['phoneTollFree', "Phone (Toll Free)"] 211 | ['phoneIntl', "Phone (International)"] 212 | ['website', "Website"] 213 | null 214 | ['pin', "PIN"] 215 | ['creditLimit', "Credit Limit"] 216 | ['cashLimit', "Cash Withdrawal Limit"] 217 | ['interest', "Interest Rate"] 218 | ['issuenumber', "Issue Number"] 219 | ]] 220 | ['wallet.government.DriversLicense', "Driver's License", [ 221 | ['fullname', "Full Name"] 222 | ['address', "Address"] 223 | ['birthdate', "Date of Birth", 'date'] 224 | ['sex', "Sex"] 225 | ['height', "Height"] 226 | ['number', "Number"] 227 | ['class', "License Class"] 228 | ['conditions', "Conditions / Restrictions"] 229 | ['state', "State"] 230 | ['country', "Country"] 231 | ['expiry_date', "Expiry Date", 'month'] 232 | ]] 233 | ['wallet.government.HuntingLicense', "Hunting License", [ 234 | ['name', "Full Name"] 235 | ['valid_from', "Valid From", 'date'] 236 | ['expires', "Expires", 'date'] 237 | ['game', "Approved Wildlife"] 238 | ['quota', "Maximum Quota"] 239 | ['state', "State"] 240 | ['country', "Country"] 241 | ]] 242 | ['wallet.membership.Membership', "Membership", [ 243 | ['org_name', "Organization"] 244 | ['website', "Website"] 245 | ['phone', "Telephone"] 246 | ['member_name', "Member Name"] 247 | ['member_since', "Member Since", 'month'] 248 | ['expiry_date', "Expiry Date", 'month'] 249 | ['membership_no', "Membership #"] 250 | ['pin', "Password"] 251 | ]] 252 | ['wallet.government.Passport', "Passport", [ 253 | ['type', "Type"] 254 | ['issuing_country', "Issuing Country"] 255 | ['number', "Number"] 256 | ['fullname', "Full Name"] 257 | ['sex', "Sex"] 258 | ['nationality', "Nationality"] 259 | ['issuing_authority', "Issuing Authority"] 260 | ['birthdate', "Date of Birth", 'date'] 261 | ['birthplace', "Place of Birth"] 262 | ['issue_date', "Issued On", 'date'] 263 | ['expiry_date', "Expiry Date", 'date'] 264 | ]] 265 | ['wallet.membership.RewardProgram', "Reward Program", [ 266 | ['company_name', "Company Name"] 267 | ['member_name', "Member Name"] 268 | ['membership_no', "Membership #"] 269 | ['pin', "PIN"] 270 | null 271 | ['membership_no', "Membership # (Additional)"] 272 | ['member_since', "Member Since", 'month'] 273 | ['customer_service_phone', "Customer Service Phone"] 274 | ['reservations_phone', "Reservations Phone"] 275 | ['website', "Website"] 276 | ]] 277 | ['wallet.government.SsnUS', "Social Security Number", [ 278 | ['name', "Name"] 279 | ['number', "Number"] 280 | ]] 281 | ]] 282 | 283 | ["Generated Passwords", [ 284 | ['passwords.Password', "Password", [ 285 | ['password', "Password"] 286 | ]] 287 | ]] 288 | ] 289 | 290 | TYPE_TO_METADATA = {} 291 | for section in METADATA 292 | [sectionName, sectionData] = section 293 | for sectionDataItem in sectionData 294 | [type, typeDescription, metadata] = sectionDataItem 295 | TYPE_TO_METADATA[type] = [typeDescription, metadata] 296 | 297 | class Renderer 298 | constructor: (@item) -> 299 | if typeDescriptionAndMetadata = TYPE_TO_METADATA[@item.type] 300 | [@typeDescription, @metadata] = typeDescriptionAndMetadata 301 | 302 | render: (stream) -> 303 | if !@metadata 304 | stream.write "Unknown item type: #{@item.type} - raw item data is below.\n" 305 | stream.write "Please file a bug report at https://github.com/oggy/1pass/issues containing\n" 306 | stream.write "this data, masking any sensitive information. Thanks!\n" 307 | @renderRaw(stream) 308 | else 309 | @renderTitle(stream) 310 | if @item.type == 'webforms.WebForm' 311 | @renderFields(stream) 312 | else 313 | @renderDetail(stream) 314 | @renderNotes(stream) 315 | 316 | renderRaw: (stream) -> 317 | stream.write(util.inspect(@item, false, null).replace(/(^|\n)/g, '$1 ') + "\n") 318 | 319 | renderTitle: (stream) -> 320 | stream.write("#{@item.name} (#{@typeDescription})") 321 | if location = @item.detail().location 322 | stream.write(" #{location}") 323 | stream.write('\n') 324 | 325 | renderFields: (stream) -> 326 | for field in @item.decrypted.fields 327 | continue if !field.name and !field.value 328 | stream.write(" #{field.name ? ''}: #{field.value ? ''}\n") 329 | 330 | renderDetail: (stream) -> 331 | data = @item.decrypted 332 | for item in @metadata 333 | if item 334 | [key, description, type] = item 335 | switch type 336 | when 'date' 337 | yy = data[key + '_yy'] 338 | mm = data[key + '_mm']; mm = '0' + mm if parseInt(mm, 10) < 10 339 | dd = data[key + '_dd']; dd = '0' + dd if parseInt(dd, 10) < 10 340 | value = "#{yy}-#{mm}-#{dd}" 341 | when 'month' 342 | yy = data[key + '_yy'] 343 | mm = data[key + '_mm']; mm = '0' + mm if parseInt(mm, 10) < 10 344 | value = "#{yy}-#{mm}" 345 | else 346 | value = data[key] 347 | if value 348 | stream.write(" #{description}: #{value}\n") 349 | else 350 | stream.write("\n") 351 | 352 | renderNotes: (stream) -> 353 | if notes = @item.decrypted.notesPlain 354 | indentedNotes = notes.replace(/(^|\n)/g, ' ') 355 | stream.write("\n Notes:\n#{indentedNotes}\n") 356 | 357 | module.exports = Renderer 358 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "1pass", 3 | "version": "0.1.0", 4 | "description": "1Password reader for the command line.", 5 | "homepage": "https://github.com/oggy/1pass", 6 | "keywords": ["1pass", "1password", "command-line"], 7 | "license": "MIT", 8 | 9 | "author": "George Ogata ", 10 | "bugs": "https://github.com/oggy/1pass/issues", 11 | 12 | "bin": {"1pass": "./bin/1pass"}, 13 | "directories": {"bin": "bin", "lib": "lib", "test": "test"}, 14 | "scripts": {"test": "make test", "prepublish": "make"}, 15 | "dependencies": {"commander": "~1.0.4"}, 16 | "devDependencies": {"mocha": "~1.5.0"}, 17 | "engines": {"node": "> 0.8.0"} 18 | } 19 | -------------------------------------------------------------------------------- /test/app_test.coffee: -------------------------------------------------------------------------------- 1 | assert = require 'assert' 2 | child_process = require 'child_process' 3 | {App} = require '..' 4 | 5 | TMP = "#{__dirname}/tmp" 6 | TEST_TMP = "#{TMP}/app" 7 | testId = 0 8 | keychainPath = 'test/data/1Password.agilekeychain' 9 | 10 | class StringStream 11 | constructor: -> 12 | @data = '' 13 | 14 | write: (data) -> 15 | @data += data 16 | 17 | contains: (pattern) -> 18 | if typeof(pattern) == 'string' 19 | @data.indexOf(pattern) != -1 20 | else 21 | pattern.test(@data) 22 | 23 | class Prompter 24 | constructor: (@databasePasswords, @databasePath=[]) -> 25 | 26 | password: (prompt, callback) -> 27 | password = @databasePasswords.shift() 28 | if password 29 | callback(password) 30 | else 31 | throw 'no more passwords configured' 32 | 33 | prompt: (prompt, callback) -> 34 | if @databasePath 35 | callback(@databasePath) 36 | else 37 | throw 'no database path configured' 38 | 39 | describe 'App', -> 40 | beforeEach -> 41 | @testId = (testId += 1) 42 | @rcDir = "#{TEST_TMP}/rc.#{@testId}" 43 | @makeApp = (args, databasePassword, databasePath, remember=0) -> 44 | remember = (remember or 0).toString() 45 | output = new StringStream() 46 | error = new StringStream() 47 | prompter = new Prompter(databasePassword, databasePath) 48 | new App(['node', 'script', '-c', @rcDir, '-r', remember].concat(args), output, error, prompter) 49 | 50 | after (done) -> 51 | child_process.exec "rm -rf \"#{TEST_TMP}\"", done 52 | 53 | describe '#run', -> 54 | describe 'show', -> 55 | it "returns 0 if the password is correct", (done) -> 56 | app = @makeApp(['-d', keychainPath, 'show', 'my-login'], ['master-password']) 57 | app.run (status) -> 58 | assert.equal(status, 0) 59 | done() 60 | 61 | it "returns 0 if the 3rd password attempt is correct", (done) -> 62 | app = @makeApp(['-d', keychainPath, 'show', 'my-login'], ['wrong', 'wrong', 'master-password']) 63 | app.run (status) -> 64 | assert.equal(status, 0) 65 | done() 66 | 67 | it "returns 1 if 3 password attempts are incorrect", (done) -> 68 | app = @makeApp(['-d', keychainPath, 'show', 'my-login'], ['wrong', 'wrong', 'wrong']) 69 | app.run (status) -> 70 | assert.equal(status, 1) 71 | done() 72 | 73 | it "remembers the password for the given number of seconds", (done) -> 74 | app = @makeApp(['-d', keychainPath, 'show', 'my-login'], ['master-password'], null, 1) 75 | app.run (status) => 76 | assert.equal(status, 0) 77 | app = @makeApp(['-d', keychainPath, 'show', 'my-login'], []) 78 | app.run (status) -> 79 | assert.equal(status, 0) 80 | assert.ok(app.output.contains('my-login')) 81 | done() 82 | 83 | it "does not remember the password for longer than the given number of seconds", (done) -> 84 | app = @makeApp(['-d', keychainPath, 'show', 'my-login'], ['master-password'], null, 0.01) 85 | app.run (status) => 86 | assert.equal(status, 0) 87 | app = @makeApp(['-d', keychainPath, 'show', 'my-login'], ['wrong', 'wrong', 'wrong']) 88 | setTimeout((-> 89 | app.run (status) -> 90 | assert.equal(status, 1) 91 | done() 92 | ), 0.1) 93 | 94 | it "prints the details of matched items", (done) -> 95 | app = @makeApp(['-d', keychainPath, 'show', 'my-login'], ['master-password']) 96 | app.run (status) -> 97 | assert.ok(app.output.contains('my-login')) 98 | assert.ok(app.output.contains('my-username')) 99 | done() 100 | 101 | it "prints raw representations with -R", (done) -> 102 | app = @makeApp(['-d', keychainPath, '-R', 'show', 'my-login'], ['master-password']) 103 | app.run (status) -> 104 | assert.ok(app.output.contains('my-username')) 105 | assert.ok(!app.output.contains('Username:')) 106 | done() 107 | 108 | describe 'list', -> 109 | it "returns 0 without asking for a password", (done) -> 110 | app = @makeApp(['-d', keychainPath, 'list', 'my-login']) 111 | app.run (status) -> 112 | assert.equal(status, 0) 113 | done() 114 | 115 | it "prints the name of matched items, without details", (done) -> 116 | app = @makeApp(['-d', keychainPath, 'list']) 117 | app.run (status) -> 118 | assert.ok(app.output.contains('my-login')) 119 | assert.ok(!app.output.contains('my-username')) 120 | done() 121 | 122 | it "prints all items by default", (done) -> 123 | app = @makeApp(['-d', keychainPath, 'list']) 124 | app.run (status) -> 125 | assert.ok(app.output.contains('my-login')) 126 | assert.ok(app.output.contains('my-social-security-number')) 127 | done() 128 | 129 | it "filters items to those matching the argument, if any", (done) -> 130 | app = @makeApp(['-d', keychainPath, 'list', 'my-login']) 131 | app.run (status) -> 132 | assert.ok(app.output.contains('my-login')) 133 | assert.ok(!app.output.contains('my-social-security-number')) 134 | done() 135 | 136 | it "defaults to running the show command", (done) -> 137 | app = @makeApp(['-d', keychainPath, 'my-login'], ['master-password']) 138 | app.run (status) -> 139 | assert.ok(app.output.contains('my-login')) 140 | assert.ok(app.output.contains('my-username')) 141 | done() 142 | 143 | describe "when a database path is specified and does not exist", -> 144 | beforeEach -> 145 | @app = @makeApp(['-d', 'invalid.agilekeychain', 'list']) 146 | 147 | it "exits with an error", (done) -> 148 | @app.run (status) => 149 | assert.ok(@app.error.contains("can't find keychain: invalid.agilekeychain")) 150 | assert.equal(status, 1) 151 | done() 152 | 153 | describe "when a database path is specified and exists", -> 154 | beforeEach -> 155 | @app = @makeApp(['-d', 'test/data/1Password.agilekeychain', 'list']) 156 | 157 | it "runs the command", (done) -> 158 | @app.run (status) => 159 | assert.ok(@app.output.contains('my-login')) 160 | assert.equal(status, 0) 161 | done() 162 | 163 | describe "when no database path is specified", -> 164 | beforeEach -> 165 | @app = @makeApp(['list']) 166 | 167 | it "can find one in the default paths", (done) -> 168 | @app.defaultDatabasePaths = ['test/data/1Password.agilekeychain'] 169 | @app.run (status) => 170 | assert.ok(@app.output.contains('my-login')) 171 | assert.equal(status, 0) 172 | done() 173 | 174 | describe "when no database path is specified and a valid path is given when prompted", -> 175 | beforeEach -> 176 | @app = @makeApp(['list'], null, 'test/data/1Password.agilekeychain') 177 | 178 | it "runs the command", (done) -> 179 | @app.defaultDatabasePaths = ['invalid.agilekeychain'] 180 | @app.run (status) => 181 | assert.ok(@app.output.contains('my-login')) 182 | assert.equal(status, 0) 183 | done() 184 | 185 | describe "when no database path is specified, and an invalid path is given when prompted", -> 186 | beforeEach -> 187 | @app = @makeApp(['list'], null, 'invalid-prompted.agilekeychain') 188 | 189 | it "exits with an error", (done) -> 190 | @app.defaultDatabasePaths = ['invalid-default.agilekeychain'] 191 | @app.run (status) => 192 | assert.ok(@app.error.contains(/can\'t find keychain:.*invalid-prompted.agilekeychain/)) 193 | assert.equal(status, 1) 194 | done() 195 | -------------------------------------------------------------------------------- /test/contents_test.coffee: -------------------------------------------------------------------------------- 1 | fs = require 'fs' 2 | assert = require 'assert' 3 | {Contents} = require '..' 4 | 5 | makeItem = (attributes) -> 6 | [ 7 | attributes.uuid ? '00000000000000000000000000000000' 8 | attributes.type ? 'webforms.WebForm' 9 | attributes.name ? 'name' 10 | attributes.url ? 'http://example.com' 11 | attributes.date ? 1234567890 12 | attributes.folder ? '' 13 | attributes.passwordStrength ? 0 14 | attributes.trashed ? 'N' 15 | ] 16 | 17 | searchItems = [ 18 | makeItem(uuid: '0', name: 'Bank of Foo') 19 | makeItem(uuid: '1', name: 'bank of foo') 20 | makeItem(uuid: '2', name: 'FOOBAR') 21 | makeItem(uuid: '3', name: 'foobar') 22 | makeItem(uuid: '4', name: 'Bank of Bar') 23 | makeItem(uuid: '5', name: 'bank of bar') 24 | ] 25 | 26 | describe 'Contents', -> 27 | describe '#search', -> 28 | it "without a key returns all items", -> 29 | contents = new Contents(searchItems) 30 | result = contents.search() 31 | assert.deepEqual((item.uuid for item in result), ['0', '1', '2', '3', '4', '5']) 32 | 33 | it "returns items whose name is exactly the key case-insensitively, if any", -> 34 | contents = new Contents(searchItems) 35 | result = contents.search('Bank of Foo') 36 | assert.deepEqual((item.uuid for item in result), ['0', '1']) 37 | 38 | it "otherwise returns items whose name contains the key case-insensitively, if any", -> 39 | contents = new Contents(searchItems) 40 | result = contents.search('oba') 41 | assert.deepEqual((item.uuid for item in result), ['2', '3']) 42 | 43 | it "otherwise returns items whose name fuzzy-matches the key case-insensitively, if any", -> 44 | contents = new Contents(searchItems) 45 | result = contents.search('bof') 46 | assert.deepEqual((item.uuid for item in result), ['0', '1', '4', '5']) 47 | 48 | it "otherwise returns an empty array", -> 49 | contents = new Contents(searchItems) 50 | result = contents.search('xyz') 51 | assert.deepEqual(result, []) 52 | 53 | it "does not return trashed items", -> 54 | items = [ 55 | makeItem(uuid: '0', name: 'a', trashed: 'Y') 56 | makeItem(uuid: '1', name: 'a', trashed: 'N') 57 | ] 58 | contents = new Contents(items) 59 | result = contents.search('a') 60 | assert.deepEqual((item.uuid for item in result), ['1']) 61 | 62 | describe '.Item', -> 63 | describe '#securityLevel', -> 64 | it "is as specified in the openContents if present", -> 65 | data = {openContents: {securityLevel: 'SL3'}} 66 | item = new Contents.Item([], -> data) 67 | assert.equal(item.securityLevel(), 'SL3') 68 | 69 | it "is SL5 if the openContents does not specify a security level", -> 70 | data = {openContents: {}} 71 | item = new Contents.Item([], -> data) 72 | assert.equal(item.securityLevel(), 'SL5') 73 | -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/a/default/files/0628D24B0D42482E849CE7FBA52F1C74/B5BA5EECA36648A4B6F745CF340F93FF: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oggy/1pass/59ef8b158533aa15219602e6421951c496fe5b5f/test/data/1Password.agilekeychain/a/default/files/0628D24B0D42482E849CE7FBA52F1C74/B5BA5EECA36648A4B6F745CF340F93FF -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/a/default/files/0628D24B0D42482E849CE7FBA52F1C74/B5BA5EECA36648A4B6F745CF340F93FF.def: -------------------------------------------------------------------------------- 1 | {"filename":"attachment.txt","encryptionKey":"CB7D05596E224460A6AF6B4E079A3254","contentsHash":"289534da","encrypted":true} -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/a/default/files/0628D24B0D42482E849CE7FBA52F1C74/B5BA5EECA36648A4B6F745CF340F93FF.icn: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oggy/1pass/59ef8b158533aa15219602e6421951c496fe5b5f/test/data/1Password.agilekeychain/a/default/files/0628D24B0D42482E849CE7FBA52F1C74/B5BA5EECA36648A4B6F745CF340F93FF.icn -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/a/default/files/0FAE93A1943E4437AD662A81976811DB/081BDB815B2B467BBDFCAFE4BE2F7F23: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oggy/1pass/59ef8b158533aa15219602e6421951c496fe5b5f/test/data/1Password.agilekeychain/a/default/files/0FAE93A1943E4437AD662A81976811DB/081BDB815B2B467BBDFCAFE4BE2F7F23 -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/a/default/files/0FAE93A1943E4437AD662A81976811DB/081BDB815B2B467BBDFCAFE4BE2F7F23.def: -------------------------------------------------------------------------------- 1 | {"filename":"attachment.txt","encryptionKey":"CB7D05596E224460A6AF6B4E079A3254","contentsHash":"289534da","encrypted":true} -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/a/default/files/0FAE93A1943E4437AD662A81976811DB/081BDB815B2B467BBDFCAFE4BE2F7F23.icn: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oggy/1pass/59ef8b158533aa15219602e6421951c496fe5b5f/test/data/1Password.agilekeychain/a/default/files/0FAE93A1943E4437AD662A81976811DB/081BDB815B2B467BBDFCAFE4BE2F7F23.icn -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/a/default/files/1EEE501364B843F3B6518597A7999D12/EF54A0F813B849EEBB14CE6A5E8A8836: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oggy/1pass/59ef8b158533aa15219602e6421951c496fe5b5f/test/data/1Password.agilekeychain/a/default/files/1EEE501364B843F3B6518597A7999D12/EF54A0F813B849EEBB14CE6A5E8A8836 -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/a/default/files/1EEE501364B843F3B6518597A7999D12/EF54A0F813B849EEBB14CE6A5E8A8836.def: -------------------------------------------------------------------------------- 1 | {"filename":"attachment.txt","encryptionKey":"CB7D05596E224460A6AF6B4E079A3254","contentsHash":"289534da","encrypted":true} -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/a/default/files/1EEE501364B843F3B6518597A7999D12/EF54A0F813B849EEBB14CE6A5E8A8836.icn: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oggy/1pass/59ef8b158533aa15219602e6421951c496fe5b5f/test/data/1Password.agilekeychain/a/default/files/1EEE501364B843F3B6518597A7999D12/EF54A0F813B849EEBB14CE6A5E8A8836.icn -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/a/default/files/3A29ED972AA248EC8CA8D76A8A8021A5/D0B243177F1842C2ADABEE30F6E03830: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oggy/1pass/59ef8b158533aa15219602e6421951c496fe5b5f/test/data/1Password.agilekeychain/a/default/files/3A29ED972AA248EC8CA8D76A8A8021A5/D0B243177F1842C2ADABEE30F6E03830 -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/a/default/files/3A29ED972AA248EC8CA8D76A8A8021A5/D0B243177F1842C2ADABEE30F6E03830.def: -------------------------------------------------------------------------------- 1 | {"filename":"attachment.txt","encryptionKey":"CB7D05596E224460A6AF6B4E079A3254","contentsHash":"289534da","encrypted":true} -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/a/default/files/3A29ED972AA248EC8CA8D76A8A8021A5/D0B243177F1842C2ADABEE30F6E03830.icn: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oggy/1pass/59ef8b158533aa15219602e6421951c496fe5b5f/test/data/1Password.agilekeychain/a/default/files/3A29ED972AA248EC8CA8D76A8A8021A5/D0B243177F1842C2ADABEE30F6E03830.icn -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/a/default/files/3F08E10EBB3248FC8EBCCD443CF1736F/E3DE48839EA3472F9D0124084B73553A: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oggy/1pass/59ef8b158533aa15219602e6421951c496fe5b5f/test/data/1Password.agilekeychain/a/default/files/3F08E10EBB3248FC8EBCCD443CF1736F/E3DE48839EA3472F9D0124084B73553A -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/a/default/files/3F08E10EBB3248FC8EBCCD443CF1736F/E3DE48839EA3472F9D0124084B73553A.def: -------------------------------------------------------------------------------- 1 | {"filename":"attachment.txt","encryptionKey":"CB7D05596E224460A6AF6B4E079A3254","contentsHash":"289534da","encrypted":true} -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/a/default/files/3F08E10EBB3248FC8EBCCD443CF1736F/E3DE48839EA3472F9D0124084B73553A.icn: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oggy/1pass/59ef8b158533aa15219602e6421951c496fe5b5f/test/data/1Password.agilekeychain/a/default/files/3F08E10EBB3248FC8EBCCD443CF1736F/E3DE48839EA3472F9D0124084B73553A.icn -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/a/default/files/4E8E2C81F2894A819BB508E60B5F337A/03F3EF9D0F5E48ADBC2B40495E9E3087: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oggy/1pass/59ef8b158533aa15219602e6421951c496fe5b5f/test/data/1Password.agilekeychain/a/default/files/4E8E2C81F2894A819BB508E60B5F337A/03F3EF9D0F5E48ADBC2B40495E9E3087 -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/a/default/files/4E8E2C81F2894A819BB508E60B5F337A/03F3EF9D0F5E48ADBC2B40495E9E3087.def: -------------------------------------------------------------------------------- 1 | {"filename":"attachment.txt","encryptionKey":"CB7D05596E224460A6AF6B4E079A3254","contentsHash":"289534da","encrypted":true} -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/a/default/files/4E8E2C81F2894A819BB508E60B5F337A/03F3EF9D0F5E48ADBC2B40495E9E3087.icn: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oggy/1pass/59ef8b158533aa15219602e6421951c496fe5b5f/test/data/1Password.agilekeychain/a/default/files/4E8E2C81F2894A819BB508E60B5F337A/03F3EF9D0F5E48ADBC2B40495E9E3087.icn -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/a/default/files/54B92A743AF74FD4ABA18500C80439E6/104C280FE94D44759B21920AFC5BD7C8: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oggy/1pass/59ef8b158533aa15219602e6421951c496fe5b5f/test/data/1Password.agilekeychain/a/default/files/54B92A743AF74FD4ABA18500C80439E6/104C280FE94D44759B21920AFC5BD7C8 -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/a/default/files/54B92A743AF74FD4ABA18500C80439E6/104C280FE94D44759B21920AFC5BD7C8.def: -------------------------------------------------------------------------------- 1 | {"filename":"attachment.txt","encryptionKey":"CB7D05596E224460A6AF6B4E079A3254","contentsHash":"289534da","encrypted":true} -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/a/default/files/54B92A743AF74FD4ABA18500C80439E6/104C280FE94D44759B21920AFC5BD7C8.icn: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oggy/1pass/59ef8b158533aa15219602e6421951c496fe5b5f/test/data/1Password.agilekeychain/a/default/files/54B92A743AF74FD4ABA18500C80439E6/104C280FE94D44759B21920AFC5BD7C8.icn -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/a/default/files/63DF9D8619A544208F9CBCACDA1D5B31/FC854B9E2D4F45FABFEF1242D9D22E91: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oggy/1pass/59ef8b158533aa15219602e6421951c496fe5b5f/test/data/1Password.agilekeychain/a/default/files/63DF9D8619A544208F9CBCACDA1D5B31/FC854B9E2D4F45FABFEF1242D9D22E91 -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/a/default/files/63DF9D8619A544208F9CBCACDA1D5B31/FC854B9E2D4F45FABFEF1242D9D22E91.def: -------------------------------------------------------------------------------- 1 | {"filename":"attachment.txt","encryptionKey":"CB7D05596E224460A6AF6B4E079A3254","contentsHash":"289534da","encrypted":true} -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/a/default/files/63DF9D8619A544208F9CBCACDA1D5B31/FC854B9E2D4F45FABFEF1242D9D22E91.icn: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oggy/1pass/59ef8b158533aa15219602e6421951c496fe5b5f/test/data/1Password.agilekeychain/a/default/files/63DF9D8619A544208F9CBCACDA1D5B31/FC854B9E2D4F45FABFEF1242D9D22E91.icn -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/a/default/files/65D231DECAAE45AAB9FA9B7523788C1E/D40918B6C4064B2EBAAE10F5083D3F37: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oggy/1pass/59ef8b158533aa15219602e6421951c496fe5b5f/test/data/1Password.agilekeychain/a/default/files/65D231DECAAE45AAB9FA9B7523788C1E/D40918B6C4064B2EBAAE10F5083D3F37 -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/a/default/files/65D231DECAAE45AAB9FA9B7523788C1E/D40918B6C4064B2EBAAE10F5083D3F37.def: -------------------------------------------------------------------------------- 1 | {"filename":"attachment.txt","encryptionKey":"CB7D05596E224460A6AF6B4E079A3254","contentsHash":"289534da","encrypted":true} -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/a/default/files/65D231DECAAE45AAB9FA9B7523788C1E/D40918B6C4064B2EBAAE10F5083D3F37.icn: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oggy/1pass/59ef8b158533aa15219602e6421951c496fe5b5f/test/data/1Password.agilekeychain/a/default/files/65D231DECAAE45AAB9FA9B7523788C1E/D40918B6C4064B2EBAAE10F5083D3F37.icn -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/a/default/files/6E29104AB35B409C8D3B0AC0423DA753/F7E6B5602DA3452D986C9332E4613C93: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oggy/1pass/59ef8b158533aa15219602e6421951c496fe5b5f/test/data/1Password.agilekeychain/a/default/files/6E29104AB35B409C8D3B0AC0423DA753/F7E6B5602DA3452D986C9332E4613C93 -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/a/default/files/6E29104AB35B409C8D3B0AC0423DA753/F7E6B5602DA3452D986C9332E4613C93.def: -------------------------------------------------------------------------------- 1 | {"filename":"attachment.txt","encryptionKey":"CB7D05596E224460A6AF6B4E079A3254","contentsHash":"289534da","encrypted":true} -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/a/default/files/6E29104AB35B409C8D3B0AC0423DA753/F7E6B5602DA3452D986C9332E4613C93.icn: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oggy/1pass/59ef8b158533aa15219602e6421951c496fe5b5f/test/data/1Password.agilekeychain/a/default/files/6E29104AB35B409C8D3B0AC0423DA753/F7E6B5602DA3452D986C9332E4613C93.icn -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/a/default/files/7AD1A9D39350460D8FE26C70D6A58D96/95836378AEF140A5B7A03A42C7C30F0A: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oggy/1pass/59ef8b158533aa15219602e6421951c496fe5b5f/test/data/1Password.agilekeychain/a/default/files/7AD1A9D39350460D8FE26C70D6A58D96/95836378AEF140A5B7A03A42C7C30F0A -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/a/default/files/7AD1A9D39350460D8FE26C70D6A58D96/95836378AEF140A5B7A03A42C7C30F0A.def: -------------------------------------------------------------------------------- 1 | {"filename":"attachment.txt","encryptionKey":"CB7D05596E224460A6AF6B4E079A3254","contentsHash":"289534da","encrypted":true} -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/a/default/files/7AD1A9D39350460D8FE26C70D6A58D96/95836378AEF140A5B7A03A42C7C30F0A.icn: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oggy/1pass/59ef8b158533aa15219602e6421951c496fe5b5f/test/data/1Password.agilekeychain/a/default/files/7AD1A9D39350460D8FE26C70D6A58D96/95836378AEF140A5B7A03A42C7C30F0A.icn -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/a/default/files/81765FA9CA7E408C8C4E24E9201F5D92/C1A72F0FCF6F4461A844F0B3600D966F: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oggy/1pass/59ef8b158533aa15219602e6421951c496fe5b5f/test/data/1Password.agilekeychain/a/default/files/81765FA9CA7E408C8C4E24E9201F5D92/C1A72F0FCF6F4461A844F0B3600D966F -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/a/default/files/81765FA9CA7E408C8C4E24E9201F5D92/C1A72F0FCF6F4461A844F0B3600D966F.def: -------------------------------------------------------------------------------- 1 | {"filename":"attachment.txt","encryptionKey":"CB7D05596E224460A6AF6B4E079A3254","contentsHash":"289534da","encrypted":true} -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/a/default/files/81765FA9CA7E408C8C4E24E9201F5D92/C1A72F0FCF6F4461A844F0B3600D966F.icn: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oggy/1pass/59ef8b158533aa15219602e6421951c496fe5b5f/test/data/1Password.agilekeychain/a/default/files/81765FA9CA7E408C8C4E24E9201F5D92/C1A72F0FCF6F4461A844F0B3600D966F.icn -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/a/default/files/A3AD6F1B94B64344823146E5D25C653A/8AAABA437FF34114B8A11E375977BB06: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oggy/1pass/59ef8b158533aa15219602e6421951c496fe5b5f/test/data/1Password.agilekeychain/a/default/files/A3AD6F1B94B64344823146E5D25C653A/8AAABA437FF34114B8A11E375977BB06 -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/a/default/files/A3AD6F1B94B64344823146E5D25C653A/8AAABA437FF34114B8A11E375977BB06.def: -------------------------------------------------------------------------------- 1 | {"filename":"attachment.txt","encryptionKey":"CB7D05596E224460A6AF6B4E079A3254","contentsHash":"289534da","encrypted":true} -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/a/default/files/A3AD6F1B94B64344823146E5D25C653A/8AAABA437FF34114B8A11E375977BB06.icn: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oggy/1pass/59ef8b158533aa15219602e6421951c496fe5b5f/test/data/1Password.agilekeychain/a/default/files/A3AD6F1B94B64344823146E5D25C653A/8AAABA437FF34114B8A11E375977BB06.icn -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/a/default/files/A3D3354DB935478CA162646CAA021D59/FB912BF2ADC54ACA9166EF1186DE8104: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oggy/1pass/59ef8b158533aa15219602e6421951c496fe5b5f/test/data/1Password.agilekeychain/a/default/files/A3D3354DB935478CA162646CAA021D59/FB912BF2ADC54ACA9166EF1186DE8104 -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/a/default/files/A3D3354DB935478CA162646CAA021D59/FB912BF2ADC54ACA9166EF1186DE8104.def: -------------------------------------------------------------------------------- 1 | {"filename":"attachment.txt","encryptionKey":"CB7D05596E224460A6AF6B4E079A3254","contentsHash":"289534da","encrypted":true} -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/a/default/files/A3D3354DB935478CA162646CAA021D59/FB912BF2ADC54ACA9166EF1186DE8104.icn: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oggy/1pass/59ef8b158533aa15219602e6421951c496fe5b5f/test/data/1Password.agilekeychain/a/default/files/A3D3354DB935478CA162646CAA021D59/FB912BF2ADC54ACA9166EF1186DE8104.icn -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/a/default/files/AC5EFDF9FBB4450389F67E497CC15A3A/E183BCCDB0C8448D8179BE15ECB24C4C: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oggy/1pass/59ef8b158533aa15219602e6421951c496fe5b5f/test/data/1Password.agilekeychain/a/default/files/AC5EFDF9FBB4450389F67E497CC15A3A/E183BCCDB0C8448D8179BE15ECB24C4C -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/a/default/files/AC5EFDF9FBB4450389F67E497CC15A3A/E183BCCDB0C8448D8179BE15ECB24C4C.def: -------------------------------------------------------------------------------- 1 | {"filename":"attachment.txt","encryptionKey":"CB7D05596E224460A6AF6B4E079A3254","contentsHash":"289534da","encrypted":true} -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/a/default/files/AC5EFDF9FBB4450389F67E497CC15A3A/E183BCCDB0C8448D8179BE15ECB24C4C.icn: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oggy/1pass/59ef8b158533aa15219602e6421951c496fe5b5f/test/data/1Password.agilekeychain/a/default/files/AC5EFDF9FBB4450389F67E497CC15A3A/E183BCCDB0C8448D8179BE15ECB24C4C.icn -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/a/default/files/BF64712D60544E3ABE715968C8B92BDA/58A1367D4BC54E5CAA7DBC63034D7D4D: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oggy/1pass/59ef8b158533aa15219602e6421951c496fe5b5f/test/data/1Password.agilekeychain/a/default/files/BF64712D60544E3ABE715968C8B92BDA/58A1367D4BC54E5CAA7DBC63034D7D4D -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/a/default/files/BF64712D60544E3ABE715968C8B92BDA/58A1367D4BC54E5CAA7DBC63034D7D4D.def: -------------------------------------------------------------------------------- 1 | {"filename":"attachment.txt","encryptionKey":"CB7D05596E224460A6AF6B4E079A3254","contentsHash":"289534da","encrypted":true} -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/a/default/files/BF64712D60544E3ABE715968C8B92BDA/58A1367D4BC54E5CAA7DBC63034D7D4D.icn: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oggy/1pass/59ef8b158533aa15219602e6421951c496fe5b5f/test/data/1Password.agilekeychain/a/default/files/BF64712D60544E3ABE715968C8B92BDA/58A1367D4BC54E5CAA7DBC63034D7D4D.icn -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/a/default/files/C08769365FB845358516CF63460BA818/8EEAFBB5137945D78CEAAF07DE396F98: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oggy/1pass/59ef8b158533aa15219602e6421951c496fe5b5f/test/data/1Password.agilekeychain/a/default/files/C08769365FB845358516CF63460BA818/8EEAFBB5137945D78CEAAF07DE396F98 -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/a/default/files/C08769365FB845358516CF63460BA818/8EEAFBB5137945D78CEAAF07DE396F98.def: -------------------------------------------------------------------------------- 1 | {"filename":"attachment.txt","encryptionKey":"CB7D05596E224460A6AF6B4E079A3254","contentsHash":"289534da","encrypted":true} -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/a/default/files/C08769365FB845358516CF63460BA818/8EEAFBB5137945D78CEAAF07DE396F98.icn: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oggy/1pass/59ef8b158533aa15219602e6421951c496fe5b5f/test/data/1Password.agilekeychain/a/default/files/C08769365FB845358516CF63460BA818/8EEAFBB5137945D78CEAAF07DE396F98.icn -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/a/default/files/C6B2359919054C32A5747899F736C4B2/23D1BE0272344BBFB02262C42667779B: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oggy/1pass/59ef8b158533aa15219602e6421951c496fe5b5f/test/data/1Password.agilekeychain/a/default/files/C6B2359919054C32A5747899F736C4B2/23D1BE0272344BBFB02262C42667779B -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/a/default/files/C6B2359919054C32A5747899F736C4B2/23D1BE0272344BBFB02262C42667779B.def: -------------------------------------------------------------------------------- 1 | {"filename":"attachment.txt","encryptionKey":"CB7D05596E224460A6AF6B4E079A3254","contentsHash":"289534da","encrypted":true} -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/a/default/files/C6B2359919054C32A5747899F736C4B2/23D1BE0272344BBFB02262C42667779B.icn: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oggy/1pass/59ef8b158533aa15219602e6421951c496fe5b5f/test/data/1Password.agilekeychain/a/default/files/C6B2359919054C32A5747899F736C4B2/23D1BE0272344BBFB02262C42667779B.icn -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/a/default/files/DD24D449A13546428423687FEF1C03D4/6B8272652C7E48139FF4F86B9BD57F33: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oggy/1pass/59ef8b158533aa15219602e6421951c496fe5b5f/test/data/1Password.agilekeychain/a/default/files/DD24D449A13546428423687FEF1C03D4/6B8272652C7E48139FF4F86B9BD57F33 -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/a/default/files/DD24D449A13546428423687FEF1C03D4/6B8272652C7E48139FF4F86B9BD57F33.def: -------------------------------------------------------------------------------- 1 | {"filename":"attachment.txt","encryptionKey":"CB7D05596E224460A6AF6B4E079A3254","contentsHash":"289534da","encrypted":true} -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/a/default/files/DD24D449A13546428423687FEF1C03D4/6B8272652C7E48139FF4F86B9BD57F33.icn: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oggy/1pass/59ef8b158533aa15219602e6421951c496fe5b5f/test/data/1Password.agilekeychain/a/default/files/DD24D449A13546428423687FEF1C03D4/6B8272652C7E48139FF4F86B9BD57F33.icn -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/a/default/files/EC1C2C874CB444C3BEE538A0EEEF3DFB/BDB6A76A0FB741489C523E838B168671: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oggy/1pass/59ef8b158533aa15219602e6421951c496fe5b5f/test/data/1Password.agilekeychain/a/default/files/EC1C2C874CB444C3BEE538A0EEEF3DFB/BDB6A76A0FB741489C523E838B168671 -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/a/default/files/EC1C2C874CB444C3BEE538A0EEEF3DFB/BDB6A76A0FB741489C523E838B168671.def: -------------------------------------------------------------------------------- 1 | {"filename":"attachment.txt","encryptionKey":"CB7D05596E224460A6AF6B4E079A3254","contentsHash":"289534da","encrypted":true} -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/a/default/files/EC1C2C874CB444C3BEE538A0EEEF3DFB/BDB6A76A0FB741489C523E838B168671.icn: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oggy/1pass/59ef8b158533aa15219602e6421951c496fe5b5f/test/data/1Password.agilekeychain/a/default/files/EC1C2C874CB444C3BEE538A0EEEF3DFB/BDB6A76A0FB741489C523E838B168671.icn -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/a/default/files/F1D5DEC910FC40E3B0C260DF582CF1E5/543A923DE7F44418AE7F8CE40E26E169: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oggy/1pass/59ef8b158533aa15219602e6421951c496fe5b5f/test/data/1Password.agilekeychain/a/default/files/F1D5DEC910FC40E3B0C260DF582CF1E5/543A923DE7F44418AE7F8CE40E26E169 -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/a/default/files/F1D5DEC910FC40E3B0C260DF582CF1E5/543A923DE7F44418AE7F8CE40E26E169.def: -------------------------------------------------------------------------------- 1 | {"filename":"attachment.txt","encryptionKey":"CB7D05596E224460A6AF6B4E079A3254","contentsHash":"289534da","encrypted":true} -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/a/default/files/F1D5DEC910FC40E3B0C260DF582CF1E5/543A923DE7F44418AE7F8CE40E26E169.icn: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oggy/1pass/59ef8b158533aa15219602e6421951c496fe5b5f/test/data/1Password.agilekeychain/a/default/files/F1D5DEC910FC40E3B0C260DF582CF1E5/543A923DE7F44418AE7F8CE40E26E169.icn -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/a/default/files/F690937594BE40D78F79B9B3B56F35A7/42416B0002FF46E59C22ECC91B1DA4BE: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oggy/1pass/59ef8b158533aa15219602e6421951c496fe5b5f/test/data/1Password.agilekeychain/a/default/files/F690937594BE40D78F79B9B3B56F35A7/42416B0002FF46E59C22ECC91B1DA4BE -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/a/default/files/F690937594BE40D78F79B9B3B56F35A7/42416B0002FF46E59C22ECC91B1DA4BE.def: -------------------------------------------------------------------------------- 1 | {"filename":"attachment.txt","encryptionKey":"CB7D05596E224460A6AF6B4E079A3254","contentsHash":"289534da","encrypted":true} -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/a/default/files/F690937594BE40D78F79B9B3B56F35A7/42416B0002FF46E59C22ECC91B1DA4BE.icn: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oggy/1pass/59ef8b158533aa15219602e6421951c496fe5b5f/test/data/1Password.agilekeychain/a/default/files/F690937594BE40D78F79B9B3B56F35A7/42416B0002FF46E59C22ECC91B1DA4BE.icn -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/a/default/files/FB4C784BA70741FEA47522E984D8BD34/6130C132BCBA4ED6BF18018AB28A6D1A: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oggy/1pass/59ef8b158533aa15219602e6421951c496fe5b5f/test/data/1Password.agilekeychain/a/default/files/FB4C784BA70741FEA47522E984D8BD34/6130C132BCBA4ED6BF18018AB28A6D1A -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/a/default/files/FB4C784BA70741FEA47522E984D8BD34/6130C132BCBA4ED6BF18018AB28A6D1A.def: -------------------------------------------------------------------------------- 1 | {"filename":"attachment.txt","encryptionKey":"CB7D05596E224460A6AF6B4E079A3254","contentsHash":"289534da","encrypted":true} -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/a/default/files/FB4C784BA70741FEA47522E984D8BD34/6130C132BCBA4ED6BF18018AB28A6D1A.icn: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oggy/1pass/59ef8b158533aa15219602e6421951c496fe5b5f/test/data/1Password.agilekeychain/a/default/files/FB4C784BA70741FEA47522E984D8BD34/6130C132BCBA4ED6BF18018AB28A6D1A.icn -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/a/default/thumb/l/3A29ED972AA248EC8CA8D76A8A8021A5: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oggy/1pass/59ef8b158533aa15219602e6421951c496fe5b5f/test/data/1Password.agilekeychain/a/default/thumb/l/3A29ED972AA248EC8CA8D76A8A8021A5 -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/a/default/thumb/l/3A29ED972AA248EC8CA8D76A8A8021A5.def: -------------------------------------------------------------------------------- 1 | {"encryptionKey":"CB7D05596E224460A6AF6B4E079A3254","encrypted":true,"contentsHash":"ca2bff88"} -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/a/default/thumb/m/3A29ED972AA248EC8CA8D76A8A8021A5: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oggy/1pass/59ef8b158533aa15219602e6421951c496fe5b5f/test/data/1Password.agilekeychain/a/default/thumb/m/3A29ED972AA248EC8CA8D76A8A8021A5 -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/a/default/thumb/m/3A29ED972AA248EC8CA8D76A8A8021A5.def: -------------------------------------------------------------------------------- 1 | {"encryptionRequired":false,"encrypted":false,"contentsHash":"4d764364"} -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/a/default/thumb/s/3A29ED972AA248EC8CA8D76A8A8021A5: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oggy/1pass/59ef8b158533aa15219602e6421951c496fe5b5f/test/data/1Password.agilekeychain/a/default/thumb/s/3A29ED972AA248EC8CA8D76A8A8021A5 -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/a/default/thumb/s/3A29ED972AA248EC8CA8D76A8A8021A5.def: -------------------------------------------------------------------------------- 1 | {"encryptionRequired":false,"encrypted":false,"contentsHash":"63c14b2c"} -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/config/buildnum: -------------------------------------------------------------------------------- 1 | 31499 -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/config/newsletter: -------------------------------------------------------------------------------- 1 | 1347254118 -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/config/use-thumbnails: -------------------------------------------------------------------------------- 1 | y -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/data/default/.1password.keys: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SL3 6 | 6EE8D721E87248D2BA08329003B23C56 7 | SL5 8 | CB7D05596E224460A6AF6B4E079A3254 9 | list 10 | 11 | 12 | data 13 | U2FsdGVkX18kNofF295yoryIbjC0gQA4QTVbrjE2JNQ0Hh6NJmVESaT2opYIX2J4dZaysH/7OnisBnqwbjiNAirbtpz/OEGoyZJiGilQUKieRExa/55axoTpkai1hS1DhTItfeVgNc59GUNo3T4WtCZvpNv/xlb1ArFutiJ4XTVGNYsjmhL6WffC5qJGJTY+qY8SMZTNDIDiTVM1eQMFu/C0WGPPYPTNSMr7G86/JrDt4xP+csv03cZWHSDDnGcY0WwJPxzf0Yd/5vhFvYBdwGYQFyuaz+FJyh2M596WDh5Wauegv1l4DXbmB7cHOnGI0KnwlaUsRk6PYAc5+uzf6FxXtt/iGjLZWf8PhduhLI1xGxvYQL9eaTfUe/rs9UFsxgT9f7I3262HtUQ553h2cBwddp6qZ+wUCovEK8dP2YSJluGSVRheB+GUUyX5W3rde3EKfhrJVVf8BPPgY9IFCRKGxENX++y+MO0wCzO2XD2an6A1zrUYxr4LwZmGzBF+a/pafyrHTKxCQgPTAlEUrDT1vocowKcK2QZMQ7E24XdyjpToyz5Fe/XpaGZ5KHwU3KphM0gSysAF0W3AGSWYGO2DXfiSvUtgUOhNlqAEcegVcaUmg7icHG6qNgG68sxFyPmoyzQfk/ZhQ5ruogjxs52Kx++955i+O6ujJ+7ID9azDhRgV/tN/jmhNlSP91F3ey1f4uJURe128e16WhhM4sG2Q3Vq201bNL3cRG9oPLEEUHUTt3DbLFcJt29unyxKUmkoXTaG2hJw8qX1yzOFdfLBY3U58SdyWwXuqsmCeGK+UvTIi0r8BIhCG8aMmS2PGIm8xTinFrK2dp2wls0yzcFprRc10SSqJ88A9C8O+6pCgEpbgeuR3QhgoFytOwinC012qfDBhoLms8tUxwZ8yEsPjuHffNdoP5SAg+G3w5jIk9zd8vCkwOhXFcrjBhVD8FjP0dU9YOGCK9iTwVP2f70l1UpPFLm7FMrwh/hX6EKgWk5J44s8eLbmYn9QUlBdMMWU1xOzRJVACxtUVL9Ymt0kfXp/ZMnp/new1KxAl1VHG9/AgSF2x9yrGMsgpxOssnsftS+ekFz/TtS8HzyopBUHLPEP5jmuOvVSu96LUwFowcqS0S/zxR7hIE38NeNRFg0sF+bVlLYEGnN+fAzqfodO9eeiRczXBcUelyehgwon/0dg592OXRqEVq0EMqOfuNDrtUKdTZ1ZTfuXy4rjduK3RXNPeF/4RDDMEjs2UNgCk6gus2v2yvcBa22nKuVOGpq9Hf9L185lBiCKmucdNeM4pelIdfmZSSRN3TAjexchOW3bKzDZhqO3WEc716Ic0ETqCj1l3fuF6/yELQG5I7pgj/Lq2tXQhaI6EfEQTEgWhIXaSSSPY8Fn/0ndQaKn 14 | identifier 15 | 6EE8D721E87248D2BA08329003B23C56 16 | iterations 17 | 10000 18 | level 19 | SL3 20 | validation 21 | U2FsdGVkX18HfNCJEqhTvj89fBcgvzn0g8ghnCUhb5pqI/IS8yw7+o5I5pwm/Dd11rgPKgHzTSrMyc4sgLgBpsZfzDstfe0CS9XfAhbteFhRZN5vuwsaRneAed8BDLFRaA/uZj3iBosJpWky70vnqw81jYjUeHeXL5EXnK06GuovUCumw2AzrtpHX4FQPJxaLrx8s/mllYCMEQ0fywkysQ+lobcdceFbHFqOnGbLZfDDzcwoDzDsLrszyMJhWcY2hc/nbD3aHJcB28YoNQOHeiq0j6fbpsR8BOkyqWQAzlIRiwDv9ROW5Zn4l79AcQhoKejLJTOG3cERvnBns/3MCR4rJksAWoB7h762GQ/srSpjh8SHyFevDSSfUjg/0tzt4rF0lzFx5wwFdonMWNCky5PtUQ5IC2RcKRhCuLMgHqoxLyXBCDgBV6XWjhE6WXlaNu/HF9YPhKc9HnxjtQZkyBiPbN4je5wS/bYfP/zpzUqH9sXo1VHLYlnIw93+MHSqIsMUhMIJOjG850JZwVXw9lDsybu6zLYDER+zEcPaBIIXZ7aL0Bf5Y6oYgmOggrojkfYO0MHhMOmYhDijCXJZqceLMAUQeFfDovdXkpBKOX5t+idbEhJX44pkLb2YGtavH4tco4jAY6n80/N6KdL/ikAyq8DcURwhjajcAQFV31gAuAeQHdiTYumu3JkGitn7TwIdLRk1esf5nsdid9EEFYRPdpbmrAecRwV2Z6ZL+4jvFndpubnN3Ys9aIIAKa3rXlKSsUakB+/ntfb3JHj0APs+Cw2juatUllqNYOsmMz29rBjDX//39Dq65loPjJKq12MV83MvX0N4GlP926WTa6mXf0hL+fvGfKxSSrplKtCYpflkN1AO7Nv8rnrid47XWAVxRPNM9UmhMpPacYLhh/3i3JtbkmL9FcSgpB+K1vgM4LOwebsar1Gm9gdmLkmpN3mktrQL+ZE0FZAC+nQO8ap3yZ91TVFIsvZgK59sbofpxBIJx3Qy3A5j9piDUvW3/7zd1FY8FyAmBkry1kY4x4z5ZoDmHh6c0BGGvg4qW/b4LvnD2Yi8I2TpHgdI9zEEoho15rWOUqlijdK1JS6o9fHrBSnlXuZVHurJ+HF8zaXnaTt+/nv7RgyopJQhgr5sMU7RiR2GYg+o82ZRMaoY6cPl8eJM+WAb/ZIuvTn/JZ/6NDnXKRGB40sgOVNV2d9BETzrhbQ5/D1zsmOdSOfzxUabO5Aw6VX57d2paXQSXDJioYJw0FafVwBSCX3gkXuIdc+/F0e+BV65MBqeJfnCwVP47pjLm2yYftVZCV2yULBzzoeD0Qbvo08QN4MybztRSc/FX53H6Vt3lyxo6h7BxiTS5Y7ff3i0ZpnSS8LtxXGysUb3JaiaO8UeS3IV2Eef 22 | 23 | 24 | data 25 | U2FsdGVkX1/2nv06QLYyeKoNehrq2F3qgxobNWxPyxBWGdkpJIJxqiz9KHQtbiW2pTI1OqE3vdNLIGiclsWTx4kpke7Ww2sxt6B3gZvswruhy2ZQo0DtDzhwQA8IZMbCTvjtDkLwL8ORqwLMAzq9CFEa7ZHQ29j7Bq5zI/QfvTwMh9DLra5PojgJ1BNWagT2gdFV65JgKH68ZoKbsWJzzpYkI4osO1c5zwl3kwTNXd/09teTTV5zZfXA9ksjDwbpmsxz36w0rpPbElC0SYadJHOGZ/YttGBAp+XvMMWprDfkzd1dFVc89TIWRLUzi0zIO1sit4aoLfrPEwm0RKZAtNj8ZIXg98mBFsI3pHYMS0h0ureQ/SInwic6jNka/CYNp6PAApDvTmPI5oL7qipw2rGHjeDjJY3M8pOGJ0FT2nM6qgQKlPckNcRlRtmz02D7wLCiGIbc+yvVCHiDdpaS+WfZVf0qPcr/Ecur4bjJBuRFDcIsQgFbfXLuv9ecfXBYVgsNw79JPmNQKz39HlKF+2X3rXiQzS7WG2soHdnVK4VSZpnIGMZip1AyijtxWMRScbdt2woOTyRv3cs5asXd0ZMD+iR9h4t1V/Fl4RtwJtfBMTq/fhwv9YoFlz6FJfUd7P13CfGi0CFaU9DrmoNKu8Q3lwr03t575BHu2IkhWkSHll79H/btERZnr3IJ2rLZWdn3bh0PLnisBQ2qDQWP9DIhrHjRbW5tp1ffqXnBnndGIBi20hfJyTzimXEJZ3pIt5YfUlos09AboAqYX9DI95bEvwtxmMNNGW2/Wc5iZX9+rdQXL10wfItlbV+XUsK8RIzngGKAMuNZMcl9BQ6BU/5ravoZQgaMJZHC0cx+yJHPI1ciJr9pCss/Sqmu9agO5V0oiXSeIBZUp/X7aOat/LJBJydd0b+YFQ3Pjk9cyTYQbNQUkOZkGsUF/ykwmCI10fW9aRZ5GBZSlPqQYpK1HPYhjAELpLXsyNZ5HwEoOFVLOcLjKc4sZ6Kl0GMgz2FLM1i76lRaOToZUaRqeq8QTqL4XTvKMZhVzWF9gEtFAXtYSAoHa5mSTgpZmRtKSmyh89vjcQPEa2m+aAqf2Idx3gHgaGHw+xqoLaaBvMWBlM5mlWg1z9VNu+6VqMSS83gTm2KP5sShouHegr3PjRvDA/cROdv5WvimzJPj8p+L/UDkfeMfGcbZKc9/rsB1LYwtyLU/4ADTF3I4v963QeEh017MwFuXwmmoYv7A7GRSJ4kLETRLvhWiFjH1xohJPN6nrn/dB35SgnRNIi1XFNNb2lRKzoc3nazAJ6t7MY6H///oE2ml8WtoIxRkU14vtTZvUOdb33Pr2zNPmuANd7/xlf5WOQQwWwWbtbAovJ2SJxM9p+c7FnfMl9YR2nm10raZ 26 | identifier 27 | CB7D05596E224460A6AF6B4E079A3254 28 | iterations 29 | 10000 30 | level 31 | SL5 32 | validation 33 | U2FsdGVkX1/n/cdXWqhEbKWtiJ7f9R74xSQVjqH9rAC5DvIDr8JzM0hKWuScsCaAxjmCR2nMYmkFK9OsMWSCNUFFBY+E7uXVC6amcUJIMt37jU5gvJ35zKOIoV8Wy3DxD/XXOZPL6zomgUIvqj66u8juamiuAK7uV2J+cNC/54rVuwHai7Ip/YWEyXYl/BgxmHatDUv8RExT617tWLKRObmXnEcyQq6+PttkvwDdiSsfyrzduEvVHvgFB4JJ8fNnpkgl4SQipvDymxMoBxW4IpP4ACa/qzuDwScKggJCk4bo9liSh7zW4gwV40dDdDNCwVZNhQ14AxyLlkDEhzgFq77RHnJafiekU0qm5rLn1O5U/tgjUpbbTqENv+gQBKLNb0+NHxsQ/U4PNibWHKxtS7hCjrdYUGsBGtxfdVDD8yMGH8i6dz2VnHx/l+M+PhKWBIxTWvGYCLewZg24VW0/X5IOSItbFtHu6QWqS0xUOtS9wqieBwWi2sl+nJ8E4DJryzpav68l9ejH+3tGKVZWYkzoNV+Z8hawctio/I4cfwttdAW0eRdTsrFT50dEFmfBmnW9wWYedkZpTm7liyW+5f0e5672TloEz3aMTdHW7X0TVC/gWxIQqTHXxGAp78AgwZZXcEfvChl3mLCqlhdZH+P90LyGybnaCEW3hhgsjd7Kh7e35e0A/cUcBD5nxDk7//6mltgVn0roZgCZnDnbg/u02/V3IiMeFp8Bs3AtPdyV04ZKdJrxRzObl/1URnfadwgvR42b2jRA2LqxW2TORFEwsX/TVmjxmPVvPUXsXvetd9CYO1pe1Q0nBisno1IrYtIrAT1eIsGIlLnBUhg4WEGmGTJDbWLE//fA4qP6L6HyVzkiOQQZRGg8CHc39cjcmOmyjZftKhefZB3fM0HMZOdOF9v1paOFxs+JG+p2b0fxwxJF7BFv3yXvpf25/sOBIb2WehZRInjs+2FghwAZbLj99fteb/lB1OiCBkJVM/QtW0UthtGbLuJ8OXAGHxzxLNV6BSP92FSNglU3uCbw2uQVLyhcxEJvz5+oXoHP51kB9SEhwmJbahBjGaxOpqk5gW1mrua5OiLLQcwgbND/eetBkcI4Ga3Ma+CZ4faTs74KDspSIJmc1K2fRt0OnGmF/rSM1w7eFYuYuigrQhdYU/ZQlC008QUL6HxQlLmKRW8N35O/+aRKL1qG7MnMoglqp3xaYrlaX1JYRtADCuwZiUia7YvhKL2DnlGrddThfcLYqLavqKXqVC/lTYErlVN2VKScnHG0AsgINKypVBNl0t69/jKYUsd+x4gPe1yWi/gRqqH0TBOdjWi41Bx0FNfzAZHz+J3Rf/T7OUNWibN5Sf1EqldT2ZJxeouzDVQ552VfEKUXqyQhQtBUFn4kskiy 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/data/default/.password.hint: -------------------------------------------------------------------------------- 1 | my-password-hint -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/data/default/0628D24B0D42482E849CE7FBA52F1C74.1password: -------------------------------------------------------------------------------- 1 | {"uuid":"0628D24B0D42482E849CE7FBA52F1C74","updatedAt":1347253415,"locationKey":"","openContents":{"tags":["tag-one","tag-two"],"contentsHash":"711b2cd5"},"keyID":"CB7D05596E224460A6AF6B4E079A3254","title":"my-bank-account","location":"","encrypted":"U2FsdGVkX186TiDGUd8k/E+oi8h6ttns0AaarHRkhlE1+DJveobYU0rWaO/Ka+CAKyOOYvYsMDVQfihdEE3heTHEfGEQcfbV1Pe+6Rn7KMtpGADTGq/MIp5uNqVXhEm0qimkQEjqTvBltoXAsDmPNTLa5KQl2fOkGDU6DEd6/cTGVzFDcZTBrCrLZMUJzVtLWt7WW1K6xTLqVvyO5brBjz9wlZpT8ZCmGLdu3PlHWqYr97qFeb1mKYO9c6AuWtoQvPY8+d6gwRCPHSkenAd+9QmJCoKEKpQ4hI0OxNZEeSTzltmAa7KAJhKe22HhjKzR9Bn4oh8djnBMynwDuOXmvSVYQ0r7xppjpCrFFfpfpF2GWPAYbA9ceZeJJXCYhRHpavd1n9doGaLndtTSoGS859UqQrKn3QOQy0j8z2Qk2BA=\u0000","createdAt":1347253370,"typeName":"wallet.financial.BankAccountUS"} -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/data/default/0FAE93A1943E4437AD662A81976811DB.1password: -------------------------------------------------------------------------------- 1 | {"uuid":"0FAE93A1943E4437AD662A81976811DB","updatedAt":1347252692,"locationKey":"","openContents":{"tags":["tag-one","tag-two"],"contentsHash":"eb13bcc0"},"keyID":"CB7D05596E224460A6AF6B4E079A3254","title":"my-email-account","location":"","encrypted":"U2FsdGVkX1/PFU7JgHu8Kno9WA+JySsDEI0yDOJFx86iyfJUhPzn9t88Qscb9fQwQlWU4uhbr3xsINBMD7o+CtuQ52F6U8H1VGOeSUjIURZuFshC9FWtGHdqTqWxskN689zRxooVfuWxOicCO8zL8PMSRMyYfQ2faBYfM4+e2wJBiBLEae5gMAyJx1My8QeG03lAJoggF+lgHneKeqRM9rdVISGYGOzcvyVCEMvkCblzDIiYqU4heqXawrhsJpswnN+BOgPP34ZuU4ooZKxQumpEi93hnRc7X14moyl4WS2PIaUxXtlNf+zU/D0GE8/ZlKaFC2D9B8e7riw8znCGIOWsOOcbBw1koFy/Ru7DinyR3pZ4xNq/IIUSNt00SqIVO5h1xN6nqkKVWGlbo1dfztkOWxqqFOIpUVfaVmDUFZpWhEGrNZ0DLG5/81j/dbcJrcgwZpPXzjbrjhxx2bDPJL2wLmLG4AR6cMioPnzRRb2GbbB67aMMZpdpmZPVQl2kyeojYsofapJ5njtfDehG+4ebpVPI1Llfq4U0JiCCbPJIWRXJJW8lZqiKx6eQFRV2Kt+vDFY5uIjtSqNeIYToTStO7WdVU2D0BpBkWHFn7ecw9NrgViZoFExz88MVqqRbPqZaqrhPGZDINrIP9vSMMxicrNVn4MdLf2g7tcmRT1sSB8hqFYMVZyUzMRqGMLC4racRKySXKb3bxA+45AmPIA==\u0000","createdAt":1347252617,"typeName":"wallet.onlineservices.Email.v2"} -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/data/default/1EEE501364B843F3B6518597A7999D12.1password: -------------------------------------------------------------------------------- 1 | {"uuid":"1EEE501364B843F3B6518597A7999D12","updatedAt":1347253363,"locationKey":"","openContents":{"contentsHash":"5f0d6fe5","tags":["tag-one","tag-two"],"securityLevel":"SL3"},"keyID":"6EE8D721E87248D2BA08329003B23C56","title":"my-software","location":"","encrypted":"U2FsdGVkX1/lYiF1hp1w+GLkZaeAGxLm71KUvGGEb6rnkNsyrh+muWQKGx6l0FOl7KwoEhXIbz+FoBB2XoQaSqNW4dBR5lPbB3JULgPt1Bf45U35r3BugsnnG+BYuWZhB0b96HH8vjR36wNoqmsZJPNaKs9dwAU/SB5rX6vqPGFrGrq1XsKLBtSI2cOggz/I23bNwcik+0DH3vZXcIOkpLyBGvt1vlY3tl9Dpnd9Yi0yWQ1k7a9r/N/x3vGxRbw9ln1qnC0M/cSokAgZDt2oNBW5qICsusj+uo74vIK3WG0w7/FJtgEBsjVzDleqmjFgErIi3fSMuvGcxyrACstgFFZLba6VK1wyFkA8jY0FVnxtGBwUGbjgFYVRevU85oj9JoUczSiowKwuzXCbP/wG93/TzUh3v4R3IIuuF74vMIQbF+eY8UEMNiIzj3t0cNYAv5FkNGLHMo7sR4gTBaQSzCHX7+Ti0XUdQIt89r6SzR6WAU8huXdTD4XPTCR6lyPXt7o4vy7KFHAZgW3/1jzrbWDgt8JJLeHYz9a4Rz8Sm0ZMl6Ji0JTbloKqUZgD/2CsX2xi26zQjP436FZpEglvnxrW1PnLUgegOXD0k6PfTX0YslLiejUmbO1EbQgdEaZcx7lpPa5Z16bkDGpeRm/2TQ==\u0000","createdAt":1347253300,"typeName":"wallet.computer.License"} -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/data/default/1password.keys: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SL3 6 | 6EE8D721E87248D2BA08329003B23C56 7 | SL5 8 | CB7D05596E224460A6AF6B4E079A3254 9 | list 10 | 11 | 12 | data 13 | U2FsdGVkX18kNofF295yoryIbjC0gQA4QTVbrjE2JNQ0Hh6NJmVESaT2opYIX2J4dZaysH/7OnisBnqwbjiNAirbtpz/OEGoyZJiGilQUKieRExa/55axoTpkai1hS1DhTItfeVgNc59GUNo3T4WtCZvpNv/xlb1ArFutiJ4XTVGNYsjmhL6WffC5qJGJTY+qY8SMZTNDIDiTVM1eQMFu/C0WGPPYPTNSMr7G86/JrDt4xP+csv03cZWHSDDnGcY0WwJPxzf0Yd/5vhFvYBdwGYQFyuaz+FJyh2M596WDh5Wauegv1l4DXbmB7cHOnGI0KnwlaUsRk6PYAc5+uzf6FxXtt/iGjLZWf8PhduhLI1xGxvYQL9eaTfUe/rs9UFsxgT9f7I3262HtUQ553h2cBwddp6qZ+wUCovEK8dP2YSJluGSVRheB+GUUyX5W3rde3EKfhrJVVf8BPPgY9IFCRKGxENX++y+MO0wCzO2XD2an6A1zrUYxr4LwZmGzBF+a/pafyrHTKxCQgPTAlEUrDT1vocowKcK2QZMQ7E24XdyjpToyz5Fe/XpaGZ5KHwU3KphM0gSysAF0W3AGSWYGO2DXfiSvUtgUOhNlqAEcegVcaUmg7icHG6qNgG68sxFyPmoyzQfk/ZhQ5ruogjxs52Kx++955i+O6ujJ+7ID9azDhRgV/tN/jmhNlSP91F3ey1f4uJURe128e16WhhM4sG2Q3Vq201bNL3cRG9oPLEEUHUTt3DbLFcJt29unyxKUmkoXTaG2hJw8qX1yzOFdfLBY3U58SdyWwXuqsmCeGK+UvTIi0r8BIhCG8aMmS2PGIm8xTinFrK2dp2wls0yzcFprRc10SSqJ88A9C8O+6pCgEpbgeuR3QhgoFytOwinC012qfDBhoLms8tUxwZ8yEsPjuHffNdoP5SAg+G3w5jIk9zd8vCkwOhXFcrjBhVD8FjP0dU9YOGCK9iTwVP2f70l1UpPFLm7FMrwh/hX6EKgWk5J44s8eLbmYn9QUlBdMMWU1xOzRJVACxtUVL9Ymt0kfXp/ZMnp/new1KxAl1VHG9/AgSF2x9yrGMsgpxOssnsftS+ekFz/TtS8HzyopBUHLPEP5jmuOvVSu96LUwFowcqS0S/zxR7hIE38NeNRFg0sF+bVlLYEGnN+fAzqfodO9eeiRczXBcUelyehgwon/0dg592OXRqEVq0EMqOfuNDrtUKdTZ1ZTfuXy4rjduK3RXNPeF/4RDDMEjs2UNgCk6gus2v2yvcBa22nKuVOGpq9Hf9L185lBiCKmucdNeM4pelIdfmZSSRN3TAjexchOW3bKzDZhqO3WEc716Ic0ETqCj1l3fuF6/yELQG5I7pgj/Lq2tXQhaI6EfEQTEgWhIXaSSSPY8Fn/0ndQaKn 14 | identifier 15 | 6EE8D721E87248D2BA08329003B23C56 16 | iterations 17 | 10000 18 | level 19 | SL3 20 | validation 21 | U2FsdGVkX18HfNCJEqhTvj89fBcgvzn0g8ghnCUhb5pqI/IS8yw7+o5I5pwm/Dd11rgPKgHzTSrMyc4sgLgBpsZfzDstfe0CS9XfAhbteFhRZN5vuwsaRneAed8BDLFRaA/uZj3iBosJpWky70vnqw81jYjUeHeXL5EXnK06GuovUCumw2AzrtpHX4FQPJxaLrx8s/mllYCMEQ0fywkysQ+lobcdceFbHFqOnGbLZfDDzcwoDzDsLrszyMJhWcY2hc/nbD3aHJcB28YoNQOHeiq0j6fbpsR8BOkyqWQAzlIRiwDv9ROW5Zn4l79AcQhoKejLJTOG3cERvnBns/3MCR4rJksAWoB7h762GQ/srSpjh8SHyFevDSSfUjg/0tzt4rF0lzFx5wwFdonMWNCky5PtUQ5IC2RcKRhCuLMgHqoxLyXBCDgBV6XWjhE6WXlaNu/HF9YPhKc9HnxjtQZkyBiPbN4je5wS/bYfP/zpzUqH9sXo1VHLYlnIw93+MHSqIsMUhMIJOjG850JZwVXw9lDsybu6zLYDER+zEcPaBIIXZ7aL0Bf5Y6oYgmOggrojkfYO0MHhMOmYhDijCXJZqceLMAUQeFfDovdXkpBKOX5t+idbEhJX44pkLb2YGtavH4tco4jAY6n80/N6KdL/ikAyq8DcURwhjajcAQFV31gAuAeQHdiTYumu3JkGitn7TwIdLRk1esf5nsdid9EEFYRPdpbmrAecRwV2Z6ZL+4jvFndpubnN3Ys9aIIAKa3rXlKSsUakB+/ntfb3JHj0APs+Cw2juatUllqNYOsmMz29rBjDX//39Dq65loPjJKq12MV83MvX0N4GlP926WTa6mXf0hL+fvGfKxSSrplKtCYpflkN1AO7Nv8rnrid47XWAVxRPNM9UmhMpPacYLhh/3i3JtbkmL9FcSgpB+K1vgM4LOwebsar1Gm9gdmLkmpN3mktrQL+ZE0FZAC+nQO8ap3yZ91TVFIsvZgK59sbofpxBIJx3Qy3A5j9piDUvW3/7zd1FY8FyAmBkry1kY4x4z5ZoDmHh6c0BGGvg4qW/b4LvnD2Yi8I2TpHgdI9zEEoho15rWOUqlijdK1JS6o9fHrBSnlXuZVHurJ+HF8zaXnaTt+/nv7RgyopJQhgr5sMU7RiR2GYg+o82ZRMaoY6cPl8eJM+WAb/ZIuvTn/JZ/6NDnXKRGB40sgOVNV2d9BETzrhbQ5/D1zsmOdSOfzxUabO5Aw6VX57d2paXQSXDJioYJw0FafVwBSCX3gkXuIdc+/F0e+BV65MBqeJfnCwVP47pjLm2yYftVZCV2yULBzzoeD0Qbvo08QN4MybztRSc/FX53H6Vt3lyxo6h7BxiTS5Y7ff3i0ZpnSS8LtxXGysUb3JaiaO8UeS3IV2Eef 22 | 23 | 24 | data 25 | U2FsdGVkX1/2nv06QLYyeKoNehrq2F3qgxobNWxPyxBWGdkpJIJxqiz9KHQtbiW2pTI1OqE3vdNLIGiclsWTx4kpke7Ww2sxt6B3gZvswruhy2ZQo0DtDzhwQA8IZMbCTvjtDkLwL8ORqwLMAzq9CFEa7ZHQ29j7Bq5zI/QfvTwMh9DLra5PojgJ1BNWagT2gdFV65JgKH68ZoKbsWJzzpYkI4osO1c5zwl3kwTNXd/09teTTV5zZfXA9ksjDwbpmsxz36w0rpPbElC0SYadJHOGZ/YttGBAp+XvMMWprDfkzd1dFVc89TIWRLUzi0zIO1sit4aoLfrPEwm0RKZAtNj8ZIXg98mBFsI3pHYMS0h0ureQ/SInwic6jNka/CYNp6PAApDvTmPI5oL7qipw2rGHjeDjJY3M8pOGJ0FT2nM6qgQKlPckNcRlRtmz02D7wLCiGIbc+yvVCHiDdpaS+WfZVf0qPcr/Ecur4bjJBuRFDcIsQgFbfXLuv9ecfXBYVgsNw79JPmNQKz39HlKF+2X3rXiQzS7WG2soHdnVK4VSZpnIGMZip1AyijtxWMRScbdt2woOTyRv3cs5asXd0ZMD+iR9h4t1V/Fl4RtwJtfBMTq/fhwv9YoFlz6FJfUd7P13CfGi0CFaU9DrmoNKu8Q3lwr03t575BHu2IkhWkSHll79H/btERZnr3IJ2rLZWdn3bh0PLnisBQ2qDQWP9DIhrHjRbW5tp1ffqXnBnndGIBi20hfJyTzimXEJZ3pIt5YfUlos09AboAqYX9DI95bEvwtxmMNNGW2/Wc5iZX9+rdQXL10wfItlbV+XUsK8RIzngGKAMuNZMcl9BQ6BU/5ravoZQgaMJZHC0cx+yJHPI1ciJr9pCss/Sqmu9agO5V0oiXSeIBZUp/X7aOat/LJBJydd0b+YFQ3Pjk9cyTYQbNQUkOZkGsUF/ykwmCI10fW9aRZ5GBZSlPqQYpK1HPYhjAELpLXsyNZ5HwEoOFVLOcLjKc4sZ6Kl0GMgz2FLM1i76lRaOToZUaRqeq8QTqL4XTvKMZhVzWF9gEtFAXtYSAoHa5mSTgpZmRtKSmyh89vjcQPEa2m+aAqf2Idx3gHgaGHw+xqoLaaBvMWBlM5mlWg1z9VNu+6VqMSS83gTm2KP5sShouHegr3PjRvDA/cROdv5WvimzJPj8p+L/UDkfeMfGcbZKc9/rsB1LYwtyLU/4ADTF3I4v963QeEh017MwFuXwmmoYv7A7GRSJ4kLETRLvhWiFjH1xohJPN6nrn/dB35SgnRNIi1XFNNb2lRKzoc3nazAJ6t7MY6H///oE2ml8WtoIxRkU14vtTZvUOdb33Pr2zNPmuANd7/xlf5WOQQwWwWbtbAovJ2SJxM9p+c7FnfMl9YR2nm10raZ 26 | identifier 27 | CB7D05596E224460A6AF6B4E079A3254 28 | iterations 29 | 10000 30 | level 31 | SL5 32 | validation 33 | U2FsdGVkX1/n/cdXWqhEbKWtiJ7f9R74xSQVjqH9rAC5DvIDr8JzM0hKWuScsCaAxjmCR2nMYmkFK9OsMWSCNUFFBY+E7uXVC6amcUJIMt37jU5gvJ35zKOIoV8Wy3DxD/XXOZPL6zomgUIvqj66u8juamiuAK7uV2J+cNC/54rVuwHai7Ip/YWEyXYl/BgxmHatDUv8RExT617tWLKRObmXnEcyQq6+PttkvwDdiSsfyrzduEvVHvgFB4JJ8fNnpkgl4SQipvDymxMoBxW4IpP4ACa/qzuDwScKggJCk4bo9liSh7zW4gwV40dDdDNCwVZNhQ14AxyLlkDEhzgFq77RHnJafiekU0qm5rLn1O5U/tgjUpbbTqENv+gQBKLNb0+NHxsQ/U4PNibWHKxtS7hCjrdYUGsBGtxfdVDD8yMGH8i6dz2VnHx/l+M+PhKWBIxTWvGYCLewZg24VW0/X5IOSItbFtHu6QWqS0xUOtS9wqieBwWi2sl+nJ8E4DJryzpav68l9ejH+3tGKVZWYkzoNV+Z8hawctio/I4cfwttdAW0eRdTsrFT50dEFmfBmnW9wWYedkZpTm7liyW+5f0e5672TloEz3aMTdHW7X0TVC/gWxIQqTHXxGAp78AgwZZXcEfvChl3mLCqlhdZH+P90LyGybnaCEW3hhgsjd7Kh7e35e0A/cUcBD5nxDk7//6mltgVn0roZgCZnDnbg/u02/V3IiMeFp8Bs3AtPdyV04ZKdJrxRzObl/1URnfadwgvR42b2jRA2LqxW2TORFEwsX/TVmjxmPVvPUXsXvetd9CYO1pe1Q0nBisno1IrYtIrAT1eIsGIlLnBUhg4WEGmGTJDbWLE//fA4qP6L6HyVzkiOQQZRGg8CHc39cjcmOmyjZftKhefZB3fM0HMZOdOF9v1paOFxs+JG+p2b0fxwxJF7BFv3yXvpf25/sOBIb2WehZRInjs+2FghwAZbLj99fteb/lB1OiCBkJVM/QtW0UthtGbLuJ8OXAGHxzxLNV6BSP92FSNglU3uCbw2uQVLyhcxEJvz5+oXoHP51kB9SEhwmJbahBjGaxOpqk5gW1mrua5OiLLQcwgbND/eetBkcI4Ga3Ma+CZ4faTs74KDspSIJmc1K2fRt0OnGmF/rSM1w7eFYuYuigrQhdYU/ZQlC008QUL6HxQlLmKRW8N35O/+aRKL1qG7MnMoglqp3xaYrlaX1JYRtADCuwZiUia7YvhKL2DnlGrddThfcLYqLavqKXqVC/lTYErlVN2VKScnHG0AsgINKypVBNl0t69/jKYUsd+x4gPe1yWi/gRqqH0TBOdjWi41Bx0FNfzAZHz+J3Rf/T7OUNWibN5Sf1EqldT2ZJxeouzDVQ552VfEKUXqyQhQtBUFn4kskiy 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/data/default/3A29ED972AA248EC8CA8D76A8A8021A5.1password: -------------------------------------------------------------------------------- 1 | {"uuid":"3A29ED972AA248EC8CA8D76A8A8021A5","updatedAt":1347253257,"locationKey":"","openContents":{"tags":["tag-one","tag-two"],"contentsHash":"39d46ddd"},"keyID":"CB7D05596E224460A6AF6B4E079A3254","title":"my-identity","location":"","encrypted":"U2FsdGVkX1+tPpgDiDAXO6tMsYQEhybKOP2pO+vXmDUFYR+DwEchReUhX8csc7/aYFJxqymqwBALcqNjPaUlRs/4sJuFc5PWSHuA4OMi0/TFDsylqNg/pPSdohaYgPevjFpe+gH93e7oCveDyN/5Kkf40M4+mV/aoHO/mHfnV1rOagwPO5tsvh1chv8POTiuUDLNhbRPREZagq4/Iz6NO9euVNHsZGiPJkNZ6sd45++mCaoXcUMWRQcqbR4+N5ROuYXASDn4lQbTokb4+Zml4q7g4Ibv3Gtbn4qirO3bS+bZIweZds5Qqrjr4FQuFSCoswX+SrFuBHxLV6u9JZpYNNNgwtBSR2LOILGo0HswXmIbtz4PLf2WQx/YKv9T30JywzScmXWg18gpLWPkgMego2778aip4foWE3XgbQeRCJoKhzniQgsdokDvA10gBwA1zdts9g8peqkhc0TLR4HsndzQ76aE5ztCr3KVjpy2zP08mqYQ3q1mvDPEtO+pUbyHLCP69J6FEsMDLRvTxRE5R2uFIQoHEI9SiXGg0ICP6Gi0Hw4+WPZKLmjN06P2Kdo6w44n7J0m4dQwoBGhNhPm4VppY8+azLHuaianBkaVTz9lfCs16jiIoIpxO1U2ytIvTTCwBQgqyiGtDrKdXBBStRfjheWUggjltNfoIUP71XakA4fuD1OFfAndX0y7/2vjSnctlPTN5Pt+b72XFp3Q7+u9GBVP6fLAIYC3XOOojOCn5rlt5wPwkE1DPEdtoJwJhyZ0qp8YZXm4sEM+lu8nQbZoCMMlQFX4qS3F5ZO/XbJlZnTbJfV+5nXbN+H/kxiPRvX63KigOe11vr0ZOCCJ2JhhaeHJJpBydJioYUBGDWH2+TWGKPvN8DSeQf11wEvu+l38NjQYr8CNA4jZZIAvbuK0XSKp8r9CW3v9BoOL9kakWiUvsWHzu0b16KTdlzHeTghfT/+fPVxtMQ26s0XPe41x5b6tj3ORl/vJ2E/bWUl6TilKtmvKnvxLs8KCbD+D4euEcmfsohNv8pM0Xp74iZcCySUzg51Ga5ldu4VumHVhili1nyVQ0S/dhaARdZ1x\u0000","createdAt":1347253070,"typeName":"identities.Identity"} -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/data/default/3D500EBABDC443168A5601D3081FBEB6.1password: -------------------------------------------------------------------------------- 1 | {"uuid":"3D500EBABDC443168A5601D3081FBEB6","updatedAt":1347254508,"locationKey":"example.com","folderUuid":"9E6C4144CC6C45749967D56CF0B72673","openContents":{"contentsHash":"a7366bff"},"keyID":"CB7D05596E224460A6AF6B4E079A3254","title":"in-folder-two","location":"http://www.example.com","encrypted":"U2FsdGVkX19DfyPB4v5LG5MDV1Na08qLNGj1OelfUnE=\u0000","createdAt":1347254492,"typeName":"webforms.WebForm"} -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/data/default/3F08E10EBB3248FC8EBCCD443CF1736F.1password: -------------------------------------------------------------------------------- 1 | {"uuid":"3F08E10EBB3248FC8EBCCD443CF1736F","updatedAt":1347253527,"locationKey":"","openContents":{"tags":["tag-one","tag-two"],"contentsHash":"313b44a3"},"keyID":"CB7D05596E224460A6AF6B4E079A3254","title":"my-drivers-license","location":"","encrypted":"U2FsdGVkX19B7IONEfjZLruHts+Q+m+y4ii6pyGDk86BeVmK6R4S1eMil9e7TRVuni0DZeeKmrzsxqBRAXhV+UxrlNlKya5LnhHc84ODKMMX2BdVt52WcCjwcJjDwcqkb4/Ifm+/mvWDzFHizd4le4wLyq8L/tRySfRtqYCkwDObeGaj7xA8ItzoeRfIQYQ6EIx8+9FT/hT5GFiKnEuLVQzVf33X8kalN8Gh9M0ohh8CkYe2RkCP1n6p6TEvMUiWb0OidfQgCc4z+2LGLosloX55u2Io/XrwjejO2BNdWGrPYBPabKD3PuS4+54rYNUU3alujzNYRM64sj1RlHaLa76TpEQ6mfqEvmx641KZabrFPGT8cuqDaYIt/eemTm27pgJ7B+YaproA3/pUoPiRICFe25xrNWEZT7odU/FFbTRpdKs9KV7YSgRhPGFbNMP4VYEmtc8pKsc0x1LmAZU39Q==\u0000","createdAt":1347253488,"typeName":"wallet.government.DriversLicense"} -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/data/default/45EFDC1D10E345C4B6EFB5C9F9D029DE.1password: -------------------------------------------------------------------------------- 1 | {"uuid":"45EFDC1D10E345C4B6EFB5C9F9D029DE","updatedAt":1347254501,"locationKey":"example.com","folderUuid":"52A31E6F7F2D45E49FEDE7F1AE08BAF3","openContents":{"contentsHash":"38263019"},"keyID":"CB7D05596E224460A6AF6B4E079A3254","title":"in-folder-one-a","location":"http://www.example.com","encrypted":"U2FsdGVkX1/IDjBAmr7QwR85KpX6RDp+PjR+lNN+h/w=\u0000","createdAt":1347254481,"typeName":"webforms.WebForm"} -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/data/default/4E8E2C81F2894A819BB508E60B5F337A.1password: -------------------------------------------------------------------------------- 1 | {"uuid":"4E8E2C81F2894A819BB508E60B5F337A","updatedAt":1347253573,"locationKey":"","openContents":{"tags":["tag-one","tag-two"],"contentsHash":"8d76aaa4"},"keyID":"CB7D05596E224460A6AF6B4E079A3254","title":"my-hunting-license","location":"","encrypted":"U2FsdGVkX1/38vjhH5ZMjePR+Q47Ql+FOEswaTMu/JhXYvnm+/VM7IQczTNyXxuQ/mw5xezQkgccy8nazSiqxoNU0tIOmSzam0gaSmwXe6IWyeOJKazAR7oGt8imD/TCkpb07z9ToXjlROLucXbDJYKN8BFVE9UVhOBzF6ftZLWwUmqVxF91DrIIYFcd3kojndd7rTQfbzRPe0J527Fm2esVKS66yd3D4TFoDhAUIvWqYePLZLbOMhXHT+UzHUPlt6oyDmbZhqxSKqN49oNb6nzjd8fmP6ZCYOdDoQIwEDiOmAGeSEhm/dg1njwPPvme8Ddc8YhfsfKYgxH2UYQy04AfWuBCwZ4RehHZHiHEk8gfXFU3wY7SObKghI1P5DhK\u0000","createdAt":1347253533,"typeName":"wallet.government.HuntingLicense"} -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/data/default/52A31E6F7F2D45E49FEDE7F1AE08BAF3.1password: -------------------------------------------------------------------------------- 1 | {"uuid":"52A31E6F7F2D45E49FEDE7F1AE08BAF3","updatedAt":1347254465,"locationKey":"","folderUuid":"5E9DFE25726E4AEE8E1A2F01F6667B77","openContents":{"contentsHash":"a0ec5dd5"},"keyID":"CB7D05596E224460A6AF6B4E079A3254","title":"Folder One A","location":"","encrypted":"U2FsdGVkX1/OCMokX4431tkz1kJevVHnZZE1gPnph7o=\u0000","createdAt":1347254463,"typeName":"system.folder.Regular"} -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/data/default/54B92A743AF74FD4ABA18500C80439E6.1password: -------------------------------------------------------------------------------- 1 | {"uuid":"54B92A743AF74FD4ABA18500C80439E6","updatedAt":1347252563,"locationKey":"","openContents":{"tags":["tag-one","tag-two"],"contentsHash":"11902951"},"keyID":"CB7D05596E224460A6AF6B4E079A3254","title":"my-amazon-web-service","location":"","encrypted":"U2FsdGVkX188Q8nH3gV0OSecA+hFlhgsKmYbgWDwu+H4Ep8TF/vPjbTU/8y4eaePG9rie2RnVKz8/YBUGW8ghVCA589Rpt0eHpEQjd/nHQHDRU1ju0Llf/OSFnDOypjOJ2M8AuiQR0p+DZfILqCYNnHrKtdbdGco/dWTrHYKXLyblRG9oeZSSMvtIG27IbGnGHfymX9iBTVUI4ltb4Fc7vepZmiFoKANf5Bu5ZbgNc4=\u0000","createdAt":1347252494,"typeName":"wallet.onlineservices.AmazonS3"} -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/data/default/5E9DFE25726E4AEE8E1A2F01F6667B77.1password: -------------------------------------------------------------------------------- 1 | {"uuid":"5E9DFE25726E4AEE8E1A2F01F6667B77","updatedAt":1347254452,"locationKey":"","openContents":{"contentsHash":"660ec6a3"},"keyID":"CB7D05596E224460A6AF6B4E079A3254","title":"Folder One","location":"","encrypted":"U2FsdGVkX1+7aMMKlsOjFCUp4a9EKUCXJjeNUDpEMYs=\u0000","createdAt":1347254446,"typeName":"system.folder.Regular"} -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/data/default/63DF9D8619A544208F9CBCACDA1D5B31.1password: -------------------------------------------------------------------------------- 1 | {"uuid":"63DF9D8619A544208F9CBCACDA1D5B31","updatedAt":1347252843,"locationKey":"","openContents":{"tags":["tag-one","tag-two"],"contentsHash":"6d5c2f9d"},"keyID":"CB7D05596E224460A6AF6B4E079A3254","title":"my-internet-provider","location":"","encrypted":"U2FsdGVkX19lvbpKHd6ylICiOrurknF8XW04i8DKDTuOn48XF35c5Jp7pw2A5cvWHwcY6+Ow9qhevrS7eazT1iHY1iuy7Jm49RciJY1qi3cmleKeCxNfyVVRMySoZ7Me2eEoBepf+WWv5GA4vGtjRZMRuzsjT7166yLPqr+SSFR4eUXZPKsoTvoafPCKFwEOY2yQXARkSDIULTJEWfRdftY9nsI1+nunTrg+BUPurYfYpPA1QT11KxRIQz6RkT5HCGS568nTO+55eakne/UsTP1u4f4Bi5/PtIbGWGCCVzwQmWTHupcAgTktZdQgtcZQ\u0000","createdAt":1347252803,"typeName":"wallet.onlineservices.ISP"} -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/data/default/65D231DECAAE45AAB9FA9B7523788C1E.1password: -------------------------------------------------------------------------------- 1 | {"uuid":"65D231DECAAE45AAB9FA9B7523788C1E","updatedAt":1347253664,"locationKey":"","openContents":{"tags":["tag-one","tag-two"],"contentsHash":"d518e8bd"},"keyID":"CB7D05596E224460A6AF6B4E079A3254","title":"my-passport","location":"","encrypted":"U2FsdGVkX1+ftBcne4UsgfnM9DI2iWWeY0PJO0PuUIgYCRhu6anWjmYvYaC3cBzijTLrOLkXCYV7GCRCr1BVeP/E44ZOUAiPcwj8xSinp+ilkxKuuf8eYHCUk+hTwrReGX1ftcRO1W8YSkmxVklnwH6v2T+QaTUBBkyxMpPPqKGY298W/hx2DEdHyES/+mjeMTccQ+a2F+NXwEJRC53ALomjwJdAUnJzCL88HXoKElEOkZ6ude4JrWzYtzfeYhUeAZDzxEUlL+eAKLnxytXwOkU36obWiqRTAzUuF4kt1jkoxrlqHGhxi2dknBLx8Bnt9pPFPIvs4lxqCmunM1gePJRU/3ufETvDLPOrg7GRetCFko72V7V1O7/PIjVy2O7i+QL0cq78ztKQ2Jmh9lrYxGjicXRYuteRV6C/3yGxUHKBP+SMThNjBhSkt81xPCZlf9OnhEu9l217McBdJ+DRwd1hS0my5xABnIBk8Ol+E/HbXHzeL0psxJ9WcETPBMzRdapfZTk8+ncLLXvpUVyP3y30vDeixcwB3bOzJKMoLcadmIQNWSYKRVwE8gM2ZypuH/vN6IbeEA9AW7fbSOcBLrhCXL3FxNZsM0/lCZrRLic=\u0000","createdAt":1347253618,"typeName":"wallet.government.Passport"} -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/data/default/6D025BB9F3A5432DBB9163A3B5F67C4B.1password: -------------------------------------------------------------------------------- 1 | {"uuid":"6D025BB9F3A5432DBB9163A3B5F67C4B","updatedAt":1347254505,"locationKey":"example.com","folderUuid":"F32475F595734B16904804137B1FCAF1","openContents":{"contentsHash":"6b40ea5b"},"keyID":"CB7D05596E224460A6AF6B4E079A3254","title":"in-folder-one-b","location":"http://www.example.com","encrypted":"U2FsdGVkX1/MEidjtSNihB7Fz+2T5+/m1DxeJGdaTF4=\u0000","createdAt":1347254488,"typeName":"webforms.WebForm"} -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/data/default/6E29104AB35B409C8D3B0AC0423DA753.1password: -------------------------------------------------------------------------------- 1 | {"uuid":"6E29104AB35B409C8D3B0AC0423DA753","updatedAt":1347252762,"locationKey":"","openContents":{"tags":["tag-one","tag-two"],"contentsHash":"83ec8d53"},"keyID":"CB7D05596E224460A6AF6B4E079A3254","title":"my-generic-account","location":"","encrypted":"U2FsdGVkX18gVLK85T/SYh9eJMi0IVsBLmDoaX1vcm4s66FfPzcVB0IRLtOpTev5S9rjNuxjcA04OgXjXcK/CR7swoh6rWZdzCRXEhTcLQ9Eob6yaXNk4xYOJKcSUaJK\u0000","createdAt":1347252742,"typeName":"wallet.onlineservices.GenericAccount"} -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/data/default/7AD1A9D39350460D8FE26C70D6A58D96.1password: -------------------------------------------------------------------------------- 1 | {"uuid":"7AD1A9D39350460D8FE26C70D6A58D96","updatedAt":1347252936,"locationKey":"","openContents":{"tags":["tag-one","tag-two"],"contentsHash":"b324a8a5"},"keyID":"CB7D05596E224460A6AF6B4E079A3254","title":"my-server","location":"","encrypted":"U2FsdGVkX19bTyiJ6CPn5aAvDZcGV8rlbdQkd9x1OXgDHaDya+VA+OWrtlarorBygLXPpG1hWv1onJjx+jaMhRFdO9nHPE5W8pMJCWwe86eBnENfv178UK5T8UJkbbcFRGmOksP0qZ2+QOwMMAd0X45hRQXumILxEmIn3v7+Nsk2hrwH9+0njY+CGsYnGICnhPx/2amrWXJ+GNeFmQn+j6i7VCXB8yucMaksEE2fJry6kA4gDJsB3g5xeHfnriCJkd/GVv09zum2x0p2/Agdjew6KGpi8D+qiY2KACqqFUjcG5OgGhpY9a/qLWQkU1sOZ7sPI/Nvs3afHx0nIJYsTIfIV7roVeped2fSckO6o6r5bCo0L1acm4HrwivUgRUicPU+nCdzmFs9QCGKedjF0DtrD1cB/N7BnDopaOZjcLD4RZaCdWxmmfT5U0FQmbmk0+BBHkevDStCInkogr15nRIbOPVq1ZBz4Ciro3dwXyIU3ht4Sii/mbtF8ZGG5Z99\u0000","createdAt":1347252892,"typeName":"wallet.computer.UnixServer"} -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/data/default/81765FA9CA7E408C8C4E24E9201F5D92.1password: -------------------------------------------------------------------------------- 1 | {"uuid":"81765FA9CA7E408C8C4E24E9201F5D92","updatedAt":1347253614,"locationKey":"","openContents":{"tags":["tag-one","tag-two"],"contentsHash":"c7f7e374"},"keyID":"CB7D05596E224460A6AF6B4E079A3254","title":"my-membership","location":"","encrypted":"U2FsdGVkX18q1edl45WrKk9NR4yzncS93OBhn3o6/3AJt8vTGuoZ3beI9SXV1dpjHw0KuEqNgP4mpYi12yNp2zRBHYD65tDdZyQPtAmaYi5ag4Uq3f3JSN2/FymMuxjGvveHH826eetItaeMvTHQ7B9Q1/QlS6god58j21IbiP+e0oqca1kon7cptstxxLNIhR1+87y67Fa0x1zVbC4s0/1GFMaRIVrdTvm683B/c89fNzMxVHjcPAxqCljPj9HuEzWzGA9SyMYsdSTa+iMV9E5zD9tYJSY/WdrNe4rqBKkvSzkzw0murTZnRl53dEM2onZef6LrljVXIp7NMKNY2svO0itVTMJ+xK3zWKlsR1Du5tot+xEC2UiL7X1zM2U1k+Ed+MRMmTWh+iruO/3z0g==\u0000","createdAt":1347253578,"typeName":"wallet.membership.Membership"} -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/data/default/81790CA860ED45329CA9E9BF9D0C0804.1password: -------------------------------------------------------------------------------- 1 | {"uuid":"81790CA860ED45329CA9E9BF9D0C0804","updatedAt":1347254150,"locationKey":"","openContents":{"contentsHash":"37868cf3"},"keyID":"CB7D05596E224460A6AF6B4E079A3254","title":"my-minimal-login","location":"","encrypted":"U2FsdGVkX185QOmi5Rpzrb/aPKbpQAPhI0Xho3nDVRk=\u0000","createdAt":1347254132,"typeName":"webforms.WebForm"} -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/data/default/9E6C4144CC6C45749967D56CF0B72673.1password: -------------------------------------------------------------------------------- 1 | {"uuid":"9E6C4144CC6C45749967D56CF0B72673","updatedAt":1347254460,"locationKey":"","openContents":{"contentsHash":"864d6ff9"},"keyID":"CB7D05596E224460A6AF6B4E079A3254","title":"Folder Two","location":"","encrypted":"U2FsdGVkX18bsYMDObs4uPKv2GduXMfrhmF5ZAb/eQ8=\u0000","createdAt":1347254454,"typeName":"system.folder.Regular"} -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/data/default/9E7429A62EE04DFFBFDCAEFF84A82E80.1password: -------------------------------------------------------------------------------- 1 | {"uuid":"9E7429A62EE04DFFBFDCAEFF84A82E80","updatedAt":1348551537,"locationKey":"my-service-name","openContents":{"tags":["tag-one","tag-two"],"contentsHash":"9f289d3b"},"keyID":"CB7D05596E224460A6AF6B4E079A3254","title":"my-password","location":"my-service-name","encrypted":"U2FsdGVkX1+rv05ymbg+U91chjF2wBnptmXGcG3Wl3LuBJTUOY/PCdBCcVotd+Q9F3OcdHiIErRgpjJQ9xSoD5kxTsBB13SiPJMeqMO4iHo=\u0000","createdAt":1348551502,"typeName":"passwords.Password"} -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/data/default/A3AD6F1B94B64344823146E5D25C653A.1password: -------------------------------------------------------------------------------- 1 | {"uuid":"A3AD6F1B94B64344823146E5D25C653A","updatedAt":1347253483,"locationKey":"","openContents":{"tags":["tag-one","tag-two"],"contentsHash":"82fb8311"},"keyID":"CB7D05596E224460A6AF6B4E079A3254","title":"my-credit-card","location":"","encrypted":"U2FsdGVkX1+sUO1FdghRfK0/SRF+OEI6M2V0TArzt3AWZmGgsnPG3dECPcL8bv4cci0FLLZkmpd4oPx+OmkKCOQeotaiir9v/+8HaB68JK98ExwDRS/VySKNtvFueuyNRT7p0UjViPQpa5OQuZ/VJRu9g9SnvPZVbPOPpmVmtjLUwtJush26fHw91M7UEiwozFGoChAz9xJ/bTm/n4E9G/InTLYlaIRHZPJBh6GD7tAe8065FVL3HcJaGEdTeP73SbYjtecVkRKEnaF4cQitrBHOZ1fszOBuPg4XzFuq2+ZkZOFB0zajwt/wZhDTrgiJw++8twEiQZ5jycTe3hohec185k2+QhjbmELlItLHSMtVpk8p7t+HdXItV1hU4yPdvhguj1zxGI7jznz67A4cVLQCWdUN5IyQE91V+xo1Hn+BLaGJWc15T9+L2t+LIWPffuBLDGIPXYhJ2bUL7X1L4kctOmKdDkakyWFidLm2xckxdVzVnZLEZ8yPkL9u6d/rfADsJmtKU7tupow33BAv2dH96B/uOLmbkujk4wLKHYHUXEi4x2iRKyhH2Ymk7O6RqnaU95YEa64K7qoERmA/fIv844n4yJpeb802I5bfHezhtgWweLscAif2/3PWhzVvsBkUqqJhRVaQhMSGWqTtH49/CU7JzFWLg/o5hy0jJtp42d05RHhaAyoJxpW1GyhT\u0000","createdAt":1347253420,"typeName":"wallet.financial.CreditCard"} -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/data/default/A3D3354DB935478CA162646CAA021D59.1password: -------------------------------------------------------------------------------- 1 | {"uuid":"A3D3354DB935478CA162646CAA021D59","updatedAt":1347252612,"locationKey":"","openContents":{"tags":["tag-one","tag-two"],"contentsHash":"1d9b8a92"},"keyID":"CB7D05596E224460A6AF6B4E079A3254","title":"my-database","location":"","encrypted":"U2FsdGVkX18cWsWDe1lIksdSo3GvrAKa8Sll9rHaQeCSwVi04SxAaw1vWep5HDn6fAxZuMZj6QK2yxngl3xdvMmmvslSjOjk7dhm1Z+siwyW/ZODfHI+JEB4DPPTvokoxzEUoXRqSrJ+ctspRCwAyyG9qorMO4Q/IfJBLJJRBdZhs16VcW6wD7tPW5/q+t9DQZvdr3SJOs1lcLJTFDwLr3/VHWoGnMSM87r3JV+zL6e6RjMdlCqqExrN0T+tKF83GuW2f6fIjlGp7HFGbRoIa1jY/SdpWkXz5rrElkAwoXHUAcFW8oncD8gewJao74ZDnSHSPB7GIgy3xn/QtJoPEQ==\u0000","createdAt":1347252568,"typeName":"wallet.computer.Database"} -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/data/default/AC5EFDF9FBB4450389F67E497CC15A3A.1password: -------------------------------------------------------------------------------- 1 | {"uuid":"AC5EFDF9FBB4450389F67E497CC15A3A","updatedAt":1347252737,"locationKey":"","openContents":{"tags":["tag-one","tag-two"],"contentsHash":"6b3864eb"},"keyID":"CB7D05596E224460A6AF6B4E079A3254","title":"my-ftp-account","location":"","encrypted":"U2FsdGVkX1+i9ASGOWxMo1NovEkJnwXoDSKJ+Pi4emZxidbgR/XRn/fqwxCZI46OpR/0iyQ0mdca/97pW4N0hewh3HYSkf8PI9YLHSi0pCnzZBO4KISD5Nr+LOX9G5UCIaNzTr1xA1rZhV5LGgbdX46JEpqJ6p8+hU4RbIAPhsuID9c3B0njLo7l2HikVCoJvTR0vpLertbZtXLuk920pGOf9lAzDl6lyh2CYOVgAjOq/IHpGAGev7tsmzw39egQRqTq2MiM7XUNb3yG0Q8mcQTRv3a9At92IMuoHyZj4gSJkAhKPq408QMag8mZMyOTr4cIyOk/rwp7yiFOTw809xphDzr7jLk7+n8uQx+sJ5+Sy1g0hZ1y83aHA61DuwpW\u0000","createdAt":1347252696,"typeName":"wallet.onlineservices.FTP"} -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/data/default/BF64712D60544E3ABE715968C8B92BDA.1password: -------------------------------------------------------------------------------- 1 | {"uuid":"BF64712D60544E3ABE715968C8B92BDA","updatedAt":1347253720,"locationKey":"","openContents":{"tags":["tag-one","tag-two"],"contentsHash":"a61e1bbf"},"keyID":"CB7D05596E224460A6AF6B4E079A3254","title":"my-reward-program","location":"","encrypted":"U2FsdGVkX18uCSe/wKiNLaTS2mdDE/KUvGcyhWLPotL1WwkOd+5JNr5RBDl4wd7aK7RxGaVrEysJ35Ruqs6g1+bCIg4hO8TCbZnmekAmHCvwr2IAiP+/0WCqMcJKj7VO9sDZKm3EPY/aaxpYrKGEN7dc/JmG5m9inOOYty5nPYNrMpQq52g/cdoBtiN3yqKPSHzJ44m5V2sJn3aw5RIQEpmLNO1SI3u3lBNDLpu+ZEoxrADCuSiGjX4EhgFNPmkmv/pIdVs4Hc3rnbWHlSjULLTQo7cOUrFhMaWWUe9zIzR4DJwAd4YgyeeyBOVCAzmQ8z9LALFk57dRsJNH1iI3D+TaqnLHmXCIoipmlzJXx9RzO3Cvi9psXxj41nJMz7HxE0UB7u4avnsyRORwcra6+M+tzc442hHCOWH3fH7XT2Tpjnw74kLCOG5MRHqy6LcFBxIdG+9WfOrTSugFfs947JJ55YKlyzusvsANKQ9a147qGg9UZAlTREMSfaRnDLWC\u0000","createdAt":1347253669,"typeName":"wallet.membership.RewardProgram"} -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/data/default/C08769365FB845358516CF63460BA818.1password: -------------------------------------------------------------------------------- 1 | {"uuid":"C08769365FB845358516CF63460BA818","updatedAt":1347252389,"locationKey":"example.com","openContents":{"usernameHash":"269ec28e0f77166df12bac55af52e2e7908cfab8c6ad1320a0a3395e07a1eb7a","tags":["tag-one","tag-two"],"contentsHash":"bb28709f"},"keyID":"CB7D05596E224460A6AF6B4E079A3254","title":"my-login","location":"http://my-login.example.com","encrypted":"U2FsdGVkX18szXGGFR7FwBrP1w4cIk2XSlsjUlq74hAtOy7he9f/kOEpBkmCUtgu/CtkxqRF7pAfI6EDdwtH3iVj9vKHHjLyBDp5ZGlp8YiKbjXVZCzysqGryiqwx7whZBcn/Kso1vw/uWtF6YYxjnWhX8mVFC9S9BcXrJMBq8bGGMWdlmPFREJ998vhkLSE2/pIycocThDdR5wNLeQMemIarB8kRLICeoNwqUOlPpyIIa/soZqN1Nbn/aKWhBPkNgYV/x8+L4/R7blXzHINedeS1HuojFnBy7b3vRvYFM40jXTAMAsYyuRUKXolP+APTwXM29z/PzNbLXXzcojGuHcZbffdUovUZuT9cUBAB7Oefwmlq6jU07wj9KpywW/x3VWUYY7Q3aixsmmD3WDJz4pMcqSzF/rtcLBC6IqG9/s=\u0000","createdAt":1347252233,"typeName":"webforms.WebForm"} -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/data/default/C6B2359919054C32A5747899F736C4B2.1password: -------------------------------------------------------------------------------- 1 | {"uuid":"C6B2359919054C32A5747899F736C4B2","updatedAt":1347253751,"locationKey":"","openContents":{"tags":["tag-one","tag-two"],"contentsHash":"d83dc99"},"keyID":"CB7D05596E224460A6AF6B4E079A3254","title":"my-social-security-number","location":"","encrypted":"U2FsdGVkX1/OrsodvH4PZmyLXg7c+5GaT+CfA3e8vzMWNlzn2qJHrsXvHx8TisflnalSZbADi0ei2s34KVuyJeH0l4pBLjRR15AOtwhSVXc=\u0000","createdAt":1347253726,"typeName":"wallet.government.SsnUS"} -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/data/default/DD24D449A13546428423687FEF1C03D4.1password: -------------------------------------------------------------------------------- 1 | {"uuid":"DD24D449A13546428423687FEF1C03D4","updatedAt":1347252886,"locationKey":"","openContents":{"tags":["tag-one","tag-two"],"contentsHash":"e9601b3a"},"keyID":"CB7D05596E224460A6AF6B4E079A3254","title":"my-mobile-me","location":"","encrypted":"U2FsdGVkX19ASxbs1LHJ3VwaP3Obxr716WtrUIF0EOlOr0MPmXLA3Cj5/ktiD0LXeth+ELwVAN7kA4Gc/WGsIHrd8kvHlPX3fDSAaXABEEd82AS1G2UBBfZ4+cAeALu6lpgoCfM7wj8TqGR+M0TMJUa/LYY++iQyrEbuYAWCyu3KWExopqezUiW4x4JEQdreVjxum26e6Tr9bBfKGkiJQI/HpLc/K1yh8s77j6iOjUuuAHkTTRM2we2C3fIWYX9idRTFsX2sgqxGUDNxlKy6Me0BoTiotkYH16lPebKsCloWiAKvkcEYDLKwCT2T9P4kz2wrYIeAdqupViMoaEtOYqcad1xo06t4KGpAw1lD53I=\u0000","createdAt":1347252847,"typeName":"wallet.onlineservices.DotMac"} -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/data/default/EC1C2C874CB444C3BEE538A0EEEF3DFB.1password: -------------------------------------------------------------------------------- 1 | {"uuid":"EC1C2C874CB444C3BEE538A0EEEF3DFB","updatedAt":1347253285,"locationKey":"","openContents":{"tags":["tag-one","tag-two"],"contentsHash":"12e3d205"},"keyID":"CB7D05596E224460A6AF6B4E079A3254","title":"my-secure-note","location":"","encrypted":"U2FsdGVkX1/oNLBh+mFER9VdRUTEf3ZjL0hVG3eb99ibNvoUUDbb/ufefdI9jd8r\u0000","createdAt":1347253264,"typeName":"securenotes.SecureNote"} -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/data/default/F1D5DEC910FC40E3B0C260DF582CF1E5.1password: -------------------------------------------------------------------------------- 1 | {"uuid":"F1D5DEC910FC40E3B0C260DF582CF1E5","updatedAt":1347252798,"locationKey":"","openContents":{"tags":["tag-one","tag-two"],"contentsHash":"8b185509"},"keyID":"CB7D05596E224460A6AF6B4E079A3254","title":"my-instant-messenger","location":"","encrypted":"U2FsdGVkX1/FAQoTIJaVotQc9UVpdMvNg7Ow4NUKKYcnS8FFiPPDus0j/27J3cw5OL+vS7MKqp66BRTItvKewHvRwSOdzuSieTwVW36qGzAjI/zm+fWXtbLFFf6AAXE1WAaZiVl8tPTFDzXzB4V3YNm6Nzbb7J8gW+RiliHLuOBFx97pYzxI6qqWZC9WR//hjlF4P56MugYNaBVLQvVIvw==\u0000","createdAt":1347252766,"typeName":"wallet.onlineservices.InstantMessenger"} -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/data/default/F32475F595734B16904804137B1FCAF1.1password: -------------------------------------------------------------------------------- 1 | {"uuid":"F32475F595734B16904804137B1FCAF1","updatedAt":1347254477,"locationKey":"","folderUuid":"5E9DFE25726E4AEE8E1A2F01F6667B77","openContents":{"contentsHash":"e44d78cd"},"keyID":"CB7D05596E224460A6AF6B4E079A3254","title":"Folder One B","location":"","encrypted":"U2FsdGVkX19kZA+HWudLATrT2CwF3/epnXkQ0vbR4IQ=\u0000","createdAt":1347254473,"typeName":"system.folder.Regular"} -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/data/default/F690937594BE40D78F79B9B3B56F35A7.1password: -------------------------------------------------------------------------------- 1 | {"uuid":"F690937594BE40D78F79B9B3B56F35A7","updatedAt":1347252993,"locationKey":"","openContents":{"tags":["tag-one","tag-two"],"contentsHash":"a6ff5fe2"},"keyID":"CB7D05596E224460A6AF6B4E079A3254","title":"my-wireless-router","location":"","encrypted":"U2FsdGVkX1/gObk2jjGDYK2+PfZS/tfV6Nxl5Vn1NuWUgmt0zMP3eq/pAqwZwlRX75p9PD8Q8SZH4k+t8EcFQBulByVTbXTPbBVbMEv/AvIkf6YQDfWxXs0oW1SOkBm1GTvEREc5YCABVCS9OjmSTZh47aCzhkTQlF9qZpCG6yT3KGsyuDuUgIqx6qjddRRuku6Q85ZvnaOpOAbT/nxsKUMcT4iIy/exfHKfyW9TX14zsQdbq2r+3U3HZvOyE9KdAxMilPlNteE0pUBH4Q7P3vm5fBElEE0OR4YtZFKiVdCvaR6EsFBK96z4EEKCQpQxjKBKcY5J99qDZVgxhqe73ezCzQO+lPhjMe2aMRaNNWcPQes4Vz0f51VZekQ3mFgRLnbKZObEJDEXbX+d4SiwwFo942pQNUc5yGO473U57EQ=\u0000","createdAt":1347252940,"typeName":"wallet.computer.Router"} -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/data/default/FB4C784BA70741FEA47522E984D8BD34.1password: -------------------------------------------------------------------------------- 1 | {"uuid":"FB4C784BA70741FEA47522E984D8BD34","updatedAt":1347253026,"locationKey":"","openContents":{"tags":["tag-one","tag-two"],"contentsHash":"adfb9098"},"keyID":"CB7D05596E224460A6AF6B4E079A3254","title":"my-itunes","location":"","encrypted":"U2FsdGVkX192jRSM1efstc2TN3tog4WGGOMdDI6PUBC7+0C4dykuc/pjO3RuWjH68hxRsPGLorCaKWjaYUyLRwqZFmy5zBLBuKeW28SKtU26OUgriWxb1HKUO+SpUkBfV9MNbu2fdZ6hLTOvTZTc2O87wVEZFrKhzZ49hPUt80NwAw78UZmRRmrCLJ9R5fXhU05Q6FcWodgB5ZNdBhy5dg==\u0000","createdAt":1347252999,"typeName":"wallet.onlineservices.iTunes"} -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/data/default/contents.js: -------------------------------------------------------------------------------- 1 | [["0FAE93A1943E4437AD662A81976811DB","wallet.onlineservices.Email.v2","my-email-account","",1347252692,"",0,"N"],["1EEE501364B843F3B6518597A7999D12","wallet.computer.License","my-software","",1347253363,"",0,"N"],["0628D24B0D42482E849CE7FBA52F1C74","wallet.financial.BankAccountUS","my-bank-account","",1347253415,"",0,"N"],["3D500EBABDC443168A5601D3081FBEB6","webforms.WebForm","in-folder-two","example.com",1347254508,"9E6C4144CC6C45749967D56CF0B72673",0,"N"],["3A29ED972AA248EC8CA8D76A8A8021A5","identities.Identity","my-identity","",1347253257,"",0,"N"],["3F08E10EBB3248FC8EBCCD443CF1736F","wallet.government.DriversLicense","my-drivers-license","",1347253527,"",0,"N"],["45EFDC1D10E345C4B6EFB5C9F9D029DE","webforms.WebForm","in-folder-one-a","example.com",1347254501,"52A31E6F7F2D45E49FEDE7F1AE08BAF3",0,"N"],["4E8E2C81F2894A819BB508E60B5F337A","wallet.government.HuntingLicense","my-hunting-license","",1347253573,"",0,"N"],["52A31E6F7F2D45E49FEDE7F1AE08BAF3","system.folder.Regular","Folder One A","",1347254465,"5E9DFE25726E4AEE8E1A2F01F6667B77",0,"N"],["5E9DFE25726E4AEE8E1A2F01F6667B77","system.folder.Regular","Folder One","",1347254452,"",0,"N"],["65D231DECAAE45AAB9FA9B7523788C1E","wallet.government.Passport","my-passport","",1347253664,"",0,"N"],["6D025BB9F3A5432DBB9163A3B5F67C4B","webforms.WebForm","in-folder-one-b","example.com",1347254505,"F32475F595734B16904804137B1FCAF1",0,"N"],["63DF9D8619A544208F9CBCACDA1D5B31","wallet.onlineservices.ISP","my-internet-provider","",1347252843,"",0,"N"],["6E29104AB35B409C8D3B0AC0423DA753","wallet.onlineservices.GenericAccount","my-generic-account","",1347252762,"",0,"N"],["54B92A743AF74FD4ABA18500C80439E6","wallet.onlineservices.AmazonS3","my-amazon-web-service","",1347252563,"",0,"N"],["7AD1A9D39350460D8FE26C70D6A58D96","wallet.computer.UnixServer","my-server","",1347252936,"",0,"N"],["81765FA9CA7E408C8C4E24E9201F5D92","wallet.membership.Membership","my-membership","",1347253614,"",0,"N"],["9E6C4144CC6C45749967D56CF0B72673","system.folder.Regular","Folder Two","",1347254460,"",0,"N"],["A3AD6F1B94B64344823146E5D25C653A","wallet.financial.CreditCard","my-credit-card","",1347253483,"",0,"N"],["81790CA860ED45329CA9E9BF9D0C0804","webforms.WebForm","my-minimal-login","",1347254150,"",0,"N"],["A3D3354DB935478CA162646CAA021D59","wallet.computer.Database","my-database","",1347252612,"",0,"N"],["AC5EFDF9FBB4450389F67E497CC15A3A","wallet.onlineservices.FTP","my-ftp-account","",1347252737,"",0,"N"],["C08769365FB845358516CF63460BA818","webforms.WebForm","my-login","example.com",1347252389,"",0,"N"],["BF64712D60544E3ABE715968C8B92BDA","wallet.membership.RewardProgram","my-reward-program","",1347253720,"",0,"N"],["C6B2359919054C32A5747899F736C4B2","wallet.government.SsnUS","my-social-security-number","",1347253751,"",0,"N"],["DD24D449A13546428423687FEF1C03D4","wallet.onlineservices.DotMac","my-mobile-me","",1347252886,"",0,"N"],["EC1C2C874CB444C3BEE538A0EEEF3DFB","securenotes.SecureNote","my-secure-note","",1347253285,"",0,"N"],["F1D5DEC910FC40E3B0C260DF582CF1E5","wallet.onlineservices.InstantMessenger","my-instant-messenger","",1347252798,"",0,"N"],["F32475F595734B16904804137B1FCAF1","system.folder.Regular","Folder One B","",1347254477,"5E9DFE25726E4AEE8E1A2F01F6667B77",0,"N"],["F690937594BE40D78F79B9B3B56F35A7","wallet.computer.Router","my-wireless-router","",1347252993,"",0,"N"],["FB4C784BA70741FEA47522E984D8BD34","wallet.onlineservices.iTunes","my-itunes","",1347253026,"",0,"N"],["9E7429A62EE04DFFBFDCAEFF84A82E80","passwords.Password","my-password","my-service-name",1348551537,"",0,"N"]] -------------------------------------------------------------------------------- /test/data/1Password.agilekeychain/data/default/encryptionKeys.js: -------------------------------------------------------------------------------- 1 | {"SL3":"6EE8D721E87248D2BA08329003B23C56","list":[{"data":"U2FsdGVkX18kNofF295yoryIbjC0gQA4QTVbrjE2JNQ0Hh6NJmVESaT2opYIX2J4dZaysH/7OnisBnqwbjiNAirbtpz/OEGoyZJiGilQUKieRExa/55axoTpkai1hS1DhTItfeVgNc59GUNo3T4WtCZvpNv/xlb1ArFutiJ4XTVGNYsjmhL6WffC5qJGJTY+qY8SMZTNDIDiTVM1eQMFu/C0WGPPYPTNSMr7G86/JrDt4xP+csv03cZWHSDDnGcY0WwJPxzf0Yd/5vhFvYBdwGYQFyuaz+FJyh2M596WDh5Wauegv1l4DXbmB7cHOnGI0KnwlaUsRk6PYAc5+uzf6FxXtt/iGjLZWf8PhduhLI1xGxvYQL9eaTfUe/rs9UFsxgT9f7I3262HtUQ553h2cBwddp6qZ+wUCovEK8dP2YSJluGSVRheB+GUUyX5W3rde3EKfhrJVVf8BPPgY9IFCRKGxENX++y+MO0wCzO2XD2an6A1zrUYxr4LwZmGzBF+a/pafyrHTKxCQgPTAlEUrDT1vocowKcK2QZMQ7E24XdyjpToyz5Fe/XpaGZ5KHwU3KphM0gSysAF0W3AGSWYGO2DXfiSvUtgUOhNlqAEcegVcaUmg7icHG6qNgG68sxFyPmoyzQfk/ZhQ5ruogjxs52Kx++955i+O6ujJ+7ID9azDhRgV/tN/jmhNlSP91F3ey1f4uJURe128e16WhhM4sG2Q3Vq201bNL3cRG9oPLEEUHUTt3DbLFcJt29unyxKUmkoXTaG2hJw8qX1yzOFdfLBY3U58SdyWwXuqsmCeGK+UvTIi0r8BIhCG8aMmS2PGIm8xTinFrK2dp2wls0yzcFprRc10SSqJ88A9C8O+6pCgEpbgeuR3QhgoFytOwinC012qfDBhoLms8tUxwZ8yEsPjuHffNdoP5SAg+G3w5jIk9zd8vCkwOhXFcrjBhVD8FjP0dU9YOGCK9iTwVP2f70l1UpPFLm7FMrwh/hX6EKgWk5J44s8eLbmYn9QUlBdMMWU1xOzRJVACxtUVL9Ymt0kfXp/ZMnp/new1KxAl1VHG9/AgSF2x9yrGMsgpxOssnsftS+ekFz/TtS8HzyopBUHLPEP5jmuOvVSu96LUwFowcqS0S/zxR7hIE38NeNRFg0sF+bVlLYEGnN+fAzqfodO9eeiRczXBcUelyehgwon/0dg592OXRqEVq0EMqOfuNDrtUKdTZ1ZTfuXy4rjduK3RXNPeF/4RDDMEjs2UNgCk6gus2v2yvcBa22nKuVOGpq9Hf9L185lBiCKmucdNeM4pelIdfmZSSRN3TAjexchOW3bKzDZhqO3WEc716Ic0ETqCj1l3fuF6/yELQG5I7pgj/Lq2tXQhaI6EfEQTEgWhIXaSSSPY8Fn/0ndQaKn\u0000","validation":"U2FsdGVkX18HfNCJEqhTvj89fBcgvzn0g8ghnCUhb5pqI/IS8yw7+o5I5pwm/Dd11rgPKgHzTSrMyc4sgLgBpsZfzDstfe0CS9XfAhbteFhRZN5vuwsaRneAed8BDLFRaA/uZj3iBosJpWky70vnqw81jYjUeHeXL5EXnK06GuovUCumw2AzrtpHX4FQPJxaLrx8s/mllYCMEQ0fywkysQ+lobcdceFbHFqOnGbLZfDDzcwoDzDsLrszyMJhWcY2hc/nbD3aHJcB28YoNQOHeiq0j6fbpsR8BOkyqWQAzlIRiwDv9ROW5Zn4l79AcQhoKejLJTOG3cERvnBns/3MCR4rJksAWoB7h762GQ/srSpjh8SHyFevDSSfUjg/0tzt4rF0lzFx5wwFdonMWNCky5PtUQ5IC2RcKRhCuLMgHqoxLyXBCDgBV6XWjhE6WXlaNu/HF9YPhKc9HnxjtQZkyBiPbN4je5wS/bYfP/zpzUqH9sXo1VHLYlnIw93+MHSqIsMUhMIJOjG850JZwVXw9lDsybu6zLYDER+zEcPaBIIXZ7aL0Bf5Y6oYgmOggrojkfYO0MHhMOmYhDijCXJZqceLMAUQeFfDovdXkpBKOX5t+idbEhJX44pkLb2YGtavH4tco4jAY6n80/N6KdL/ikAyq8DcURwhjajcAQFV31gAuAeQHdiTYumu3JkGitn7TwIdLRk1esf5nsdid9EEFYRPdpbmrAecRwV2Z6ZL+4jvFndpubnN3Ys9aIIAKa3rXlKSsUakB+/ntfb3JHj0APs+Cw2juatUllqNYOsmMz29rBjDX//39Dq65loPjJKq12MV83MvX0N4GlP926WTa6mXf0hL+fvGfKxSSrplKtCYpflkN1AO7Nv8rnrid47XWAVxRPNM9UmhMpPacYLhh/3i3JtbkmL9FcSgpB+K1vgM4LOwebsar1Gm9gdmLkmpN3mktrQL+ZE0FZAC+nQO8ap3yZ91TVFIsvZgK59sbofpxBIJx3Qy3A5j9piDUvW3/7zd1FY8FyAmBkry1kY4x4z5ZoDmHh6c0BGGvg4qW/b4LvnD2Yi8I2TpHgdI9zEEoho15rWOUqlijdK1JS6o9fHrBSnlXuZVHurJ+HF8zaXnaTt+/nv7RgyopJQhgr5sMU7RiR2GYg+o82ZRMaoY6cPl8eJM+WAb/ZIuvTn/JZ/6NDnXKRGB40sgOVNV2d9BETzrhbQ5/D1zsmOdSOfzxUabO5Aw6VX57d2paXQSXDJioYJw0FafVwBSCX3gkXuIdc+/F0e+BV65MBqeJfnCwVP47pjLm2yYftVZCV2yULBzzoeD0Qbvo08QN4MybztRSc/FX53H6Vt3lyxo6h7BxiTS5Y7ff3i0ZpnSS8LtxXGysUb3JaiaO8UeS3IV2Eef\u0000","level":"SL3","identifier":"6EE8D721E87248D2BA08329003B23C56","iterations":10000},{"data":"U2FsdGVkX1/2nv06QLYyeKoNehrq2F3qgxobNWxPyxBWGdkpJIJxqiz9KHQtbiW2pTI1OqE3vdNLIGiclsWTx4kpke7Ww2sxt6B3gZvswruhy2ZQo0DtDzhwQA8IZMbCTvjtDkLwL8ORqwLMAzq9CFEa7ZHQ29j7Bq5zI/QfvTwMh9DLra5PojgJ1BNWagT2gdFV65JgKH68ZoKbsWJzzpYkI4osO1c5zwl3kwTNXd/09teTTV5zZfXA9ksjDwbpmsxz36w0rpPbElC0SYadJHOGZ/YttGBAp+XvMMWprDfkzd1dFVc89TIWRLUzi0zIO1sit4aoLfrPEwm0RKZAtNj8ZIXg98mBFsI3pHYMS0h0ureQ/SInwic6jNka/CYNp6PAApDvTmPI5oL7qipw2rGHjeDjJY3M8pOGJ0FT2nM6qgQKlPckNcRlRtmz02D7wLCiGIbc+yvVCHiDdpaS+WfZVf0qPcr/Ecur4bjJBuRFDcIsQgFbfXLuv9ecfXBYVgsNw79JPmNQKz39HlKF+2X3rXiQzS7WG2soHdnVK4VSZpnIGMZip1AyijtxWMRScbdt2woOTyRv3cs5asXd0ZMD+iR9h4t1V/Fl4RtwJtfBMTq/fhwv9YoFlz6FJfUd7P13CfGi0CFaU9DrmoNKu8Q3lwr03t575BHu2IkhWkSHll79H/btERZnr3IJ2rLZWdn3bh0PLnisBQ2qDQWP9DIhrHjRbW5tp1ffqXnBnndGIBi20hfJyTzimXEJZ3pIt5YfUlos09AboAqYX9DI95bEvwtxmMNNGW2/Wc5iZX9+rdQXL10wfItlbV+XUsK8RIzngGKAMuNZMcl9BQ6BU/5ravoZQgaMJZHC0cx+yJHPI1ciJr9pCss/Sqmu9agO5V0oiXSeIBZUp/X7aOat/LJBJydd0b+YFQ3Pjk9cyTYQbNQUkOZkGsUF/ykwmCI10fW9aRZ5GBZSlPqQYpK1HPYhjAELpLXsyNZ5HwEoOFVLOcLjKc4sZ6Kl0GMgz2FLM1i76lRaOToZUaRqeq8QTqL4XTvKMZhVzWF9gEtFAXtYSAoHa5mSTgpZmRtKSmyh89vjcQPEa2m+aAqf2Idx3gHgaGHw+xqoLaaBvMWBlM5mlWg1z9VNu+6VqMSS83gTm2KP5sShouHegr3PjRvDA/cROdv5WvimzJPj8p+L/UDkfeMfGcbZKc9/rsB1LYwtyLU/4ADTF3I4v963QeEh017MwFuXwmmoYv7A7GRSJ4kLETRLvhWiFjH1xohJPN6nrn/dB35SgnRNIi1XFNNb2lRKzoc3nazAJ6t7MY6H///oE2ml8WtoIxRkU14vtTZvUOdb33Pr2zNPmuANd7/xlf5WOQQwWwWbtbAovJ2SJxM9p+c7FnfMl9YR2nm10raZ\u0000","validation":"U2FsdGVkX1/n/cdXWqhEbKWtiJ7f9R74xSQVjqH9rAC5DvIDr8JzM0hKWuScsCaAxjmCR2nMYmkFK9OsMWSCNUFFBY+E7uXVC6amcUJIMt37jU5gvJ35zKOIoV8Wy3DxD/XXOZPL6zomgUIvqj66u8juamiuAK7uV2J+cNC/54rVuwHai7Ip/YWEyXYl/BgxmHatDUv8RExT617tWLKRObmXnEcyQq6+PttkvwDdiSsfyrzduEvVHvgFB4JJ8fNnpkgl4SQipvDymxMoBxW4IpP4ACa/qzuDwScKggJCk4bo9liSh7zW4gwV40dDdDNCwVZNhQ14AxyLlkDEhzgFq77RHnJafiekU0qm5rLn1O5U/tgjUpbbTqENv+gQBKLNb0+NHxsQ/U4PNibWHKxtS7hCjrdYUGsBGtxfdVDD8yMGH8i6dz2VnHx/l+M+PhKWBIxTWvGYCLewZg24VW0/X5IOSItbFtHu6QWqS0xUOtS9wqieBwWi2sl+nJ8E4DJryzpav68l9ejH+3tGKVZWYkzoNV+Z8hawctio/I4cfwttdAW0eRdTsrFT50dEFmfBmnW9wWYedkZpTm7liyW+5f0e5672TloEz3aMTdHW7X0TVC/gWxIQqTHXxGAp78AgwZZXcEfvChl3mLCqlhdZH+P90LyGybnaCEW3hhgsjd7Kh7e35e0A/cUcBD5nxDk7//6mltgVn0roZgCZnDnbg/u02/V3IiMeFp8Bs3AtPdyV04ZKdJrxRzObl/1URnfadwgvR42b2jRA2LqxW2TORFEwsX/TVmjxmPVvPUXsXvetd9CYO1pe1Q0nBisno1IrYtIrAT1eIsGIlLnBUhg4WEGmGTJDbWLE//fA4qP6L6HyVzkiOQQZRGg8CHc39cjcmOmyjZftKhefZB3fM0HMZOdOF9v1paOFxs+JG+p2b0fxwxJF7BFv3yXvpf25/sOBIb2WehZRInjs+2FghwAZbLj99fteb/lB1OiCBkJVM/QtW0UthtGbLuJ8OXAGHxzxLNV6BSP92FSNglU3uCbw2uQVLyhcxEJvz5+oXoHP51kB9SEhwmJbahBjGaxOpqk5gW1mrua5OiLLQcwgbND/eetBkcI4Ga3Ma+CZ4faTs74KDspSIJmc1K2fRt0OnGmF/rSM1w7eFYuYuigrQhdYU/ZQlC008QUL6HxQlLmKRW8N35O/+aRKL1qG7MnMoglqp3xaYrlaX1JYRtADCuwZiUia7YvhKL2DnlGrddThfcLYqLavqKXqVC/lTYErlVN2VKScnHG0AsgINKypVBNl0t69/jKYUsd+x4gPe1yWi/gRqqH0TBOdjWi41Bx0FNfzAZHz+J3Rf/T7OUNWibN5Sf1EqldT2ZJxeouzDVQ552VfEKUXqyQhQtBUFn4kskiy\u0000","level":"SL5","identifier":"CB7D05596E224460A6AF6B4E079A3254","iterations":10000}],"SL5":"CB7D05596E224460A6AF6B4E079A3254"} -------------------------------------------------------------------------------- /test/data/make_dangling_socket.js: -------------------------------------------------------------------------------- 1 | var fs = require('fs'); 2 | var path = require('path'); 3 | var net = require('net'); 4 | 5 | function mkDirs(dir) { 6 | if (!fs.existsSync(dir)) { 7 | mkDirs(path.dirname(dir)); 8 | fs.mkdirSync(dir); 9 | } 10 | } 11 | 12 | process.on('message', function(data) { 13 | var server = net.createServer(); 14 | mkDirs(path.dirname(data.path)); 15 | server.listen(data.path, function() { 16 | setTimeout(function() { process.kill(process.pid) }); 17 | }); 18 | }); 19 | -------------------------------------------------------------------------------- /test/data/renderings.txt: -------------------------------------------------------------------------------- 1 | ## my-login 2 | 3 | my-login (Login) http://my-login.example.com 4 | Username: my-username 5 | Password: my-password 6 | my-text-field-name: my-field-value 7 | my-checkbox-field-name: ✓ 8 | 9 | Notes: 10 | my-notes 11 | 12 | ## my-amazon-web-service 13 | 14 | my-amazon-web-service (Amazon Web Service) 15 | Path: my-path 16 | Email: my-email 17 | Password: my-password 18 | Access Key Id: my-access-key-id 19 | Secret Access Key: my-secret-access-key 20 | 21 | Notes: 22 | my-notes 23 | 24 | ## my-database 25 | 26 | my-database (Database) 27 | Type: db2 28 | 29 | Server: my-server 30 | Port: my-port 31 | Database: my-database 32 | Username: my-username 33 | Password: my-password 34 | 35 | SID: my-sid 36 | Alias: my-alias 37 | Connection Options: my-connection-options 38 | 39 | Notes: 40 | my-notes 41 | 42 | ## my-email-account 43 | 44 | my-email-account (Email Account) 45 | Type: pop3 46 | Username: my-username 47 | Server: my-server 48 | Port Number: my-port-number 49 | Password: my-password 50 | Security: none 51 | Authentication Method: none 52 | 53 | SMTP Server: my-smtp-server 54 | Port Number: my-port-number 55 | Username: my-username 56 | Password: my-password 57 | Security: none 58 | Authentication Method: none 59 | 60 | Provider: my-provider 61 | Provider's Website: my-providers-website 62 | Phone Number (Local): my-local-phone-number 63 | Phone Number (Toll Free): my-toll-free-phone-number 64 | 65 | Notes: 66 | my-notes 67 | 68 | ## my-ftp-account 69 | 70 | my-ftp-account (FTP Account) 71 | Server: my-server 72 | Path: my-path 73 | User Name: my-user-name 74 | Password: my-password 75 | 76 | Provider: my-provider 77 | Provider's Website: my-providers-website 78 | Phone Number (Local): my-local-phone-number 79 | Phone Number (Toll Free): my-toll-free-phone-number 80 | 81 | Notes: 82 | my-notes 83 | 84 | ## my-generic-account 85 | 86 | my-generic-account (Generic Account) 87 | Username: my-username 88 | Password: my-password 89 | 90 | Notes: 91 | my-notes 92 | 93 | ## my-instant-messenger 94 | 95 | my-instant-messenger (Instant Messenger) 96 | Account Type: mobileme 97 | User Name / Email / ID: my-user-name 98 | Password: my-password 99 | Server: my-server 100 | Port: my-port 101 | 102 | Notes: 103 | my-notes 104 | 105 | ## my-internet-provider 106 | 107 | my-internet-provider (Internet Provider) 108 | User ID: my-user-id 109 | Password: my-password 110 | PIN: my-pin 111 | Dialup Access Number: my-dialup-access-number 112 | 113 | Website: my-website 114 | Phone (Local): my-local-phone 115 | Phone (Toll Free): my-toll-free-phone 116 | 117 | Notes: 118 | my-notes 119 | 120 | ## my-mobile-me 121 | 122 | my-mobile-me (MobileMe) 123 | Apple ID (email): my-email 124 | Member: my-member 125 | Password: my-password 126 | Available iDisk Storage: my-available-idisk-storage 127 | Renewal Date: 2012-09-10 128 | Activation Key: my-activation-key 129 | 130 | Notes: 131 | my-notes 132 | 133 | ## my-server 134 | 135 | my-server (Server) 136 | URL: my-url 137 | Username: my-username 138 | Password: my-password 139 | 140 | Admin Console URL: my-admin-console-url 141 | Admin Console Username: my-admin-console-username 142 | Console Password: my-console-password 143 | 144 | Name: my-name 145 | Website: my-website 146 | Support URL: my-support-url 147 | Support Phone #: my-support-phone-number 148 | 149 | Notes: 150 | my-notes 151 | 152 | ## my-wireless-router 153 | 154 | my-wireless-router (Wireless Router) 155 | Base Station Name: my-base-station-name 156 | Base Station Password: my-base-station-password 157 | Server / IP Address: my-server 158 | AirPort ID: my-airport-id 159 | Network Name: my-network-name 160 | Wireless Security: none 161 | Wireless Network Password: my-wireless-network-password 162 | Attached Storage Password: my-attached-storage-password 163 | 164 | Notes: 165 | my-notes 166 | 167 | ## my-itunes 168 | 169 | my-itunes (iTunes) 170 | Apple ID (email): my-apple-id 171 | Password: my-password 172 | Security Question: my-security-question 173 | Security Answer: my-security-answer 174 | 175 | Notes: 176 | my-notes 177 | 178 | ## my-identity 179 | 180 | my-identity (Identity) 181 | First Name: my-first-name 182 | Initial: my-initial 183 | Last Name: my-last-name 184 | Sex: male 185 | Birth Date: 2012-09-10 186 | Occupation: my-occupation 187 | Company: my-company 188 | Department: my-department 189 | Job Title: my-job-title 190 | 191 | Country: us 192 | State/Province: my-state 193 | Address Line 1: my-address-line-1 194 | Address Line 2: my-address-line-2 195 | City/Town/Suburb: my-city 196 | Zip/Postal Code: my-zip 197 | 198 | DefaultPhone: my-default-phone 199 | Home: my-home 200 | Cell: my-cell 201 | Business: my-business 202 | 203 | Username: my-username 204 | Reminder Question: my-reminder-question 205 | Reminder Answer: my-reminder-answer 206 | Email: my-email 207 | Website: my-website 208 | ICQ: my-icq 209 | Skype: my-skype 210 | AOL/AIM: my-aol 211 | Yahoo: my-yahoo 212 | MSN: my-msn 213 | Forum Signature: my-forum-signature 214 | 215 | Notes: 216 | my-notes 217 | 218 | ## my-secure-note 219 | 220 | my-secure-note (Secure Note) 221 | 222 | Notes: 223 | my-notes 224 | 225 | ## my-software 226 | 227 | my-software (Software) 228 | License Key: my-license-key 229 | 230 | Licensed To: my-licensed-to 231 | Registered Email: my-registered-email 232 | Company: my-company 233 | Download Page: my-download-page 234 | 235 | Publisher: my-publisher 236 | Website: my-website 237 | Retail Price: my-retail-price 238 | Support Email: my-support-email 239 | 240 | Purchase Date: 2012-09-10 241 | Order Number: my-order-number 242 | Order Total: my-order-total 243 | 244 | Notes: 245 | my-notes 246 | 247 | ## my-bank-account 248 | 249 | my-bank-account (Bank Account) 250 | Bank Name: my-bank-name 251 | Name on Account: my-name-on-account 252 | Type: checking 253 | Routing Number: my-routing-number 254 | Account Number: my-account-number 255 | SWIFT Code: my-swift-code 256 | IBAN Number: my-iban-number 257 | PIN: my-pin 258 | 259 | Phone: my-phone 260 | Address: my-address 261 | 262 | Notes: 263 | my-notes 264 | 265 | ## my-credit-card 266 | 267 | my-credit-card (Credit Card) 268 | Cardholder's Name: my-cardholders-name 269 | Type: visa 270 | Number: my-number 271 | Verification Number: my-verification-number 272 | Expiry Date: 2012-09 273 | Valid From: 2012-09 274 | 275 | Issuing Bank: my-issuing-bank 276 | Phone (Local): my-local-phone 277 | Phone (Toll Free): my-toll-free-number 278 | Phone (International): my-international-phone 279 | Website: my-website 280 | 281 | PIN: my-pin 282 | Credit Limit: my-credit-limit 283 | Cash Withdrawal Limit: my-cash-withdrawal-limit 284 | Interest Rate: my-interest-rate 285 | Issue Number: my-issue-number 286 | 287 | Notes: 288 | my-notes 289 | 290 | ## my-drivers-license 291 | 292 | my-drivers-license (Driver's License) 293 | Full Name: my-full-name 294 | Address: my-address 295 | Date of Birth: 2012-09-10 296 | Sex: male 297 | Height: my-height 298 | Number: my-number 299 | License Class: my-license-class 300 | Conditions / Restrictions: my-conditions 301 | State: my-state 302 | Country: my-country 303 | Expiry Date: 2012-09 304 | 305 | Notes: 306 | my-notes 307 | 308 | ## my-hunting-license 309 | 310 | my-hunting-license (Hunting License) 311 | Full Name: my-full-name 312 | Valid From: 2012-09-10 313 | Expires: 2012-09-10 314 | Approved Wildlife: my-approved-wildlife 315 | Maximum Quota: my-maximum-quota 316 | State: my-state 317 | Country: my-country 318 | 319 | Notes: 320 | my-notes 321 | 322 | ## my-membership 323 | 324 | my-membership (Membership) 325 | Organization: my-organization 326 | Website: my-website 327 | Telephone: my-telephone 328 | Member Name: my-member-name 329 | Member Since: 2012-09 330 | Expiry Date: 2012-09 331 | Membership #: my-membership-number 332 | Password: my-password 333 | 334 | Notes: 335 | my-notes 336 | 337 | ## my-passport 338 | 339 | my-passport (Passport) 340 | Type: my-type 341 | Issuing Country: my-issuing-country 342 | Number: my-number 343 | Full Name: my-full-name 344 | Sex: male 345 | Nationality: my-nationality 346 | Issuing Authority: my-issuing-authority 347 | Date of Birth: 2012-09-10 348 | Place of Birth: my-place-of-birth 349 | Issued On: 2012-09-10 350 | Expiry Date: 2012-09-10 351 | 352 | Notes: 353 | my-notes 354 | 355 | ## my-reward-program 356 | 357 | my-reward-program (Reward Program) 358 | Company Name: my-company-name 359 | Member Name: my-member-name 360 | Membership #: my-membership-number 361 | PIN: my-pin 362 | 363 | Membership # (Additional): my-membership-number 364 | Member Since: 2012-09 365 | Customer Service Phone: my-customer-service-phone 366 | Reservations Phone: my-reservations-phone 367 | Website: my-website 368 | 369 | Notes: 370 | my-notes 371 | 372 | ## my-social-security-number 373 | 374 | my-social-security-number (Social Security Number) 375 | Name: my-name 376 | Number: my-number 377 | 378 | Notes: 379 | my-notes 380 | 381 | ## my-password 382 | 383 | my-password (Password) my-service-name 384 | Password: my-password 385 | 386 | Notes: 387 | my-notes 388 | 389 | ## my-minimal-login 390 | 391 | my-minimal-login (Login) 392 | -------------------------------------------------------------------------------- /test/database_test.coffee: -------------------------------------------------------------------------------- 1 | assert = require 'assert' 2 | {Database} = require '..' 3 | 4 | describe 'Database', -> 5 | beforeEach -> 6 | @db = new Database('test/data/1Password.agilekeychain') 7 | 8 | describe '#unlock', -> 9 | it "returns true and unlocks the database if the given password is correct", -> 10 | result = @db.unlock('master-password') 11 | assert.equal(result, true) 12 | assert.equal(@db.locked(), false) 13 | 14 | it "returns false and does not unlock the database if the given password is incorrect", -> 15 | result = @db.unlock('wrong') 16 | assert.equal(result, false) 17 | assert.equal(@db.locked(), true) 18 | 19 | describe '#search', -> 20 | it "returns matching items", -> 21 | items = @db.search('my-minimal-login') 22 | assert.deepEqual((item.name for item in items), ['my-minimal-login']) 23 | 24 | it "unlocks the items if the database is unlocked", -> 25 | assert.equal(@db.unlock('master-password'), true) 26 | items = @db.search('my-minimal-login') 27 | assert.equal(items[0].locked(), false) 28 | 29 | it "does not unlock the items if the database is still locked", -> 30 | items = @db.search('my-minimal-login') 31 | assert.equal(items[0].locked(), true) 32 | -------------------------------------------------------------------------------- /test/encryption_keys_test.coffee: -------------------------------------------------------------------------------- 1 | fs = require 'fs' 2 | assert = require 'assert' 3 | {EncryptionKeys} = require '..' 4 | 5 | describe 'EncryptionKeys', -> 6 | beforeEach -> 7 | data = JSON.parse(fs.readFileSync('test/data/1Password.agilekeychain/data/default/encryptionKeys.js').toString()) 8 | @encryptionKeys = new EncryptionKeys(data) 9 | 10 | describe '#constructor', -> 11 | it "creates a locked database", -> 12 | assert.equal(@encryptionKeys.locked(), true) 13 | 14 | describe '#unlock', -> 15 | it "returns true and unlocks the keys if the given password is correct", -> 16 | result = @encryptionKeys.unlock('master-password') 17 | assert.equal(result, true) 18 | assert.equal(@encryptionKeys.locked(), false) 19 | 20 | it "returns false and does not unlock the keys if the given password is incorrect", -> 21 | result = @encryptionKeys.unlock('wrong') 22 | assert.equal(result, false) 23 | assert.equal(@encryptionKeys.locked(), true) 24 | 25 | describe '#get', -> 26 | describe "when unlocked", -> 27 | beforeEach -> 28 | assert.equal(@encryptionKeys.unlock('master-password'), true) 29 | 30 | it "returns the unlocked key for the given security level", -> 31 | key = @encryptionKeys.get('SL5') 32 | assert.ok(key) 33 | assert.ok(key.value) 34 | 35 | it "returns null if the given key does not exist", -> 36 | assert.equal(@encryptionKeys.get('missing-key'), null) 37 | 38 | describe "when locked", -> 39 | it "when locked throws an error", -> 40 | assert.throws((-> @encryptionKeys.get('missing-key')), 'database is locked') 41 | -------------------------------------------------------------------------------- /test/password_server_test.coffee: -------------------------------------------------------------------------------- 1 | assert = require 'assert' 2 | path = require 'path' 3 | fs = require 'fs' 4 | child_process = require 'child_process' 5 | 6 | {PasswordServer} = require '..' 7 | 8 | TMP = "#{__dirname}/tmp" 9 | TEST_TMP = "#{TMP}/password_server" 10 | testId = 0 11 | 12 | describe 'PasswordServer', -> 13 | beforeEach -> 14 | @testId = (testId += 1) 15 | @rcDir = "#{TEST_TMP}/rc.#{@testId}" 16 | @pids = [] 17 | 18 | afterEach (done) -> 19 | for pid in @pids 20 | try 21 | process.kill(pid, 'SIGKILL') 22 | catch error 23 | throw error if error.code != 'ESRCH' 24 | done() 25 | 26 | after (done) -> 27 | child_process.exec "rm -rf \"#{TEST_TMP}\"", done 28 | 29 | describe "get", -> 30 | it "returns the password served by the server", (done) -> 31 | server = new PasswordServer(@rcDir, '/db') 32 | server.start 'pass', 60000, (pid) => 33 | @pids.push(pid) 34 | server.get (pass) -> 35 | assert.equal(pass, 'pass') 36 | done() 37 | 38 | it "handles nested database paths", (done) -> 39 | server = new PasswordServer(@rcDir, '/path/to/db') 40 | server.start 'pass', 60000, (pid) => 41 | @pids.push(pid) 42 | server.get (pass) -> 43 | assert.equal(pass, 'pass') 44 | done() 45 | 46 | it "supports concurrent servers for different databases", (done) -> 47 | server1 = new PasswordServer(@rcDir, '/1') 48 | server2 = new PasswordServer(@rcDir, '/2') 49 | server1.start 'pass1', 60000, (pid1) => 50 | @pids.push(pid1) 51 | server2.start 'pass2', 60000, (pid2) => 52 | @pids.push(pid2) 53 | 54 | counter = 0 55 | server1.get (pass) -> 56 | assert.equal(pass, 'pass1') 57 | if (counter += 1) == 2 58 | done() 59 | server2.get (pass) -> 60 | assert.equal(pass, 'pass2') 61 | if (counter += 1) == 2 62 | done() 63 | 64 | it "passes null to the callback if the server is not running", (done) -> 65 | server = new PasswordServer(@rcDir, '/db') 66 | server.get (pass) -> 67 | assert.equal(pass, null) 68 | done() 69 | 70 | it "passes null to the callback if there is nothing listening on the socket", (done) -> 71 | server = new PasswordServer(@rcDir, '/db') 72 | child = child_process.fork(__dirname + '/data/make_dangling_socket.js') 73 | child.send path: server.socketPath 74 | child.on 'exit', => 75 | assert fs.existsSync(server.socketPath) 76 | server.get (pass) -> 77 | assert.equal(pass, null) 78 | done() 79 | 80 | describe "start", -> 81 | it "sets secure permissions on the socket", (done) -> 82 | server = new PasswordServer(@rcDir, '/db') 83 | server.start 'pass', 60000, (pid) => 84 | @pids.push(pid) 85 | mode = fs.statSync(server.socketPath).mode 86 | assert.equal(mode & 0o777, 0o600) 87 | done() 88 | 89 | it "only lives for the given lifetime", (done) -> 90 | server = new PasswordServer(@rcDir, '/db') 91 | server.start 'pass', 1, (pid) => 92 | @pids.push(pid) 93 | setTimeout (-> 94 | server.get (pass) -> 95 | assert.equal(pass, null) 96 | done() 97 | ), 5 98 | 99 | it "deletes an existing socket if there's nothing listening on it", (done) -> 100 | server = new PasswordServer(@rcDir, '/db') 101 | child = child_process.fork(__dirname + '/data/make_dangling_socket.js') 102 | child.send path: server.socketPath 103 | child.on 'exit', => 104 | assert fs.existsSync(server.socketPath) 105 | server.start 'pass', 60000, (pid) => 106 | @pids.push(pid) 107 | server.get (pass) -> 108 | assert.equal(pass, 'pass') 109 | done() 110 | 111 | it "shuts down an existing server if there is one", (done) -> 112 | server1 = new PasswordServer(@rcDir, '/db') 113 | server2 = new PasswordServer(@rcDir, '/db') 114 | server1.start 'pass1', 60000, (pid1) => 115 | @pids.push(pid1) 116 | server2.start 'pass2', 60000, (pid2) => 117 | @pids.push(pid2) 118 | server1.get (pass) -> 119 | assert.equal(pass, 'pass2') 120 | done() 121 | 122 | describe "stop", -> 123 | it "shuts down an existing server if there is one", (done) -> 124 | server = new PasswordServer(@rcDir, '/db') 125 | server.start 'pass1', 60000, (pid) => 126 | @pids.push(pid) 127 | server.stop => 128 | assert !fs.existsSync(server.socketPath) 129 | done() 130 | 131 | it "calls the callback if the server is not running", (done) -> 132 | server = new PasswordServer(@rcDir, '/db') 133 | server.stop -> 134 | done() 135 | 136 | it "calls the callback if there is nothing listening on the socket", (done) -> 137 | server = new PasswordServer(@rcDir, '/db') 138 | child = child_process.fork(__dirname + '/data/make_dangling_socket.js') 139 | child.send path: server.socketPath 140 | child.on 'exit', -> 141 | assert fs.existsSync(server.socketPath) 142 | server.stop -> 143 | done() 144 | -------------------------------------------------------------------------------- /test/renderer_test.coffee: -------------------------------------------------------------------------------- 1 | fs = require 'fs' 2 | assert = require 'assert' 3 | {Database,Renderer} = require '..' 4 | 5 | loadRenderings = -> 6 | text = fs.readFileSync('test/data/renderings.txt').toString() 7 | segments = text.split(/(?:^|\n\n)## (.*)\n\n/) 8 | i = 1 9 | renderings = {} 10 | while i < segments.length 11 | name = segments[i++] 12 | rendering = segments[i++] 13 | rendering = "#{rendering}\n" if !/\n$/.test(rendering) 14 | renderings[name] = rendering 15 | renderings 16 | 17 | RENDERINGS = loadRenderings() 18 | 19 | class StringStream 20 | constructor: -> 21 | @data = '' 22 | 23 | write: (data) -> 24 | @data += data 25 | 26 | contains: (pattern) -> 27 | if typeof(pattern) == 'string' 28 | @data.indexOf(pattern) != -1 29 | else 30 | pattern.test(@data) 31 | 32 | db = new Database('test/data/1Password.agilekeychain') 33 | db.unlock('master-password') 34 | 35 | render = (name, assert) -> 36 | items = db.search(name) 37 | if items.length != 1 38 | throw "#{items.length} matches for #{name}, expected 1" 39 | 40 | renderer = new Renderer(items[0]) 41 | stream = new StringStream() 42 | renderer.render(stream) 43 | 44 | stream.data 45 | 46 | describe "Renderer", -> 47 | describe '#renderRaw', -> 48 | it "renders the raw item data", -> 49 | item = db.search('my-login')[0] 50 | renderer = new Renderer(item) 51 | stream = new StringStream() 52 | renderer.renderRaw(stream) 53 | 54 | assert.ok(stream.contains(/value.*my-password/)) 55 | 56 | describe '#render', -> 57 | it "renders the raw item data for unknown types", -> 58 | source = db.search('my-login')[0] 59 | item = {} 60 | for name, value of source 61 | item[name] = if name == 'type' then 'unknown' else value 62 | renderer = new Renderer(item) 63 | stream = new StringStream() 64 | renderer.render(stream) 65 | 66 | assert.ok(stream.contains(/value.*my-password/)) 67 | 68 | it "renders a Login item correctly", -> 69 | assert.equal(render('my-login'), RENDERINGS['my-login']) 70 | 71 | it "renders an Amazon Web Service item correctly", -> 72 | assert.equal(render('my-amazon-web-service'), RENDERINGS['my-amazon-web-service']) 73 | 74 | it "renders a Database item correctly", -> 75 | assert.equal(render('my-database'), RENDERINGS['my-database']) 76 | 77 | it "renders an Email Account item correctly", -> 78 | assert.equal(render('my-email-account'), RENDERINGS['my-email-account']) 79 | 80 | it "renders an FTP Account item correctly", -> 81 | assert.equal(render('my-ftp-account'), RENDERINGS['my-ftp-account']) 82 | 83 | it "renders a Generic Account item correctly", -> 84 | assert.equal(render('my-generic-account'), RENDERINGS['my-generic-account']) 85 | 86 | it "renders an Instant Messenger item correctly", -> 87 | assert.equal(render('my-instant-messenger'), RENDERINGS['my-instant-messenger']) 88 | 89 | it "renders an Internet Provider item correctly", -> 90 | assert.equal(render('my-internet-provider'), RENDERINGS['my-internet-provider']) 91 | 92 | it "renders a MobileMe item correctly", -> 93 | assert.equal(render('my-mobile-me'), RENDERINGS['my-mobile-me']) 94 | 95 | it "renders a Server item correctly", -> 96 | assert.equal(render('my-server'), RENDERINGS['my-server']) 97 | 98 | it "renders a Wireless Router item correctly", -> 99 | assert.equal(render('my-wireless-router'), RENDERINGS['my-wireless-router']) 100 | 101 | it "renders an iTunes item correctly", -> 102 | assert.equal(render('my-itunes'), RENDERINGS['my-itunes']) 103 | 104 | it "renders an Identity item correctly", -> 105 | assert.equal(render('my-identity'), RENDERINGS['my-identity']) 106 | 107 | it "renders a Secure Note item correctly", -> 108 | assert.equal(render('my-secure-note'), RENDERINGS['my-secure-note']) 109 | 110 | it "renders a Software item correctly", -> 111 | assert.equal(render('my-software'), RENDERINGS['my-software']) 112 | 113 | it "renders a Bank Account item correctly", -> 114 | assert.equal(render('my-bank-account'), RENDERINGS['my-bank-account']) 115 | 116 | it "renders a Credit Card item correctly", -> 117 | assert.equal(render('my-credit-card'), RENDERINGS['my-credit-card']) 118 | 119 | it "renders a Drivers License item correctly", -> 120 | assert.equal(render('my-drivers-license'), RENDERINGS['my-drivers-license']) 121 | 122 | it "renders a Hunting License item correctly", -> 123 | assert.equal(render('my-hunting-license'), RENDERINGS['my-hunting-license']) 124 | 125 | it "renders a Membership item correctly", -> 126 | assert.equal(render('my-membership'), RENDERINGS['my-membership']) 127 | 128 | it "renders a Passport item correctly", -> 129 | assert.equal(render('my-passport'), RENDERINGS['my-passport']) 130 | 131 | it "renders a Reward Program item correctly", -> 132 | assert.equal(render('my-reward-program'), RENDERINGS['my-reward-program']) 133 | 134 | it "renders a Social Security Number item correctly", -> 135 | assert.equal(render('my-social-security-number'), RENDERINGS['my-social-security-number']) 136 | 137 | it "renders a Password item correctly", -> 138 | assert.equal(render('my-password'), RENDERINGS['my-password']) 139 | 140 | it "renders a minimal Login item correctly", -> 141 | assert.equal(render('my-minimal-login'), RENDERINGS['my-minimal-login']) 142 | -------------------------------------------------------------------------------- /vendor/gibberish-aes.js: -------------------------------------------------------------------------------- 1 | // Gibberish-AES 2 | // A lightweight Javascript Libray for OpenSSL compatible AES CBC encryption. 3 | // 4 | // Author: Mark Percival 5 | // Email: mark@mpercival.com 6 | // Copyright: Mark Percival - http://mpercival.com 2008 7 | // Josh Davis - http://www.josh-davis.org/ecmaScrypt 2007 8 | // Chris Veness - http://www.movable-type.co.uk/scripts/aes.html 2007 9 | // Michel I. Gallant - http://www.jensign.com/ 10 | // 11 | // License: MIT 12 | // Usage: Gibberish.encrypt("secret", "password", 256) 13 | // Outputs: AES Encrypted text encoded in Base64 14 | 15 | var GibberishAES = { 16 | // Spells out 'Salted__' 17 | SALTED_PREFIX: [83, 97, 108, 116, 101, 100, 95, 95], 18 | ZERO_IV: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 19 | 20 | Nr: 14, 21 | // Default to 256 Bit Encryption 22 | Nb: 4, 23 | Nk: 8, 24 | Decrypt: false, 25 | 26 | enc_utf8: function(s) 27 | { 28 | try { 29 | return unescape(encodeURIComponent(s)); 30 | } 31 | catch(e) { 32 | throw 'Error on UTF-8 encode'; 33 | } 34 | }, 35 | 36 | dec_utf8: function(s) 37 | { 38 | try { 39 | return decodeURIComponent(escape(s)); 40 | } 41 | catch(e) { 42 | throw ('Bad Key'); 43 | } 44 | }, 45 | 46 | padBlock: function(byteArr) 47 | { 48 | var array = []; 49 | if (byteArr.length < 16) { 50 | var cpad = 16 - byteArr.length; 51 | var array = [cpad, cpad, cpad, cpad, cpad, cpad, cpad, cpad, cpad, cpad, cpad, cpad, cpad, cpad, cpad, cpad]; 52 | } 53 | for (var i = 0; i < byteArr.length; i++) 54 | { 55 | array[i] = byteArr[i] 56 | } 57 | return array; 58 | }, 59 | 60 | block2s: function(block, lastBlock) 61 | { 62 | var string = ''; 63 | if (lastBlock) { 64 | var padding = block[15]; 65 | if (padding > 16) { 66 | throw ('Decryption error: Maybe bad key'); 67 | } 68 | if (padding == 16) { 69 | return ''; 70 | } 71 | for (var i = 0; i < 16 - padding; i++) { 72 | string += String.fromCharCode(block[i]); 73 | } 74 | } else { 75 | for (i = 0; i < 16; i++) { 76 | string += String.fromCharCode(block[i]); 77 | } 78 | } 79 | return string; 80 | }, 81 | 82 | a2h: function(numArr) 83 | { 84 | var string = ''; 85 | for (var i = 0; i < numArr.length; i++) { 86 | string += (numArr[i] < 16 ? '0': '') + numArr[i].toString(16); 87 | } 88 | return string; 89 | }, 90 | 91 | h2a: function(s) 92 | { 93 | var ret = []; 94 | s.replace(/(..)/g, 95 | function(s) { 96 | ret.push(parseInt(s, 16)); 97 | }); 98 | return ret; 99 | }, 100 | 101 | s2a: function(string) { 102 | var array = []; 103 | 104 | for (var i = 0; i < string.length; i++) 105 | { 106 | array[i] = string.charCodeAt(i); 107 | } 108 | return array; 109 | }, 110 | 111 | a2s: function(inArray) { 112 | var result = ""; 113 | 114 | for (var i = 0; i < inArray.length; i++) 115 | { 116 | result += String.fromCharCode(inArray[i]); 117 | } 118 | return result; 119 | }, 120 | 121 | size: function(newsize) 122 | { 123 | switch (newsize) 124 | { 125 | case 128: 126 | this.Nr = 10; 127 | this.Nk = 4; 128 | break; 129 | case 192: 130 | this.Nr = 12; 131 | this.Nk = 6; 132 | break; 133 | case 256: 134 | this.Nr = 14; 135 | this.Nk = 8; 136 | break; 137 | default: 138 | throw ('Invalid Key Size Specified:' + newsize); 139 | } 140 | }, 141 | 142 | randArr: function(num) { 143 | var result = [] 144 | for (var i = 0; i < num; i++) { 145 | result = result.concat(Math.floor(Math.random() * 256)); 146 | } 147 | return result; 148 | }, 149 | 150 | openSSLKey: function(passwordArr, saltArr) { 151 | // Number of rounds depends on the size of the AES in use 152 | // 3 rounds for 256 153 | // 2 rounds for the key, 1 for the IV 154 | // 2 rounds for 128 155 | // 1 round for the key, 1 round for the IV 156 | // 3 rounds for 192 since it's not evenly divided by 128 bits 157 | var rounds = this.Nr >= 12 ? 3: 2; 158 | var key = []; 159 | var iv = []; 160 | var md5_hash = []; 161 | var result = []; 162 | data00 = passwordArr.concat(saltArr); 163 | md5_hash[0] = GibberishAES.Hash.MD5(data00); 164 | result = md5_hash[0]; 165 | for (var i = 1; i < rounds; i++) { 166 | md5_hash[i] = GibberishAES.Hash.MD5(md5_hash[i - 1].concat(data00)); 167 | result = result.concat(md5_hash[i]); 168 | } 169 | key = result.slice(0, 4 * this.Nk); 170 | iv = result.slice(4 * this.Nk, 4 * this.Nk + 16); 171 | return { 172 | key: key, 173 | iv: iv 174 | }; 175 | }, 176 | 177 | rawEncrypt: function(plaintext, key, iv) { 178 | // plaintext, key and iv as byte arrays 179 | key = this.expandKey(key); 180 | var numBlocks = Math.ceil(plaintext.length / 16); 181 | var blocks = []; 182 | for (var i = 0; i < numBlocks; i++) { 183 | blocks[i] = this.padBlock(plaintext.slice(i * 16, i * 16 + 16)); 184 | } 185 | if (plaintext.length % 16 === 0) { 186 | blocks.push([16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16]); 187 | // CBC OpenSSL padding scheme 188 | numBlocks++; 189 | } 190 | var cipherBlocks = []; 191 | for (var i = 0; i < blocks.length; i++) { 192 | blocks[i] = (i === 0) ? this.xorBlocks(blocks[i], iv) : this.xorBlocks(blocks[i], cipherBlocks[i - 1]); 193 | cipherBlocks[i] = this.encryptBlock(blocks[i], key); 194 | } 195 | return cipherBlocks; 196 | }, 197 | 198 | decryptBinaryUsingKeyAndIvec: function(cryptArr, key, iv) { 199 | 200 | // cryptArr, key and iv as byte arrays 201 | key = this.expandKey(key); 202 | var numBlocks = cryptArr.length / 16; 203 | var cipherBlocks = []; 204 | for (var i = 0; i < numBlocks; i++) { 205 | cipherBlocks.push(cryptArr.slice(i * 16, (i + 1) * 16)); 206 | } 207 | var plainBlocks = []; 208 | 209 | for (var i = cipherBlocks.length - 1; i >= 0; i--) { 210 | plainBlocks[i] = this.decryptBlock(cipherBlocks[i], key); 211 | plainBlocks[i] = (i === 0) ? this.xorBlocks(plainBlocks[i], iv) : this.xorBlocks(plainBlocks[i], cipherBlocks[i - 1]); 212 | } 213 | var string = ''; 214 | for (var i = 0; i < numBlocks - 1; i++) { 215 | string += this.block2s(plainBlocks[i]); 216 | } 217 | string += this.block2s(plainBlocks[i], true); 218 | return string; 219 | }, 220 | 221 | encryptBlock: function(block, words) { 222 | this.Decrypt = false; 223 | var state = this.addRoundKey(block, words, 0); 224 | for (var round = 1; round < (this.Nr + 1); round++) { 225 | state = this.subBytes(state); 226 | state = this.shiftRows(state); 227 | if (round < this.Nr) { 228 | state = this.mixColumns(state); 229 | } 230 | //last round? don't mixColumns 231 | state = this.addRoundKey(state, words, round); 232 | } 233 | 234 | return state; 235 | }, 236 | 237 | decryptBlock: function(block, words) { 238 | this.Decrypt = true; 239 | var state = this.addRoundKey(block, words, this.Nr); 240 | for (var round = this.Nr - 1; round > -1; round--) { 241 | state = this.shiftRows(state); 242 | state = this.subBytes(state); 243 | state = this.addRoundKey(state, words, round); 244 | if (round > 0) { 245 | state = this.mixColumns(state); 246 | } 247 | //last round? don't mixColumns 248 | } 249 | 250 | return state; 251 | }, 252 | 253 | subBytes: function(state) { 254 | var S = this.Decrypt ? this.SBoxInv: this.SBox; 255 | var temp = []; 256 | for (var i = 0; i < 16; i++) { 257 | temp[i] = S[state[i]]; 258 | } 259 | return temp; 260 | }, 261 | 262 | shiftRows: function(state) { 263 | var temp = []; 264 | var shiftBy = this.Decrypt ? [0, 13, 10, 7, 4, 1, 14, 11, 8, 5, 2, 15, 12, 9, 6, 3] : [0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, 1, 6, 11]; 265 | for (var i = 0; i < 16; i++) { 266 | temp[i] = state[shiftBy[i]]; 267 | } 268 | return temp; 269 | }, 270 | 271 | mixColumns: function(state) { 272 | var t = []; 273 | if (!this.Decrypt) { 274 | for (var c = 0; c < 4; c++) { 275 | t[c * 4] = this.G2X[state[c * 4]] ^ this.G3X[state[1 + c * 4]] ^ state[2 + c * 4] ^ state[3 + c * 4]; 276 | t[1 + c * 4] = state[c * 4] ^ this.G2X[state[1 + c * 4]] ^ this.G3X[state[2 + c * 4]] ^ state[3 + c * 4]; 277 | t[2 + c * 4] = state[c * 4] ^ state[1 + c * 4] ^ this.G2X[state[2 + c * 4]] ^ this.G3X[state[3 + c * 4]]; 278 | t[3 + c * 4] = this.G3X[state[c * 4]] ^ state[1 + c * 4] ^ state[2 + c * 4] ^ this.G2X[state[3 + c * 4]]; 279 | } 280 | }else { 281 | for (var c = 0; c < 4; c++) { 282 | t[c*4] = this.GEX[state[c*4]] ^ this.GBX[state[1+c*4]] ^ this.GDX[state[2+c*4]] ^ this.G9X[state[3+c*4]]; 283 | t[1+c*4] = this.G9X[state[c*4]] ^ this.GEX[state[1+c*4]] ^ this.GBX[state[2+c*4]] ^ this.GDX[state[3+c*4]]; 284 | t[2+c*4] = this.GDX[state[c*4]] ^ this.G9X[state[1+c*4]] ^ this.GEX[state[2+c*4]] ^ this.GBX[state[3+c*4]]; 285 | t[3+c*4] = this.GBX[state[c*4]] ^ this.GDX[state[1+c*4]] ^ this.G9X[state[2+c*4]] ^ this.GEX[state[3+c*4]]; 286 | } 287 | } 288 | 289 | return t; 290 | }, 291 | 292 | addRoundKey: function(state, words, round) { 293 | var temp = []; 294 | for (var i = 0; i < 16; i++) { 295 | temp[i] = state[i] ^ words[round][i]; 296 | } 297 | return temp; 298 | }, 299 | 300 | xorBlocks: function(block1, block2) { 301 | var temp = []; 302 | for (var i = 0; i < 16; i++) { 303 | temp[i] = block1[i] ^ block2[i]; 304 | } 305 | return temp; 306 | }, 307 | 308 | expandKey: function(key) { 309 | // Expects a 1d number array 310 | var Nb = this.Nb; 311 | var Nr = this.Nr; 312 | var Nk = this.Nk; 313 | 314 | var w = []; 315 | var temp = []; 316 | 317 | for (var i = 0; i < Nk; i++) { 318 | var r = [key[4 * i], key[4 * i + 1], key[4 * i + 2], key[4 * i + 3]]; 319 | w[i] = r; 320 | } 321 | 322 | for (var i = Nk; i < (4 * (Nr + 1)); i++) { 323 | w[i] = []; 324 | for (var t = 0; t < 4; t++) { 325 | temp[t] = w[i - 1][t]; 326 | } 327 | if (i % Nk === 0) { 328 | temp = this.subWord(this.rotWord(temp)); 329 | temp[0] ^= this.Rcon[i / Nk - 1]; 330 | } else if (Nk > 6 && i % Nk == 4) { 331 | temp = this.subWord(temp); 332 | } 333 | for (var t = 0; t < 4; t++) { 334 | w[i][t] = w[i - Nk][t] ^ temp[t]; 335 | } 336 | } 337 | var flat = []; 338 | for (var i = 0; i < (Nr + 1); i++) { 339 | flat[i] = []; 340 | for (var j = 0; j < 4; j++) { 341 | flat[i].push(w[i * 4 + j][0], w[i * 4 + j][1], w[i * 4 + j][2], w[i * 4 + j][3]); 342 | } 343 | } 344 | return flat; 345 | }, 346 | 347 | subWord: function(w) { 348 | // apply SBox to 4-byte word w 349 | for (var i = 0; i < 4; i++) { 350 | w[i] = this.SBox[w[i]]; 351 | } 352 | return w; 353 | }, 354 | 355 | rotWord: function(w) { 356 | // rotate 4-byte word w left by one byte 357 | var tmp = w[0]; 358 | for (var i = 0; i < 4; i++) { 359 | w[i] = w[i + 1]; 360 | } 361 | w[3] = tmp; 362 | return w; 363 | }, 364 | 365 | 366 | // S-box 367 | SBox: [ 368 | 99, 124, 119, 123, 242, 107, 111, 197, 48, 1, 103, 43, 254, 215, 171, 369 | 118, 202, 130, 201, 125, 250, 89, 71, 240, 173, 212, 162, 175, 156, 164, 370 | 114, 192, 183, 253, 147, 38, 54, 63, 247, 204, 52, 165, 229, 241, 113, 371 | 216, 49, 21, 4, 199, 35, 195, 24, 150, 5, 154, 7, 18, 128, 226, 372 | 235, 39, 178, 117, 9, 131, 44, 26, 27, 110, 90, 160, 82, 59, 214, 373 | 179, 41, 227, 47, 132, 83, 209, 0, 237, 32, 252, 177, 91, 106, 203, 374 | 190, 57, 74, 76, 88, 207, 208, 239, 170, 251, 67, 77, 51, 133, 69, 375 | 249, 2, 127, 80, 60, 159, 168, 81, 163, 64, 143, 146, 157, 56, 245, 376 | 188, 182, 218, 33, 16, 255, 243, 210, 205, 12, 19, 236, 95, 151, 68, 377 | 23, 196, 167, 126, 61, 100, 93, 25, 115, 96, 129, 79, 220, 34, 42, 378 | 144, 136, 70, 238, 184, 20, 222, 94, 11, 219, 224, 50, 58, 10, 73, 379 | 6, 36, 92, 194, 211, 172, 98, 145, 149, 228, 121, 231, 200, 55, 109, 380 | 141, 213, 78, 169, 108, 86, 244, 234, 101, 122, 174, 8, 186, 120, 37, 381 | 46, 28, 166, 180, 198, 232, 221, 116, 31, 75, 189, 139, 138, 112, 62, 382 | 181, 102, 72, 3, 246, 14, 97, 53, 87, 185, 134, 193, 29, 158, 225, 383 | 248, 152, 17, 105, 217, 142, 148, 155, 30, 135, 233, 206, 85, 40, 223, 384 | 140, 161, 137, 13, 191, 230, 66, 104, 65, 153, 45, 15, 176, 84, 187, 385 | 22], 386 | 387 | // Precomputed lookup table for the inverse SBox 388 | SBoxInv: [ 389 | 82, 9, 106, 213, 48, 54, 165, 56, 191, 64, 163, 158, 129, 243, 215, 390 | 251, 124, 227, 57, 130, 155, 47, 255, 135, 52, 142, 67, 68, 196, 222, 391 | 233, 203, 84, 123, 148, 50, 166, 194, 35, 61, 238, 76, 149, 11, 66, 392 | 250, 195, 78, 8, 46, 161, 102, 40, 217, 36, 178, 118, 91, 162, 73, 393 | 109, 139, 209, 37, 114, 248, 246, 100, 134, 104, 152, 22, 212, 164, 92, 394 | 204, 93, 101, 182, 146, 108, 112, 72, 80, 253, 237, 185, 218, 94, 21, 395 | 70, 87, 167, 141, 157, 132, 144, 216, 171, 0, 140, 188, 211, 10, 247, 396 | 228, 88, 5, 184, 179, 69, 6, 208, 44, 30, 143, 202, 63, 15, 2, 397 | 193, 175, 189, 3, 1, 19, 138, 107, 58, 145, 17, 65, 79, 103, 220, 398 | 234, 151, 242, 207, 206, 240, 180, 230, 115, 150, 172, 116, 34, 231, 173, 399 | 53, 133, 226, 249, 55, 232, 28, 117, 223, 110, 71, 241, 26, 113, 29, 400 | 41, 197, 137, 111, 183, 98, 14, 170, 24, 190, 27, 252, 86, 62, 75, 401 | 198, 210, 121, 32, 154, 219, 192, 254, 120, 205, 90, 244, 31, 221, 168, 402 | 51, 136, 7, 199, 49, 177, 18, 16, 89, 39, 128, 236, 95, 96, 81, 403 | 127, 169, 25, 181, 74, 13, 45, 229, 122, 159, 147, 201, 156, 239, 160, 404 | 224, 59, 77, 174, 42, 245, 176, 200, 235, 187, 60, 131, 83, 153, 97, 405 | 23, 43, 4, 126, 186, 119, 214, 38, 225, 105, 20, 99, 85, 33, 12, 406 | 125], 407 | // Rijndael Rcon 408 | Rcon: [1, 2, 4, 8, 16, 32, 64, 128, 27, 54, 108, 216, 171, 77, 154, 47, 94, 409 | 188, 99, 198, 151, 53, 106, 212, 179, 125, 250, 239, 197, 145], 410 | 411 | G2X: [ 412 | 0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 0x10, 0x12, 0x14, 0x16, 413 | 0x18, 0x1a, 0x1c, 0x1e, 0x20, 0x22, 0x24, 0x26, 0x28, 0x2a, 0x2c, 0x2e, 414 | 0x30, 0x32, 0x34, 0x36, 0x38, 0x3a, 0x3c, 0x3e, 0x40, 0x42, 0x44, 0x46, 415 | 0x48, 0x4a, 0x4c, 0x4e, 0x50, 0x52, 0x54, 0x56, 0x58, 0x5a, 0x5c, 0x5e, 416 | 0x60, 0x62, 0x64, 0x66, 0x68, 0x6a, 0x6c, 0x6e, 0x70, 0x72, 0x74, 0x76, 417 | 0x78, 0x7a, 0x7c, 0x7e, 0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c, 0x8e, 418 | 0x90, 0x92, 0x94, 0x96, 0x98, 0x9a, 0x9c, 0x9e, 0xa0, 0xa2, 0xa4, 0xa6, 419 | 0xa8, 0xaa, 0xac, 0xae, 0xb0, 0xb2, 0xb4, 0xb6, 0xb8, 0xba, 0xbc, 0xbe, 420 | 0xc0, 0xc2, 0xc4, 0xc6, 0xc8, 0xca, 0xcc, 0xce, 0xd0, 0xd2, 0xd4, 0xd6, 421 | 0xd8, 0xda, 0xdc, 0xde, 0xe0, 0xe2, 0xe4, 0xe6, 0xe8, 0xea, 0xec, 0xee, 422 | 0xf0, 0xf2, 0xf4, 0xf6, 0xf8, 0xfa, 0xfc, 0xfe, 0x1b, 0x19, 0x1f, 0x1d, 423 | 0x13, 0x11, 0x17, 0x15, 0x0b, 0x09, 0x0f, 0x0d, 0x03, 0x01, 0x07, 0x05, 424 | 0x3b, 0x39, 0x3f, 0x3d, 0x33, 0x31, 0x37, 0x35, 0x2b, 0x29, 0x2f, 0x2d, 425 | 0x23, 0x21, 0x27, 0x25, 0x5b, 0x59, 0x5f, 0x5d, 0x53, 0x51, 0x57, 0x55, 426 | 0x4b, 0x49, 0x4f, 0x4d, 0x43, 0x41, 0x47, 0x45, 0x7b, 0x79, 0x7f, 0x7d, 427 | 0x73, 0x71, 0x77, 0x75, 0x6b, 0x69, 0x6f, 0x6d, 0x63, 0x61, 0x67, 0x65, 428 | 0x9b, 0x99, 0x9f, 0x9d, 0x93, 0x91, 0x97, 0x95, 0x8b, 0x89, 0x8f, 0x8d, 429 | 0x83, 0x81, 0x87, 0x85, 0xbb, 0xb9, 0xbf, 0xbd, 0xb3, 0xb1, 0xb7, 0xb5, 430 | 0xab, 0xa9, 0xaf, 0xad, 0xa3, 0xa1, 0xa7, 0xa5, 0xdb, 0xd9, 0xdf, 0xdd, 431 | 0xd3, 0xd1, 0xd7, 0xd5, 0xcb, 0xc9, 0xcf, 0xcd, 0xc3, 0xc1, 0xc7, 0xc5, 432 | 0xfb, 0xf9, 0xff, 0xfd, 0xf3, 0xf1, 0xf7, 0xf5, 0xeb, 0xe9, 0xef, 0xed, 433 | 0xe3, 0xe1, 0xe7, 0xe5 434 | ], 435 | 436 | G3X: [ 437 | 0x00, 0x03, 0x06, 0x05, 0x0c, 0x0f, 0x0a, 0x09, 0x18, 0x1b, 0x1e, 0x1d, 438 | 0x14, 0x17, 0x12, 0x11, 0x30, 0x33, 0x36, 0x35, 0x3c, 0x3f, 0x3a, 0x39, 439 | 0x28, 0x2b, 0x2e, 0x2d, 0x24, 0x27, 0x22, 0x21, 0x60, 0x63, 0x66, 0x65, 440 | 0x6c, 0x6f, 0x6a, 0x69, 0x78, 0x7b, 0x7e, 0x7d, 0x74, 0x77, 0x72, 0x71, 441 | 0x50, 0x53, 0x56, 0x55, 0x5c, 0x5f, 0x5a, 0x59, 0x48, 0x4b, 0x4e, 0x4d, 442 | 0x44, 0x47, 0x42, 0x41, 0xc0, 0xc3, 0xc6, 0xc5, 0xcc, 0xcf, 0xca, 0xc9, 443 | 0xd8, 0xdb, 0xde, 0xdd, 0xd4, 0xd7, 0xd2, 0xd1, 0xf0, 0xf3, 0xf6, 0xf5, 444 | 0xfc, 0xff, 0xfa, 0xf9, 0xe8, 0xeb, 0xee, 0xed, 0xe4, 0xe7, 0xe2, 0xe1, 445 | 0xa0, 0xa3, 0xa6, 0xa5, 0xac, 0xaf, 0xaa, 0xa9, 0xb8, 0xbb, 0xbe, 0xbd, 446 | 0xb4, 0xb7, 0xb2, 0xb1, 0x90, 0x93, 0x96, 0x95, 0x9c, 0x9f, 0x9a, 0x99, 447 | 0x88, 0x8b, 0x8e, 0x8d, 0x84, 0x87, 0x82, 0x81, 0x9b, 0x98, 0x9d, 0x9e, 448 | 0x97, 0x94, 0x91, 0x92, 0x83, 0x80, 0x85, 0x86, 0x8f, 0x8c, 0x89, 0x8a, 449 | 0xab, 0xa8, 0xad, 0xae, 0xa7, 0xa4, 0xa1, 0xa2, 0xb3, 0xb0, 0xb5, 0xb6, 450 | 0xbf, 0xbc, 0xb9, 0xba, 0xfb, 0xf8, 0xfd, 0xfe, 0xf7, 0xf4, 0xf1, 0xf2, 451 | 0xe3, 0xe0, 0xe5, 0xe6, 0xef, 0xec, 0xe9, 0xea, 0xcb, 0xc8, 0xcd, 0xce, 452 | 0xc7, 0xc4, 0xc1, 0xc2, 0xd3, 0xd0, 0xd5, 0xd6, 0xdf, 0xdc, 0xd9, 0xda, 453 | 0x5b, 0x58, 0x5d, 0x5e, 0x57, 0x54, 0x51, 0x52, 0x43, 0x40, 0x45, 0x46, 454 | 0x4f, 0x4c, 0x49, 0x4a, 0x6b, 0x68, 0x6d, 0x6e, 0x67, 0x64, 0x61, 0x62, 455 | 0x73, 0x70, 0x75, 0x76, 0x7f, 0x7c, 0x79, 0x7a, 0x3b, 0x38, 0x3d, 0x3e, 456 | 0x37, 0x34, 0x31, 0x32, 0x23, 0x20, 0x25, 0x26, 0x2f, 0x2c, 0x29, 0x2a, 457 | 0x0b, 0x08, 0x0d, 0x0e, 0x07, 0x04, 0x01, 0x02, 0x13, 0x10, 0x15, 0x16, 458 | 0x1f, 0x1c, 0x19, 0x1a 459 | ], 460 | 461 | G9X: [ 462 | 0x00, 0x09, 0x12, 0x1b, 0x24, 0x2d, 0x36, 0x3f, 0x48, 0x41, 0x5a, 0x53, 463 | 0x6c, 0x65, 0x7e, 0x77, 0x90, 0x99, 0x82, 0x8b, 0xb4, 0xbd, 0xa6, 0xaf, 464 | 0xd8, 0xd1, 0xca, 0xc3, 0xfc, 0xf5, 0xee, 0xe7, 0x3b, 0x32, 0x29, 0x20, 465 | 0x1f, 0x16, 0x0d, 0x04, 0x73, 0x7a, 0x61, 0x68, 0x57, 0x5e, 0x45, 0x4c, 466 | 0xab, 0xa2, 0xb9, 0xb0, 0x8f, 0x86, 0x9d, 0x94, 0xe3, 0xea, 0xf1, 0xf8, 467 | 0xc7, 0xce, 0xd5, 0xdc, 0x76, 0x7f, 0x64, 0x6d, 0x52, 0x5b, 0x40, 0x49, 468 | 0x3e, 0x37, 0x2c, 0x25, 0x1a, 0x13, 0x08, 0x01, 0xe6, 0xef, 0xf4, 0xfd, 469 | 0xc2, 0xcb, 0xd0, 0xd9, 0xae, 0xa7, 0xbc, 0xb5, 0x8a, 0x83, 0x98, 0x91, 470 | 0x4d, 0x44, 0x5f, 0x56, 0x69, 0x60, 0x7b, 0x72, 0x05, 0x0c, 0x17, 0x1e, 471 | 0x21, 0x28, 0x33, 0x3a, 0xdd, 0xd4, 0xcf, 0xc6, 0xf9, 0xf0, 0xeb, 0xe2, 472 | 0x95, 0x9c, 0x87, 0x8e, 0xb1, 0xb8, 0xa3, 0xaa, 0xec, 0xe5, 0xfe, 0xf7, 473 | 0xc8, 0xc1, 0xda, 0xd3, 0xa4, 0xad, 0xb6, 0xbf, 0x80, 0x89, 0x92, 0x9b, 474 | 0x7c, 0x75, 0x6e, 0x67, 0x58, 0x51, 0x4a, 0x43, 0x34, 0x3d, 0x26, 0x2f, 475 | 0x10, 0x19, 0x02, 0x0b, 0xd7, 0xde, 0xc5, 0xcc, 0xf3, 0xfa, 0xe1, 0xe8, 476 | 0x9f, 0x96, 0x8d, 0x84, 0xbb, 0xb2, 0xa9, 0xa0, 0x47, 0x4e, 0x55, 0x5c, 477 | 0x63, 0x6a, 0x71, 0x78, 0x0f, 0x06, 0x1d, 0x14, 0x2b, 0x22, 0x39, 0x30, 478 | 0x9a, 0x93, 0x88, 0x81, 0xbe, 0xb7, 0xac, 0xa5, 0xd2, 0xdb, 0xc0, 0xc9, 479 | 0xf6, 0xff, 0xe4, 0xed, 0x0a, 0x03, 0x18, 0x11, 0x2e, 0x27, 0x3c, 0x35, 480 | 0x42, 0x4b, 0x50, 0x59, 0x66, 0x6f, 0x74, 0x7d, 0xa1, 0xa8, 0xb3, 0xba, 481 | 0x85, 0x8c, 0x97, 0x9e, 0xe9, 0xe0, 0xfb, 0xf2, 0xcd, 0xc4, 0xdf, 0xd6, 482 | 0x31, 0x38, 0x23, 0x2a, 0x15, 0x1c, 0x07, 0x0e, 0x79, 0x70, 0x6b, 0x62, 483 | 0x5d, 0x54, 0x4f, 0x46 484 | ], 485 | 486 | GBX: [ 487 | 0x00, 0x0b, 0x16, 0x1d, 0x2c, 0x27, 0x3a, 0x31, 0x58, 0x53, 0x4e, 0x45, 488 | 0x74, 0x7f, 0x62, 0x69, 0xb0, 0xbb, 0xa6, 0xad, 0x9c, 0x97, 0x8a, 0x81, 489 | 0xe8, 0xe3, 0xfe, 0xf5, 0xc4, 0xcf, 0xd2, 0xd9, 0x7b, 0x70, 0x6d, 0x66, 490 | 0x57, 0x5c, 0x41, 0x4a, 0x23, 0x28, 0x35, 0x3e, 0x0f, 0x04, 0x19, 0x12, 491 | 0xcb, 0xc0, 0xdd, 0xd6, 0xe7, 0xec, 0xf1, 0xfa, 0x93, 0x98, 0x85, 0x8e, 492 | 0xbf, 0xb4, 0xa9, 0xa2, 0xf6, 0xfd, 0xe0, 0xeb, 0xda, 0xd1, 0xcc, 0xc7, 493 | 0xae, 0xa5, 0xb8, 0xb3, 0x82, 0x89, 0x94, 0x9f, 0x46, 0x4d, 0x50, 0x5b, 494 | 0x6a, 0x61, 0x7c, 0x77, 0x1e, 0x15, 0x08, 0x03, 0x32, 0x39, 0x24, 0x2f, 495 | 0x8d, 0x86, 0x9b, 0x90, 0xa1, 0xaa, 0xb7, 0xbc, 0xd5, 0xde, 0xc3, 0xc8, 496 | 0xf9, 0xf2, 0xef, 0xe4, 0x3d, 0x36, 0x2b, 0x20, 0x11, 0x1a, 0x07, 0x0c, 497 | 0x65, 0x6e, 0x73, 0x78, 0x49, 0x42, 0x5f, 0x54, 0xf7, 0xfc, 0xe1, 0xea, 498 | 0xdb, 0xd0, 0xcd, 0xc6, 0xaf, 0xa4, 0xb9, 0xb2, 0x83, 0x88, 0x95, 0x9e, 499 | 0x47, 0x4c, 0x51, 0x5a, 0x6b, 0x60, 0x7d, 0x76, 0x1f, 0x14, 0x09, 0x02, 500 | 0x33, 0x38, 0x25, 0x2e, 0x8c, 0x87, 0x9a, 0x91, 0xa0, 0xab, 0xb6, 0xbd, 501 | 0xd4, 0xdf, 0xc2, 0xc9, 0xf8, 0xf3, 0xee, 0xe5, 0x3c, 0x37, 0x2a, 0x21, 502 | 0x10, 0x1b, 0x06, 0x0d, 0x64, 0x6f, 0x72, 0x79, 0x48, 0x43, 0x5e, 0x55, 503 | 0x01, 0x0a, 0x17, 0x1c, 0x2d, 0x26, 0x3b, 0x30, 0x59, 0x52, 0x4f, 0x44, 504 | 0x75, 0x7e, 0x63, 0x68, 0xb1, 0xba, 0xa7, 0xac, 0x9d, 0x96, 0x8b, 0x80, 505 | 0xe9, 0xe2, 0xff, 0xf4, 0xc5, 0xce, 0xd3, 0xd8, 0x7a, 0x71, 0x6c, 0x67, 506 | 0x56, 0x5d, 0x40, 0x4b, 0x22, 0x29, 0x34, 0x3f, 0x0e, 0x05, 0x18, 0x13, 507 | 0xca, 0xc1, 0xdc, 0xd7, 0xe6, 0xed, 0xf0, 0xfb, 0x92, 0x99, 0x84, 0x8f, 508 | 0xbe, 0xb5, 0xa8, 0xa3 509 | ], 510 | 511 | GDX: [ 512 | 0x00, 0x0d, 0x1a, 0x17, 0x34, 0x39, 0x2e, 0x23, 0x68, 0x65, 0x72, 0x7f, 513 | 0x5c, 0x51, 0x46, 0x4b, 0xd0, 0xdd, 0xca, 0xc7, 0xe4, 0xe9, 0xfe, 0xf3, 514 | 0xb8, 0xb5, 0xa2, 0xaf, 0x8c, 0x81, 0x96, 0x9b, 0xbb, 0xb6, 0xa1, 0xac, 515 | 0x8f, 0x82, 0x95, 0x98, 0xd3, 0xde, 0xc9, 0xc4, 0xe7, 0xea, 0xfd, 0xf0, 516 | 0x6b, 0x66, 0x71, 0x7c, 0x5f, 0x52, 0x45, 0x48, 0x03, 0x0e, 0x19, 0x14, 517 | 0x37, 0x3a, 0x2d, 0x20, 0x6d, 0x60, 0x77, 0x7a, 0x59, 0x54, 0x43, 0x4e, 518 | 0x05, 0x08, 0x1f, 0x12, 0x31, 0x3c, 0x2b, 0x26, 0xbd, 0xb0, 0xa7, 0xaa, 519 | 0x89, 0x84, 0x93, 0x9e, 0xd5, 0xd8, 0xcf, 0xc2, 0xe1, 0xec, 0xfb, 0xf6, 520 | 0xd6, 0xdb, 0xcc, 0xc1, 0xe2, 0xef, 0xf8, 0xf5, 0xbe, 0xb3, 0xa4, 0xa9, 521 | 0x8a, 0x87, 0x90, 0x9d, 0x06, 0x0b, 0x1c, 0x11, 0x32, 0x3f, 0x28, 0x25, 522 | 0x6e, 0x63, 0x74, 0x79, 0x5a, 0x57, 0x40, 0x4d, 0xda, 0xd7, 0xc0, 0xcd, 523 | 0xee, 0xe3, 0xf4, 0xf9, 0xb2, 0xbf, 0xa8, 0xa5, 0x86, 0x8b, 0x9c, 0x91, 524 | 0x0a, 0x07, 0x10, 0x1d, 0x3e, 0x33, 0x24, 0x29, 0x62, 0x6f, 0x78, 0x75, 525 | 0x56, 0x5b, 0x4c, 0x41, 0x61, 0x6c, 0x7b, 0x76, 0x55, 0x58, 0x4f, 0x42, 526 | 0x09, 0x04, 0x13, 0x1e, 0x3d, 0x30, 0x27, 0x2a, 0xb1, 0xbc, 0xab, 0xa6, 527 | 0x85, 0x88, 0x9f, 0x92, 0xd9, 0xd4, 0xc3, 0xce, 0xed, 0xe0, 0xf7, 0xfa, 528 | 0xb7, 0xba, 0xad, 0xa0, 0x83, 0x8e, 0x99, 0x94, 0xdf, 0xd2, 0xc5, 0xc8, 529 | 0xeb, 0xe6, 0xf1, 0xfc, 0x67, 0x6a, 0x7d, 0x70, 0x53, 0x5e, 0x49, 0x44, 530 | 0x0f, 0x02, 0x15, 0x18, 0x3b, 0x36, 0x21, 0x2c, 0x0c, 0x01, 0x16, 0x1b, 531 | 0x38, 0x35, 0x22, 0x2f, 0x64, 0x69, 0x7e, 0x73, 0x50, 0x5d, 0x4a, 0x47, 532 | 0xdc, 0xd1, 0xc6, 0xcb, 0xe8, 0xe5, 0xf2, 0xff, 0xb4, 0xb9, 0xae, 0xa3, 533 | 0x80, 0x8d, 0x9a, 0x97 534 | ], 535 | 536 | GEX: [ 537 | 0x00, 0x0e, 0x1c, 0x12, 0x38, 0x36, 0x24, 0x2a, 0x70, 0x7e, 0x6c, 0x62, 538 | 0x48, 0x46, 0x54, 0x5a, 0xe0, 0xee, 0xfc, 0xf2, 0xd8, 0xd6, 0xc4, 0xca, 539 | 0x90, 0x9e, 0x8c, 0x82, 0xa8, 0xa6, 0xb4, 0xba, 0xdb, 0xd5, 0xc7, 0xc9, 540 | 0xe3, 0xed, 0xff, 0xf1, 0xab, 0xa5, 0xb7, 0xb9, 0x93, 0x9d, 0x8f, 0x81, 541 | 0x3b, 0x35, 0x27, 0x29, 0x03, 0x0d, 0x1f, 0x11, 0x4b, 0x45, 0x57, 0x59, 542 | 0x73, 0x7d, 0x6f, 0x61, 0xad, 0xa3, 0xb1, 0xbf, 0x95, 0x9b, 0x89, 0x87, 543 | 0xdd, 0xd3, 0xc1, 0xcf, 0xe5, 0xeb, 0xf9, 0xf7, 0x4d, 0x43, 0x51, 0x5f, 544 | 0x75, 0x7b, 0x69, 0x67, 0x3d, 0x33, 0x21, 0x2f, 0x05, 0x0b, 0x19, 0x17, 545 | 0x76, 0x78, 0x6a, 0x64, 0x4e, 0x40, 0x52, 0x5c, 0x06, 0x08, 0x1a, 0x14, 546 | 0x3e, 0x30, 0x22, 0x2c, 0x96, 0x98, 0x8a, 0x84, 0xae, 0xa0, 0xb2, 0xbc, 547 | 0xe6, 0xe8, 0xfa, 0xf4, 0xde, 0xd0, 0xc2, 0xcc, 0x41, 0x4f, 0x5d, 0x53, 548 | 0x79, 0x77, 0x65, 0x6b, 0x31, 0x3f, 0x2d, 0x23, 0x09, 0x07, 0x15, 0x1b, 549 | 0xa1, 0xaf, 0xbd, 0xb3, 0x99, 0x97, 0x85, 0x8b, 0xd1, 0xdf, 0xcd, 0xc3, 550 | 0xe9, 0xe7, 0xf5, 0xfb, 0x9a, 0x94, 0x86, 0x88, 0xa2, 0xac, 0xbe, 0xb0, 551 | 0xea, 0xe4, 0xf6, 0xf8, 0xd2, 0xdc, 0xce, 0xc0, 0x7a, 0x74, 0x66, 0x68, 552 | 0x42, 0x4c, 0x5e, 0x50, 0x0a, 0x04, 0x16, 0x18, 0x32, 0x3c, 0x2e, 0x20, 553 | 0xec, 0xe2, 0xf0, 0xfe, 0xd4, 0xda, 0xc8, 0xc6, 0x9c, 0x92, 0x80, 0x8e, 554 | 0xa4, 0xaa, 0xb8, 0xb6, 0x0c, 0x02, 0x10, 0x1e, 0x34, 0x3a, 0x28, 0x26, 555 | 0x7c, 0x72, 0x60, 0x6e, 0x44, 0x4a, 0x58, 0x56, 0x37, 0x39, 0x2b, 0x25, 556 | 0x0f, 0x01, 0x13, 0x1d, 0x47, 0x49, 0x5b, 0x55, 0x7f, 0x71, 0x63, 0x6d, 557 | 0xd7, 0xd9, 0xcb, 0xc5, 0xef, 0xe1, 0xf3, 0xfd, 0xa7, 0xa9, 0xbb, 0xb5, 558 | 0x9f, 0x91, 0x83, 0x8d 559 | ], 560 | 561 | enc: function(string, pass) { 562 | // string, password in plaintext 563 | return this.encryptUsingPassword(string, pass, true); 564 | }, 565 | 566 | encryptUsingPassword: function(string, password, salted) { 567 | var key = GibberishAES.Hash.MD5(this.s2a(password)); 568 | return this.encryptUsingKey(string, key, salted); 569 | }, 570 | 571 | encryptUsingKey: function(string, inKeyArray, salted) { 572 | var key, iv; 573 | 574 | if (salted) { 575 | var salt = this.randArr(8); 576 | var pbe = this.openSSLKey(inKeyArray, salt); 577 | key = pbe.key; 578 | iv = pbe.iv; 579 | } 580 | else { 581 | key = inKeyArray; 582 | iv = this.ZERO_IV; 583 | } 584 | 585 | string = this.s2a(string); 586 | var cipherBlocks = this.rawEncrypt(string, key, iv); 587 | 588 | if (salted) { 589 | var saltBlock = [this.SALTED_PREFIX.concat(salt)]; 590 | cipherBlocks = saltBlock.concat(cipherBlocks); 591 | } 592 | 593 | return this.Base64.encode(cipherBlocks); 594 | }, 595 | 596 | dec: function(string, pass) { 597 | // string, password in plaintext 598 | return this.decryptBase64UsingKey(string, this.s2a(pass)); 599 | }, 600 | 601 | decryptUsingPBKDF2: function(data, password, iterations) { 602 | var binaryArr = GibberishAES.Base64.decode(data); 603 | 604 | var saltArr = this.ZERO_IV; 605 | if (this.isSalted(binaryArr)) { 606 | saltArr = binaryArr.slice(8, 16); 607 | binaryArr = binaryArr.slice(16); 608 | } 609 | 610 | var t0 = new Date(); 611 | var mypbkdf2 = new PBKDF2(password, this.a2s(saltArr), iterations, 32); // key is 16bytes; ivec is 16bytes 612 | var derivedKey = mypbkdf2.deriveKey(); 613 | 614 | var t1 = new Date(); 615 | // alert ("Key generation time: " + (t1.getTime() - t0.getTime())); 616 | 617 | var key = derivedKey.slice(0, 16); 618 | var iv = derivedKey.slice(16); 619 | try { 620 | return this.decryptBinaryUsingKeyAndIvec(binaryArr, key, iv); 621 | }catch(e) { 622 | return null; 623 | } 624 | }, 625 | 626 | decryptBase64UsingKey: function(string, inKeyArray) { 627 | var binaryArr = this.Base64.decode(string); 628 | return this.decryptBinaryUsingKey(binaryArr, inKeyArray); 629 | }, 630 | 631 | decryptBinaryUsingKey: function(binaryArr, inKeyArray) { 632 | var salted = this.isSalted(binaryArr); 633 | var key, iv; 634 | 635 | if (salted) { 636 | var salt = binaryArr.slice(8, 16); 637 | 638 | var pbe = this.openSSLKey(inKeyArray, salt); 639 | key = pbe.key; 640 | iv = pbe.iv; 641 | binaryArr = binaryArr.slice(16, binaryArr.length); 642 | } 643 | else { 644 | key = GibberishAES.Hash.MD5(inKeyArray); 645 | iv = this.ZERO_IV; 646 | } 647 | 648 | try { 649 | return this.decryptBinaryUsingKeyAndIvec(binaryArr, key, iv); 650 | } 651 | catch (e) { 652 | // alert('Caught error ' + e); 653 | return null; 654 | } 655 | }, 656 | 657 | isSalted: function(cryptArr) { 658 | for (var i=0; i < 8; i++) { 659 | if (this.SALTED_PREFIX[i] != cryptArr[i]) { 660 | return false; 661 | } 662 | } 663 | return true; 664 | } 665 | }; 666 | 667 | GibberishAES.Hash = { 668 | 669 | MD5: function(numArr) { 670 | 671 | function RotateLeft(lValue, iShiftBits) { 672 | return (lValue << iShiftBits) | (lValue >>> (32 - iShiftBits)); 673 | } 674 | 675 | function AddUnsigned(lX, lY) { 676 | var lX4, 677 | lY4, 678 | lX8, 679 | lY8, 680 | lResult; 681 | lX8 = (lX & 0x80000000); 682 | lY8 = (lY & 0x80000000); 683 | lX4 = (lX & 0x40000000); 684 | lY4 = (lY & 0x40000000); 685 | lResult = (lX & 0x3FFFFFFF) + (lY & 0x3FFFFFFF); 686 | if (lX4 & lY4) { 687 | return (lResult ^ 0x80000000 ^ lX8 ^ lY8); 688 | } 689 | if (lX4 | lY4) { 690 | if (lResult & 0x40000000) { 691 | return (lResult ^ 0xC0000000 ^ lX8 ^ lY8); 692 | } else { 693 | return (lResult ^ 0x40000000 ^ lX8 ^ lY8); 694 | } 695 | } else { 696 | return (lResult ^ lX8 ^ lY8); 697 | } 698 | } 699 | 700 | function F(x, y, z) { 701 | return (x & y) | ((~x) & z); 702 | } 703 | function G(x, y, z) { 704 | return (x & z) | (y & (~z)); 705 | } 706 | function H(x, y, z) { 707 | return (x ^ y ^ z); 708 | } 709 | function I(x, y, z) { 710 | return (y ^ (x | (~z))); 711 | } 712 | 713 | function FF(a, b, c, d, x, s, ac) { 714 | a = AddUnsigned(a, AddUnsigned(AddUnsigned(F(b, c, d), x), ac)); 715 | return AddUnsigned(RotateLeft(a, s), b); 716 | }; 717 | 718 | function GG(a, b, c, d, x, s, ac) { 719 | a = AddUnsigned(a, AddUnsigned(AddUnsigned(G(b, c, d), x), ac)); 720 | return AddUnsigned(RotateLeft(a, s), b); 721 | }; 722 | 723 | function HH(a, b, c, d, x, s, ac) { 724 | a = AddUnsigned(a, AddUnsigned(AddUnsigned(H(b, c, d), x), ac)); 725 | return AddUnsigned(RotateLeft(a, s), b); 726 | }; 727 | 728 | function II(a, b, c, d, x, s, ac) { 729 | a = AddUnsigned(a, AddUnsigned(AddUnsigned(I(b, c, d), x), ac)); 730 | return AddUnsigned(RotateLeft(a, s), b); 731 | }; 732 | 733 | function ConvertToWordArray(numArr) { 734 | var lWordCount; 735 | var lMessageLength = numArr.length; 736 | var lNumberOfWords_temp1 = lMessageLength + 8; 737 | var lNumberOfWords_temp2 = (lNumberOfWords_temp1 - (lNumberOfWords_temp1 % 64)) / 64; 738 | var lNumberOfWords = (lNumberOfWords_temp2 + 1) * 16; 739 | var lWordArray = Array(lNumberOfWords - 1); 740 | var lBytePosition = 0; 741 | var lByteCount = 0; 742 | while (lByteCount < lMessageLength) { 743 | lWordCount = (lByteCount - (lByteCount % 4)) / 4; 744 | lBytePosition = (lByteCount % 4) * 8; 745 | lWordArray[lWordCount] = (lWordArray[lWordCount] | (numArr[lByteCount] << lBytePosition)); 746 | lByteCount++; 747 | } 748 | lWordCount = (lByteCount - (lByteCount % 4)) / 4; 749 | lBytePosition = (lByteCount % 4) * 8; 750 | lWordArray[lWordCount] = lWordArray[lWordCount] | (0x80 << lBytePosition); 751 | lWordArray[lNumberOfWords - 2] = lMessageLength << 3; 752 | lWordArray[lNumberOfWords - 1] = lMessageLength >>> 29; 753 | return lWordArray; 754 | }; 755 | 756 | function WordToHex(lValue) { 757 | var WordToHexValue = "", 758 | WordToHexValue_temp = "", 759 | lByte, 760 | lCount; 761 | var WordToHexArr = [] 762 | for (lCount = 0; lCount <= 3; lCount++) { 763 | lByte = (lValue >>> (lCount * 8)) & 255; 764 | WordToHexArr = WordToHexArr.concat(lByte) 765 | } 766 | return WordToHexArr; 767 | }; 768 | 769 | function Utf8Encode(string) { 770 | string = string.replace(/\r\n/g, "\n"); 771 | var utftext = ""; 772 | 773 | for (var n = 0; n < string.length; n++) { 774 | 775 | var c = string.charCodeAt(n); 776 | 777 | if (c < 128) { 778 | utftext += String.fromCharCode(c); 779 | } 780 | else if ((c > 127) && (c < 2048)) { 781 | utftext += String.fromCharCode((c >> 6) | 192); 782 | utftext += String.fromCharCode((c & 63) | 128); 783 | } 784 | else { 785 | utftext += String.fromCharCode((c >> 12) | 224); 786 | utftext += String.fromCharCode(((c >> 6) & 63) | 128); 787 | utftext += String.fromCharCode((c & 63) | 128); 788 | } 789 | 790 | } 791 | 792 | return utftext; 793 | }; 794 | 795 | var x = Array(); 796 | var k, 797 | AA, 798 | BB, 799 | CC, 800 | DD, 801 | a, 802 | b, 803 | c, 804 | d; 805 | var S11 = 7, 806 | S12 = 12, 807 | S13 = 17, 808 | S14 = 22; 809 | var S21 = 5, 810 | S22 = 9, 811 | S23 = 14, 812 | S24 = 20; 813 | var S31 = 4, 814 | S32 = 11, 815 | S33 = 16, 816 | S34 = 23; 817 | var S41 = 6, 818 | S42 = 10, 819 | S43 = 15, 820 | S44 = 21; 821 | 822 | x = ConvertToWordArray(numArr); 823 | 824 | a = 0x67452301; 825 | b = 0xEFCDAB89; 826 | c = 0x98BADCFE; 827 | d = 0x10325476; 828 | 829 | for (k = 0; k < x.length; k += 16) { 830 | AA = a; 831 | BB = b; 832 | CC = c; 833 | DD = d; 834 | a = FF(a, b, c, d, x[k + 0], S11, 0xD76AA478); 835 | d = FF(d, a, b, c, x[k + 1], S12, 0xE8C7B756); 836 | c = FF(c, d, a, b, x[k + 2], S13, 0x242070DB); 837 | b = FF(b, c, d, a, x[k + 3], S14, 0xC1BDCEEE); 838 | a = FF(a, b, c, d, x[k + 4], S11, 0xF57C0FAF); 839 | d = FF(d, a, b, c, x[k + 5], S12, 0x4787C62A); 840 | c = FF(c, d, a, b, x[k + 6], S13, 0xA8304613); 841 | b = FF(b, c, d, a, x[k + 7], S14, 0xFD469501); 842 | a = FF(a, b, c, d, x[k + 8], S11, 0x698098D8); 843 | d = FF(d, a, b, c, x[k + 9], S12, 0x8B44F7AF); 844 | c = FF(c, d, a, b, x[k + 10], S13, 0xFFFF5BB1); 845 | b = FF(b, c, d, a, x[k + 11], S14, 0x895CD7BE); 846 | a = FF(a, b, c, d, x[k + 12], S11, 0x6B901122); 847 | d = FF(d, a, b, c, x[k + 13], S12, 0xFD987193); 848 | c = FF(c, d, a, b, x[k + 14], S13, 0xA679438E); 849 | b = FF(b, c, d, a, x[k + 15], S14, 0x49B40821); 850 | a = GG(a, b, c, d, x[k + 1], S21, 0xF61E2562); 851 | d = GG(d, a, b, c, x[k + 6], S22, 0xC040B340); 852 | c = GG(c, d, a, b, x[k + 11], S23, 0x265E5A51); 853 | b = GG(b, c, d, a, x[k + 0], S24, 0xE9B6C7AA); 854 | a = GG(a, b, c, d, x[k + 5], S21, 0xD62F105D); 855 | d = GG(d, a, b, c, x[k + 10], S22, 0x2441453); 856 | c = GG(c, d, a, b, x[k + 15], S23, 0xD8A1E681); 857 | b = GG(b, c, d, a, x[k + 4], S24, 0xE7D3FBC8); 858 | a = GG(a, b, c, d, x[k + 9], S21, 0x21E1CDE6); 859 | d = GG(d, a, b, c, x[k + 14], S22, 0xC33707D6); 860 | c = GG(c, d, a, b, x[k + 3], S23, 0xF4D50D87); 861 | b = GG(b, c, d, a, x[k + 8], S24, 0x455A14ED); 862 | a = GG(a, b, c, d, x[k + 13], S21, 0xA9E3E905); 863 | d = GG(d, a, b, c, x[k + 2], S22, 0xFCEFA3F8); 864 | c = GG(c, d, a, b, x[k + 7], S23, 0x676F02D9); 865 | b = GG(b, c, d, a, x[k + 12], S24, 0x8D2A4C8A); 866 | a = HH(a, b, c, d, x[k + 5], S31, 0xFFFA3942); 867 | d = HH(d, a, b, c, x[k + 8], S32, 0x8771F681); 868 | c = HH(c, d, a, b, x[k + 11], S33, 0x6D9D6122); 869 | b = HH(b, c, d, a, x[k + 14], S34, 0xFDE5380C); 870 | a = HH(a, b, c, d, x[k + 1], S31, 0xA4BEEA44); 871 | d = HH(d, a, b, c, x[k + 4], S32, 0x4BDECFA9); 872 | c = HH(c, d, a, b, x[k + 7], S33, 0xF6BB4B60); 873 | b = HH(b, c, d, a, x[k + 10], S34, 0xBEBFBC70); 874 | a = HH(a, b, c, d, x[k + 13], S31, 0x289B7EC6); 875 | d = HH(d, a, b, c, x[k + 0], S32, 0xEAA127FA); 876 | c = HH(c, d, a, b, x[k + 3], S33, 0xD4EF3085); 877 | b = HH(b, c, d, a, x[k + 6], S34, 0x4881D05); 878 | a = HH(a, b, c, d, x[k + 9], S31, 0xD9D4D039); 879 | d = HH(d, a, b, c, x[k + 12], S32, 0xE6DB99E5); 880 | c = HH(c, d, a, b, x[k + 15], S33, 0x1FA27CF8); 881 | b = HH(b, c, d, a, x[k + 2], S34, 0xC4AC5665); 882 | a = II(a, b, c, d, x[k + 0], S41, 0xF4292244); 883 | d = II(d, a, b, c, x[k + 7], S42, 0x432AFF97); 884 | c = II(c, d, a, b, x[k + 14], S43, 0xAB9423A7); 885 | b = II(b, c, d, a, x[k + 5], S44, 0xFC93A039); 886 | a = II(a, b, c, d, x[k + 12], S41, 0x655B59C3); 887 | d = II(d, a, b, c, x[k + 3], S42, 0x8F0CCC92); 888 | c = II(c, d, a, b, x[k + 10], S43, 0xFFEFF47D); 889 | b = II(b, c, d, a, x[k + 1], S44, 0x85845DD1); 890 | a = II(a, b, c, d, x[k + 8], S41, 0x6FA87E4F); 891 | d = II(d, a, b, c, x[k + 15], S42, 0xFE2CE6E0); 892 | c = II(c, d, a, b, x[k + 6], S43, 0xA3014314); 893 | b = II(b, c, d, a, x[k + 13], S44, 0x4E0811A1); 894 | a = II(a, b, c, d, x[k + 4], S41, 0xF7537E82); 895 | d = II(d, a, b, c, x[k + 11], S42, 0xBD3AF235); 896 | c = II(c, d, a, b, x[k + 2], S43, 0x2AD7D2BB); 897 | b = II(b, c, d, a, x[k + 9], S44, 0xEB86D391); 898 | a = AddUnsigned(a, AA); 899 | b = AddUnsigned(b, BB); 900 | c = AddUnsigned(c, CC); 901 | d = AddUnsigned(d, DD); 902 | } 903 | 904 | var temp = WordToHex(a).concat(WordToHex(b), WordToHex(c), WordToHex(d)); 905 | return temp; 906 | } 907 | }; 908 | 909 | GibberishAES.Base64 = { 910 | // Takes a Nx16x1 byte array and converts it to Base64 911 | chars: [ 912 | 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 913 | 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 914 | 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 915 | 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 916 | 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 917 | 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 918 | 'w', 'x', 'y', 'z', '0', '1', '2', '3', 919 | '4', '5', '6', '7', '8', '9', '+', '/'], 920 | 921 | encode: function(b, withBreaks) { 922 | var flatArr = []; 923 | var b64 = ''; 924 | totalChunks = Math.floor(b.length * 16 / 3) 925 | for (var i = 0; i < b.length * 16; i++) { 926 | flatArr.push(b[Math.floor(i / 16)][i % 16]); 927 | } 928 | for (var i = 0; i < flatArr.length; i = i + 3) { 929 | b64 += this.chars[flatArr[i] >> 2]; 930 | b64 += this.chars[((flatArr[i] & 3) << 4) | (flatArr[i + 1] >> 4)]; 931 | if (! (flatArr[i + 1] == null)) { 932 | b64 += this.chars[((flatArr[i + 1] & 15) << 2) | (flatArr[i + 2] >> 6)]; 933 | } else { 934 | b64 += '=' 935 | } 936 | if (! (flatArr[i + 2] == null)) { 937 | b64 += this.chars[flatArr[i + 2] & 63]; 938 | } else { 939 | b64 += '=' 940 | } 941 | } 942 | // OpenSSL is super particular about line breaks 943 | var broken_b64 = b64.slice(0, 64) + '\n'; 944 | for (var i = 1; i < (Math.ceil(b64.length / 64)); i++) { 945 | broken_b64 += b64.slice(i * 64, i * 64 + 64) + (Math.ceil(b64.length / 64) == i + 1 ? '': '\n'); 946 | } 947 | return broken_b64 948 | }, 949 | 950 | decode: function(string) { 951 | string = string.replace(/\n/g, ''); 952 | var flatArr = []; 953 | var c = []; 954 | var b = []; 955 | for (var i = 0; i < string.length; i = i + 4) { 956 | c[0] = this.chars.indexOf(string.charAt(i)); 957 | c[1] = this.chars.indexOf(string.charAt(i + 1)); 958 | c[2] = this.chars.indexOf(string.charAt(i + 2)); 959 | c[3] = this.chars.indexOf(string.charAt(i + 3)); 960 | 961 | b[0] = (c[0] << 2) | (c[1] >> 4); 962 | b[1] = ((c[1] & 15) << 4) | (c[2] >> 2); 963 | b[2] = ((c[2] & 3) << 6) | c[3]; 964 | flatArr.push(b[0], b[1], b[2]); 965 | } 966 | flatArr = flatArr.slice(0, flatArr.length - (flatArr.length % 16)); 967 | return flatArr; 968 | }, 969 | 970 | }; 971 | 972 | 973 | 974 | 975 | // 976 | // JavaScript implementation of Password-Based Key Derivation Function 2 977 | // (PBKDF2) as defined in RFC 2898. 978 | // Version 1.1 979 | // Copyright (c) 2007, Parvez Anandam 980 | // parvez.anandam@cern.ch 981 | // http://anandam.name/pbkdf2 982 | // 983 | // Distributed under the BSD license 984 | // 985 | // (Uses Paul Johnston's excellent SHA-1 JavaScript library sha1.js) 986 | // Thanks to Felix Gartsman for pointing out a bug in version 1.0 987 | // 988 | 989 | // The four arguments to the constructor of the PBKDF2 object are 990 | // the password, salt, number of iterations and number of bytes in 991 | // generated key. This follows the RFC 2898 definition: PBKDF2 (P, S, c, dkLen) 992 | // 993 | // The method deriveKey takes two parameters, both callback functions: 994 | // the first is used to provide status on the computation, the second 995 | // is called with the result of the computation (the generated key in hex). 996 | // 997 | function PBKDF2(password, salt, num_iterations, num_bytes) 998 | { 999 | // Remember the password and salt 1000 | var m_bpassword = str2binb(password); 1001 | var m_salt = salt; 1002 | 1003 | // Total number of iterations 1004 | var m_total_iterations = num_iterations; 1005 | 1006 | // Run iterations in chunks instead of all at once, so as to not block. 1007 | // Define size of chunk here; adjust for slower or faster machines if necessary. 1008 | var m_iterations_in_chunk = 100; 1009 | 1010 | // Iteration counter 1011 | var m_iterations_done = 0; 1012 | 1013 | // Key length, as number of bytes 1014 | var m_key_length = num_bytes; 1015 | 1016 | // The length (number of bytes) of the output of the pseudo-random function. 1017 | // Since HMAC-SHA1 is the standard, and what is used here, it's 20 bytes. 1018 | var m_hash_length = 20; 1019 | 1020 | // Number of hash-sized blocks in the derived key (called 'l' in RFC2898) 1021 | var m_total_blocks = Math.ceil(m_key_length/m_hash_length); 1022 | 1023 | // Start computation with the first block 1024 | var m_current_block = 1; 1025 | 1026 | // Used in the HMAC-SHA1 computations 1027 | var m_ipad = new Array(16); 1028 | var m_opad = new Array(16); 1029 | 1030 | // This is where the result of the iterations gets sotred 1031 | var m_buffer = new Array(0x0,0x0,0x0,0x0,0x0); 1032 | 1033 | // The result 1034 | var m_key = ""; 1035 | 1036 | // The function to call with the result 1037 | var m_result_func; 1038 | 1039 | // The function to call with status after computing every chunk 1040 | var m_status_func; 1041 | 1042 | // Set up the HMAC-SHA1 computations 1043 | if (m_bpassword.length > 16) m_bpassword = core_sha1(m_bpassword, password.length * chrsz); 1044 | for(var i = 0; i < 16; ++i) 1045 | { 1046 | m_ipad[i] = m_bpassword[i] ^ 0x36363636; 1047 | m_opad[i] = m_bpassword[i] ^ 0x5C5C5C5C; 1048 | } 1049 | 1050 | // Starts the computation 1051 | this.deriveKey = function() 1052 | { 1053 | return this.do_PBKDF2_iterations(); 1054 | } 1055 | 1056 | 1057 | // The workhorse 1058 | this.do_PBKDF2_iterations = function() 1059 | { 1060 | while(1) { 1061 | var iterations = m_total_iterations; 1062 | 1063 | for(var i=0; i> 24 & 0xF) + 1067 | String.fromCharCode(m_current_block >> 16 & 0xF) + 1068 | String.fromCharCode(m_current_block >> 8 & 0xF) + 1069 | String.fromCharCode(m_current_block & 0xF); 1070 | 1071 | m_hash = core_sha1(m_ipad.concat(str2binb(salt_block)), 512 + salt_block.length * 8); 1072 | m_hash = core_sha1(m_opad.concat(m_hash), 512 + 160); 1073 | } 1074 | else { 1075 | m_hash = core_sha1(m_ipad.concat(m_hash), 512 + m_hash.length * 32); 1076 | m_hash = core_sha1(m_opad.concat(m_hash), 512 + 160); 1077 | } 1078 | 1079 | for(var j=0; j> 5] |= 0x80 << (24 - len % 32); 44 | x[((len + 64 >> 9) << 4) + 15] = len; 45 | 46 | var w = Array(80); 47 | var a = 1732584193; 48 | var b = -271733879; 49 | var c = -1732584194; 50 | var d = 271733878; 51 | var e = -1009589776; 52 | 53 | for(var i = 0; i < x.length; i += 16) 54 | { 55 | var olda = a; 56 | var oldb = b; 57 | var oldc = c; 58 | var oldd = d; 59 | var olde = e; 60 | 61 | for(var j = 0; j < 80; j++) 62 | { 63 | if(j < 16) w[j] = x[i + j]; 64 | else w[j] = rol(w[j-3] ^ w[j-8] ^ w[j-14] ^ w[j-16], 1); 65 | var t = safe_add(safe_add(rol(a, 5), sha1_ft(j, b, c, d)), 66 | safe_add(safe_add(e, w[j]), sha1_kt(j))); 67 | e = d; 68 | d = c; 69 | c = rol(b, 30); 70 | b = a; 71 | a = t; 72 | } 73 | 74 | a = safe_add(a, olda); 75 | b = safe_add(b, oldb); 76 | c = safe_add(c, oldc); 77 | d = safe_add(d, oldd); 78 | e = safe_add(e, olde); 79 | } 80 | return Array(a, b, c, d, e); 81 | 82 | } 83 | 84 | // Perform the appropriate triplet combination function for the current 85 | // iteration 86 | function sha1_ft(t, b, c, d) 87 | { 88 | if(t < 20) return (b & c) | ((~b) & d); 89 | if(t < 40) return b ^ c ^ d; 90 | if(t < 60) return (b & c) | (b & d) | (c & d); 91 | return b ^ c ^ d; 92 | } 93 | 94 | // Determine the appropriate additive constant for the current iteration 95 | function sha1_kt(t) 96 | { 97 | return (t < 20) ? 1518500249 : (t < 40) ? 1859775393 : 98 | (t < 60) ? -1894007588 : -899497514; 99 | } 100 | 101 | // Calculate the HMAC-SHA1 of a key and some data 102 | function core_hmac_sha1(key, data) 103 | { 104 | var bkey = str2binb(key); 105 | if(bkey.length > 16) bkey = core_sha1(bkey, key.length * chrsz); 106 | 107 | var ipad = Array(16), opad = Array(16); 108 | for(var i = 0; i < 16; i++) 109 | { 110 | ipad[i] = bkey[i] ^ 0x36363636; 111 | opad[i] = bkey[i] ^ 0x5C5C5C5C; 112 | } 113 | 114 | var hash = core_sha1(ipad.concat(str2binb(data)), 512 + data.length * chrsz); 115 | return core_sha1(opad.concat(hash), 512 + 160); 116 | } 117 | 118 | // Add integers, wrapping at 2^32. This uses 16-bit operations internally 119 | // to work around bugs in some JS interpreters. 120 | function safe_add(x, y) 121 | { 122 | var lsw = (x & 0xFFFF) + (y & 0xFFFF); 123 | var msw = (x >> 16) + (y >> 16) + (lsw >> 16); 124 | return (msw << 16) | (lsw & 0xFFFF); 125 | } 126 | 127 | // Bitwise rotate a 32-bit number to the left. 128 | function rol(num, cnt) 129 | { 130 | return (num << cnt) | (num >>> (32 - cnt)); 131 | } 132 | 133 | // Convert an 8-bit or 16-bit string to an array of big-endian words 134 | // In 8-bit function, characters >255 have their hi-byte silently ignored. 135 | function str2binb(str) 136 | { 137 | var bin = Array(); 138 | var mask = (1 << chrsz) - 1; 139 | for(var i = 0; i < str.length * chrsz; i += chrsz) 140 | bin[i>>5] |= (str.charCodeAt(i / chrsz) & mask) << (32 - chrsz - i%32); 141 | return bin; 142 | } 143 | 144 | // Convert an array of big-endian words to a string 145 | function binb2str(bin) 146 | { 147 | var str = ""; 148 | var mask = (1 << chrsz) - 1; 149 | for(var i = 0; i < bin.length * 32; i += chrsz) 150 | str += String.fromCharCode((bin[i>>5] >>> (32 - chrsz - i%32)) & mask); 151 | return str; 152 | } 153 | 154 | // Convert an array of big-endian words to a hex string. 155 | function binb2hex(binarray) 156 | { 157 | var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef"; 158 | var str = ""; 159 | for(var i = 0; i < binarray.length * 4; i++) 160 | { 161 | str += hex_tab.charAt((binarray[i>>2] >> ((3 - i%4)*8+4)) & 0xF) + 162 | hex_tab.charAt((binarray[i>>2] >> ((3 - i%4)*8 )) & 0xF); 163 | } 164 | return str; 165 | } 166 | 167 | function hex2bin(hex_str) 168 | { 169 | var char_str = ""; 170 | var num_str = ""; 171 | var i; 172 | for(i=0; i < hex_str.length; i+=2) { 173 | char_str += String.fromCharCode(parseInt(hex_str.substring(i, i+2), 16)); 174 | } 175 | return char_str; 176 | } 177 | 178 | 179 | // Convert an array of big-endian words to a base-64 string 180 | function binb2b64(binarray) 181 | { 182 | var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 183 | var str = ""; 184 | for(var i = 0; i < binarray.length * 4; i += 3) 185 | { 186 | var triplet = (((binarray[i >> 2] >> 8 * (3 - i %4)) & 0xFF) << 16) 187 | | (((binarray[i+1 >> 2] >> 8 * (3 - (i+1)%4)) & 0xFF) << 8 ) 188 | | ((binarray[i+2 >> 2] >> 8 * (3 - (i+2)%4)) & 0xFF); 189 | for(var j = 0; j < 4; j++) 190 | { 191 | if(i * 8 + j * 6 > binarray.length * 32) str += b64pad; 192 | else str += tab.charAt((triplet >> 6*(3-j)) & 0x3F); 193 | } 194 | } 195 | return str; 196 | } 197 | -------------------------------------------------------------------------------- /vendor/sha256.js: -------------------------------------------------------------------------------- 1 | // A JavaScript implementation of the Secure Hash Standard 2 | // Version 0.3 Copyright Angel Marin 2003-2004 - http://anmar.eu.org/ 3 | // Distributed under the BSD License 4 | // Some bits taken from Paul Johnston's SHA-1 implementation 5 | // 6 | 7 | // bits per input character. 8 - ASCII; 16 - Unicode 8 | var chrsz = 8; 9 | 10 | // hex output format. 0 - lowercase; 1 - uppercase 11 | var hexcase = 0; 12 | 13 | function safe_add (x, y) { 14 | var lsw = (x & 0xFFFF) + (y & 0xFFFF); 15 | var msw = (x >> 16) + (y >> 16) + (lsw >> 16); 16 | return (msw << 16) | (lsw & 0xFFFF); 17 | } 18 | 19 | function S (X, n) {return ( X >>> n ) | (X << (32 - n));} 20 | 21 | function R (X, n) {return ( X >>> n );} 22 | 23 | function Ch(x, y, z) {return ((x & y) ^ ((~x) & z));} 24 | 25 | function Maj(x, y, z) {return ((x & y) ^ (x & z) ^ (y & z));} 26 | 27 | function Sigma0256(x) {return (S(x, 2) ^ S(x, 13) ^ S(x, 22));} 28 | 29 | function Sigma1256(x) {return (S(x, 6) ^ S(x, 11) ^ S(x, 25));} 30 | 31 | function Gamma0256(x) {return (S(x, 7) ^ S(x, 18) ^ R(x, 3));} 32 | 33 | function Gamma1256(x) {return (S(x, 17) ^ S(x, 19) ^ R(x, 10));} 34 | 35 | function Sigma0512(x) {return (S(x, 28) ^ S(x, 34) ^ S(x, 39));} 36 | 37 | function Sigma1512(x) {return (S(x, 14) ^ S(x, 18) ^ S(x, 41));} 38 | 39 | function Gamma0512(x) {return (S(x, 1) ^ S(x, 8) ^ R(x, 7));} 40 | 41 | function Gamma1512(x) {return (S(x, 19) ^ S(x, 61) ^ R(x, 6));} 42 | 43 | function core_sha256 (m, l) { 44 | var K = new Array(0x428A2F98,0x71374491,0xB5C0FBCF,0xE9B5DBA5,0x3956C25B,0x59F111F1,0x923F82A4,0xAB1C5ED5,0xD807AA98,0x12835B01,0x243185BE,0x550C7DC3,0x72BE5D74,0x80DEB1FE,0x9BDC06A7,0xC19BF174,0xE49B69C1,0xEFBE4786,0xFC19DC6,0x240CA1CC,0x2DE92C6F,0x4A7484AA,0x5CB0A9DC,0x76F988DA,0x983E5152,0xA831C66D,0xB00327C8,0xBF597FC7,0xC6E00BF3,0xD5A79147,0x6CA6351,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); 45 | var HASH = new Array(0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A, 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19); 46 | var W = new Array(64); 47 | var a, b, c, d, e, f, g, h, i, j; 48 | var T1, T2; 49 | 50 | // append padding 51 | m[l >> 5] |= 0x80 << (24 - l % 32); 52 | m[((l + 64 >> 9) << 4) + 15] = l; 53 | 54 | for ( var i = 0; i>5] |= (str.charCodeAt(i / chrsz) & mask) << (24 - i%32); 107 | return bin; 108 | } 109 | 110 | function binb2str (bin) { 111 | var str = ""; 112 | var mask = (1 << chrsz) - 1; 113 | for(var i = 0; i < bin.length * 32; i += chrsz) 114 | str += String.fromCharCode((bin[i>>5] >>> (24 - i%32)) & mask); 115 | return str; 116 | } 117 | 118 | function binb2hex (binarray) { 119 | var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef"; 120 | var str = ""; 121 | for(var i = 0; i < binarray.length * 4; i++) 122 | { 123 | str += hex_tab.charAt((binarray[i>>2] >> ((3 - i%4)*8+4)) & 0xF) + 124 | hex_tab.charAt((binarray[i>>2] >> ((3 - i%4)*8 )) & 0xF); 125 | } 126 | return str; 127 | } 128 | 129 | function binb2b64 (binarray) { 130 | var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 131 | var str = ""; 132 | for(var i = 0; i < binarray.length * 4; i += 3) 133 | { 134 | var triplet = (((binarray[i >> 2] >> 8 * (3 - i %4)) & 0xFF) << 16) 135 | | (((binarray[i+1 >> 2] >> 8 * (3 - (i+1)%4)) & 0xFF) << 8 ) 136 | | ((binarray[i+2 >> 2] >> 8 * (3 - (i+2)%4)) & 0xFF); 137 | for(var j = 0; j < 4; j++) 138 | { 139 | if(i * 8 + j * 6 > binarray.length * 32) str += b64pad; 140 | else str += tab.charAt((triplet >> 6*(3-j)) & 0x3F); 141 | } 142 | } 143 | return str; 144 | } 145 | 146 | function hex_sha256(s){return binb2hex(core_sha256(str2binb(s),s.length * chrsz));} 147 | function b64_sha256(s){return binb2b64(core_sha256(str2binb(s),s.length * chrsz));} 148 | function str_sha256(s){return binb2str(core_sha256(str2binb(s),s.length * chrsz));} 149 | -------------------------------------------------------------------------------- /vendor_exports.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | "GibberishAES": GibberishAES 3 | }; 4 | --------------------------------------------------------------------------------