Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

chromeipass 0.9.9: initial commit

  • Loading branch information...
commit d59eed54bd9fabd77f4b808cfcb57a00dcb539ba 1 parent de5a981
@pfn authored
View
780 chromeipass/aes.js
@@ -0,0 +1,780 @@
+/*
+ * aes.js: implements AES - Advanced Encryption Standard
+ * from the SlowAES project, http://code.google.com/p/slowaes/
+ *
+ * Copyright (c) 2008 Josh Davis ( http://www.josh-davis.org ),
+ * Mark Percival ( http://mpercival.com ),
+ *
+ * Ported from C code written by Laurent Haan ( http://www.progressive-coding.com )
+ *
+ * Licensed under the Apache License, Version 2.0
+ * http://www.apache.org/licenses/
+ */
+
+var slowAES = {
+ /*
+ * START AES SECTION
+ */
+ aes:{
+ // structure of valid key sizes
+ keySize:{
+ SIZE_128:16,
+ SIZE_192:24,
+ SIZE_256:32
+ },
+
+ // Rijndael S-box
+ sbox:[
+ 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
+ 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
+ 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
+ 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
+ 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
+ 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
+ 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
+ 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
+ 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
+ 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
+ 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
+ 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
+ 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
+ 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
+ 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
+ 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 ],
+
+ // Rijndael Inverted S-box
+ rsbox:
+ [ 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb
+ , 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb
+ , 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e
+ , 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25
+ , 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92
+ , 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84
+ , 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06
+ , 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b
+ , 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73
+ , 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e
+ , 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b
+ , 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4
+ , 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f
+ , 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef
+ , 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61
+ , 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d ],
+
+ /* rotate the word eight bits to the left */
+ rotate:function(word)
+ {
+ var c = word[0];
+ for (var i = 0; i < 3; i++)
+ word[i] = word[i+1];
+ word[3] = c;
+
+ return word;
+ },
+
+ // Rijndael Rcon
+ Rcon:[
+ 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8,
+ 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3,
+ 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f,
+ 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d,
+ 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab,
+ 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d,
+ 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25,
+ 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01,
+ 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d,
+ 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa,
+ 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a,
+ 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02,
+ 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a,
+ 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef,
+ 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94,
+ 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04,
+ 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f,
+ 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5,
+ 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33,
+ 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb ],
+
+ G2X: [
+ 0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 0x10, 0x12, 0x14, 0x16,
+ 0x18, 0x1a, 0x1c, 0x1e, 0x20, 0x22, 0x24, 0x26, 0x28, 0x2a, 0x2c, 0x2e,
+ 0x30, 0x32, 0x34, 0x36, 0x38, 0x3a, 0x3c, 0x3e, 0x40, 0x42, 0x44, 0x46,
+ 0x48, 0x4a, 0x4c, 0x4e, 0x50, 0x52, 0x54, 0x56, 0x58, 0x5a, 0x5c, 0x5e,
+ 0x60, 0x62, 0x64, 0x66, 0x68, 0x6a, 0x6c, 0x6e, 0x70, 0x72, 0x74, 0x76,
+ 0x78, 0x7a, 0x7c, 0x7e, 0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c, 0x8e,
+ 0x90, 0x92, 0x94, 0x96, 0x98, 0x9a, 0x9c, 0x9e, 0xa0, 0xa2, 0xa4, 0xa6,
+ 0xa8, 0xaa, 0xac, 0xae, 0xb0, 0xb2, 0xb4, 0xb6, 0xb8, 0xba, 0xbc, 0xbe,
+ 0xc0, 0xc2, 0xc4, 0xc6, 0xc8, 0xca, 0xcc, 0xce, 0xd0, 0xd2, 0xd4, 0xd6,
+ 0xd8, 0xda, 0xdc, 0xde, 0xe0, 0xe2, 0xe4, 0xe6, 0xe8, 0xea, 0xec, 0xee,
+ 0xf0, 0xf2, 0xf4, 0xf6, 0xf8, 0xfa, 0xfc, 0xfe, 0x1b, 0x19, 0x1f, 0x1d,
+ 0x13, 0x11, 0x17, 0x15, 0x0b, 0x09, 0x0f, 0x0d, 0x03, 0x01, 0x07, 0x05,
+ 0x3b, 0x39, 0x3f, 0x3d, 0x33, 0x31, 0x37, 0x35, 0x2b, 0x29, 0x2f, 0x2d,
+ 0x23, 0x21, 0x27, 0x25, 0x5b, 0x59, 0x5f, 0x5d, 0x53, 0x51, 0x57, 0x55,
+ 0x4b, 0x49, 0x4f, 0x4d, 0x43, 0x41, 0x47, 0x45, 0x7b, 0x79, 0x7f, 0x7d,
+ 0x73, 0x71, 0x77, 0x75, 0x6b, 0x69, 0x6f, 0x6d, 0x63, 0x61, 0x67, 0x65,
+ 0x9b, 0x99, 0x9f, 0x9d, 0x93, 0x91, 0x97, 0x95, 0x8b, 0x89, 0x8f, 0x8d,
+ 0x83, 0x81, 0x87, 0x85, 0xbb, 0xb9, 0xbf, 0xbd, 0xb3, 0xb1, 0xb7, 0xb5,
+ 0xab, 0xa9, 0xaf, 0xad, 0xa3, 0xa1, 0xa7, 0xa5, 0xdb, 0xd9, 0xdf, 0xdd,
+ 0xd3, 0xd1, 0xd7, 0xd5, 0xcb, 0xc9, 0xcf, 0xcd, 0xc3, 0xc1, 0xc7, 0xc5,
+ 0xfb, 0xf9, 0xff, 0xfd, 0xf3, 0xf1, 0xf7, 0xf5, 0xeb, 0xe9, 0xef, 0xed,
+ 0xe3, 0xe1, 0xe7, 0xe5
+ ],
+
+ G3X: [
+ 0x00, 0x03, 0x06, 0x05, 0x0c, 0x0f, 0x0a, 0x09, 0x18, 0x1b, 0x1e, 0x1d,
+ 0x14, 0x17, 0x12, 0x11, 0x30, 0x33, 0x36, 0x35, 0x3c, 0x3f, 0x3a, 0x39,
+ 0x28, 0x2b, 0x2e, 0x2d, 0x24, 0x27, 0x22, 0x21, 0x60, 0x63, 0x66, 0x65,
+ 0x6c, 0x6f, 0x6a, 0x69, 0x78, 0x7b, 0x7e, 0x7d, 0x74, 0x77, 0x72, 0x71,
+ 0x50, 0x53, 0x56, 0x55, 0x5c, 0x5f, 0x5a, 0x59, 0x48, 0x4b, 0x4e, 0x4d,
+ 0x44, 0x47, 0x42, 0x41, 0xc0, 0xc3, 0xc6, 0xc5, 0xcc, 0xcf, 0xca, 0xc9,
+ 0xd8, 0xdb, 0xde, 0xdd, 0xd4, 0xd7, 0xd2, 0xd1, 0xf0, 0xf3, 0xf6, 0xf5,
+ 0xfc, 0xff, 0xfa, 0xf9, 0xe8, 0xeb, 0xee, 0xed, 0xe4, 0xe7, 0xe2, 0xe1,
+ 0xa0, 0xa3, 0xa6, 0xa5, 0xac, 0xaf, 0xaa, 0xa9, 0xb8, 0xbb, 0xbe, 0xbd,
+ 0xb4, 0xb7, 0xb2, 0xb1, 0x90, 0x93, 0x96, 0x95, 0x9c, 0x9f, 0x9a, 0x99,
+ 0x88, 0x8b, 0x8e, 0x8d, 0x84, 0x87, 0x82, 0x81, 0x9b, 0x98, 0x9d, 0x9e,
+ 0x97, 0x94, 0x91, 0x92, 0x83, 0x80, 0x85, 0x86, 0x8f, 0x8c, 0x89, 0x8a,
+ 0xab, 0xa8, 0xad, 0xae, 0xa7, 0xa4, 0xa1, 0xa2, 0xb3, 0xb0, 0xb5, 0xb6,
+ 0xbf, 0xbc, 0xb9, 0xba, 0xfb, 0xf8, 0xfd, 0xfe, 0xf7, 0xf4, 0xf1, 0xf2,
+ 0xe3, 0xe0, 0xe5, 0xe6, 0xef, 0xec, 0xe9, 0xea, 0xcb, 0xc8, 0xcd, 0xce,
+ 0xc7, 0xc4, 0xc1, 0xc2, 0xd3, 0xd0, 0xd5, 0xd6, 0xdf, 0xdc, 0xd9, 0xda,
+ 0x5b, 0x58, 0x5d, 0x5e, 0x57, 0x54, 0x51, 0x52, 0x43, 0x40, 0x45, 0x46,
+ 0x4f, 0x4c, 0x49, 0x4a, 0x6b, 0x68, 0x6d, 0x6e, 0x67, 0x64, 0x61, 0x62,
+ 0x73, 0x70, 0x75, 0x76, 0x7f, 0x7c, 0x79, 0x7a, 0x3b, 0x38, 0x3d, 0x3e,
+ 0x37, 0x34, 0x31, 0x32, 0x23, 0x20, 0x25, 0x26, 0x2f, 0x2c, 0x29, 0x2a,
+ 0x0b, 0x08, 0x0d, 0x0e, 0x07, 0x04, 0x01, 0x02, 0x13, 0x10, 0x15, 0x16,
+ 0x1f, 0x1c, 0x19, 0x1a
+ ],
+
+ G9X: [
+ 0x00, 0x09, 0x12, 0x1b, 0x24, 0x2d, 0x36, 0x3f, 0x48, 0x41, 0x5a, 0x53,
+ 0x6c, 0x65, 0x7e, 0x77, 0x90, 0x99, 0x82, 0x8b, 0xb4, 0xbd, 0xa6, 0xaf,
+ 0xd8, 0xd1, 0xca, 0xc3, 0xfc, 0xf5, 0xee, 0xe7, 0x3b, 0x32, 0x29, 0x20,
+ 0x1f, 0x16, 0x0d, 0x04, 0x73, 0x7a, 0x61, 0x68, 0x57, 0x5e, 0x45, 0x4c,
+ 0xab, 0xa2, 0xb9, 0xb0, 0x8f, 0x86, 0x9d, 0x94, 0xe3, 0xea, 0xf1, 0xf8,
+ 0xc7, 0xce, 0xd5, 0xdc, 0x76, 0x7f, 0x64, 0x6d, 0x52, 0x5b, 0x40, 0x49,
+ 0x3e, 0x37, 0x2c, 0x25, 0x1a, 0x13, 0x08, 0x01, 0xe6, 0xef, 0xf4, 0xfd,
+ 0xc2, 0xcb, 0xd0, 0xd9, 0xae, 0xa7, 0xbc, 0xb5, 0x8a, 0x83, 0x98, 0x91,
+ 0x4d, 0x44, 0x5f, 0x56, 0x69, 0x60, 0x7b, 0x72, 0x05, 0x0c, 0x17, 0x1e,
+ 0x21, 0x28, 0x33, 0x3a, 0xdd, 0xd4, 0xcf, 0xc6, 0xf9, 0xf0, 0xeb, 0xe2,
+ 0x95, 0x9c, 0x87, 0x8e, 0xb1, 0xb8, 0xa3, 0xaa, 0xec, 0xe5, 0xfe, 0xf7,
+ 0xc8, 0xc1, 0xda, 0xd3, 0xa4, 0xad, 0xb6, 0xbf, 0x80, 0x89, 0x92, 0x9b,
+ 0x7c, 0x75, 0x6e, 0x67, 0x58, 0x51, 0x4a, 0x43, 0x34, 0x3d, 0x26, 0x2f,
+ 0x10, 0x19, 0x02, 0x0b, 0xd7, 0xde, 0xc5, 0xcc, 0xf3, 0xfa, 0xe1, 0xe8,
+ 0x9f, 0x96, 0x8d, 0x84, 0xbb, 0xb2, 0xa9, 0xa0, 0x47, 0x4e, 0x55, 0x5c,
+ 0x63, 0x6a, 0x71, 0x78, 0x0f, 0x06, 0x1d, 0x14, 0x2b, 0x22, 0x39, 0x30,
+ 0x9a, 0x93, 0x88, 0x81, 0xbe, 0xb7, 0xac, 0xa5, 0xd2, 0xdb, 0xc0, 0xc9,
+ 0xf6, 0xff, 0xe4, 0xed, 0x0a, 0x03, 0x18, 0x11, 0x2e, 0x27, 0x3c, 0x35,
+ 0x42, 0x4b, 0x50, 0x59, 0x66, 0x6f, 0x74, 0x7d, 0xa1, 0xa8, 0xb3, 0xba,
+ 0x85, 0x8c, 0x97, 0x9e, 0xe9, 0xe0, 0xfb, 0xf2, 0xcd, 0xc4, 0xdf, 0xd6,
+ 0x31, 0x38, 0x23, 0x2a, 0x15, 0x1c, 0x07, 0x0e, 0x79, 0x70, 0x6b, 0x62,
+ 0x5d, 0x54, 0x4f, 0x46
+ ],
+
+ GBX: [
+ 0x00, 0x0b, 0x16, 0x1d, 0x2c, 0x27, 0x3a, 0x31, 0x58, 0x53, 0x4e, 0x45,
+ 0x74, 0x7f, 0x62, 0x69, 0xb0, 0xbb, 0xa6, 0xad, 0x9c, 0x97, 0x8a, 0x81,
+ 0xe8, 0xe3, 0xfe, 0xf5, 0xc4, 0xcf, 0xd2, 0xd9, 0x7b, 0x70, 0x6d, 0x66,
+ 0x57, 0x5c, 0x41, 0x4a, 0x23, 0x28, 0x35, 0x3e, 0x0f, 0x04, 0x19, 0x12,
+ 0xcb, 0xc0, 0xdd, 0xd6, 0xe7, 0xec, 0xf1, 0xfa, 0x93, 0x98, 0x85, 0x8e,
+ 0xbf, 0xb4, 0xa9, 0xa2, 0xf6, 0xfd, 0xe0, 0xeb, 0xda, 0xd1, 0xcc, 0xc7,
+ 0xae, 0xa5, 0xb8, 0xb3, 0x82, 0x89, 0x94, 0x9f, 0x46, 0x4d, 0x50, 0x5b,
+ 0x6a, 0x61, 0x7c, 0x77, 0x1e, 0x15, 0x08, 0x03, 0x32, 0x39, 0x24, 0x2f,
+ 0x8d, 0x86, 0x9b, 0x90, 0xa1, 0xaa, 0xb7, 0xbc, 0xd5, 0xde, 0xc3, 0xc8,
+ 0xf9, 0xf2, 0xef, 0xe4, 0x3d, 0x36, 0x2b, 0x20, 0x11, 0x1a, 0x07, 0x0c,
+ 0x65, 0x6e, 0x73, 0x78, 0x49, 0x42, 0x5f, 0x54, 0xf7, 0xfc, 0xe1, 0xea,
+ 0xdb, 0xd0, 0xcd, 0xc6, 0xaf, 0xa4, 0xb9, 0xb2, 0x83, 0x88, 0x95, 0x9e,
+ 0x47, 0x4c, 0x51, 0x5a, 0x6b, 0x60, 0x7d, 0x76, 0x1f, 0x14, 0x09, 0x02,
+ 0x33, 0x38, 0x25, 0x2e, 0x8c, 0x87, 0x9a, 0x91, 0xa0, 0xab, 0xb6, 0xbd,
+ 0xd4, 0xdf, 0xc2, 0xc9, 0xf8, 0xf3, 0xee, 0xe5, 0x3c, 0x37, 0x2a, 0x21,
+ 0x10, 0x1b, 0x06, 0x0d, 0x64, 0x6f, 0x72, 0x79, 0x48, 0x43, 0x5e, 0x55,
+ 0x01, 0x0a, 0x17, 0x1c, 0x2d, 0x26, 0x3b, 0x30, 0x59, 0x52, 0x4f, 0x44,
+ 0x75, 0x7e, 0x63, 0x68, 0xb1, 0xba, 0xa7, 0xac, 0x9d, 0x96, 0x8b, 0x80,
+ 0xe9, 0xe2, 0xff, 0xf4, 0xc5, 0xce, 0xd3, 0xd8, 0x7a, 0x71, 0x6c, 0x67,
+ 0x56, 0x5d, 0x40, 0x4b, 0x22, 0x29, 0x34, 0x3f, 0x0e, 0x05, 0x18, 0x13,
+ 0xca, 0xc1, 0xdc, 0xd7, 0xe6, 0xed, 0xf0, 0xfb, 0x92, 0x99, 0x84, 0x8f,
+ 0xbe, 0xb5, 0xa8, 0xa3
+ ],
+
+ GDX: [
+ 0x00, 0x0d, 0x1a, 0x17, 0x34, 0x39, 0x2e, 0x23, 0x68, 0x65, 0x72, 0x7f,
+ 0x5c, 0x51, 0x46, 0x4b, 0xd0, 0xdd, 0xca, 0xc7, 0xe4, 0xe9, 0xfe, 0xf3,
+ 0xb8, 0xb5, 0xa2, 0xaf, 0x8c, 0x81, 0x96, 0x9b, 0xbb, 0xb6, 0xa1, 0xac,
+ 0x8f, 0x82, 0x95, 0x98, 0xd3, 0xde, 0xc9, 0xc4, 0xe7, 0xea, 0xfd, 0xf0,
+ 0x6b, 0x66, 0x71, 0x7c, 0x5f, 0x52, 0x45, 0x48, 0x03, 0x0e, 0x19, 0x14,
+ 0x37, 0x3a, 0x2d, 0x20, 0x6d, 0x60, 0x77, 0x7a, 0x59, 0x54, 0x43, 0x4e,
+ 0x05, 0x08, 0x1f, 0x12, 0x31, 0x3c, 0x2b, 0x26, 0xbd, 0xb0, 0xa7, 0xaa,
+ 0x89, 0x84, 0x93, 0x9e, 0xd5, 0xd8, 0xcf, 0xc2, 0xe1, 0xec, 0xfb, 0xf6,
+ 0xd6, 0xdb, 0xcc, 0xc1, 0xe2, 0xef, 0xf8, 0xf5, 0xbe, 0xb3, 0xa4, 0xa9,
+ 0x8a, 0x87, 0x90, 0x9d, 0x06, 0x0b, 0x1c, 0x11, 0x32, 0x3f, 0x28, 0x25,
+ 0x6e, 0x63, 0x74, 0x79, 0x5a, 0x57, 0x40, 0x4d, 0xda, 0xd7, 0xc0, 0xcd,
+ 0xee, 0xe3, 0xf4, 0xf9, 0xb2, 0xbf, 0xa8, 0xa5, 0x86, 0x8b, 0x9c, 0x91,
+ 0x0a, 0x07, 0x10, 0x1d, 0x3e, 0x33, 0x24, 0x29, 0x62, 0x6f, 0x78, 0x75,
+ 0x56, 0x5b, 0x4c, 0x41, 0x61, 0x6c, 0x7b, 0x76, 0x55, 0x58, 0x4f, 0x42,
+ 0x09, 0x04, 0x13, 0x1e, 0x3d, 0x30, 0x27, 0x2a, 0xb1, 0xbc, 0xab, 0xa6,
+ 0x85, 0x88, 0x9f, 0x92, 0xd9, 0xd4, 0xc3, 0xce, 0xed, 0xe0, 0xf7, 0xfa,
+ 0xb7, 0xba, 0xad, 0xa0, 0x83, 0x8e, 0x99, 0x94, 0xdf, 0xd2, 0xc5, 0xc8,
+ 0xeb, 0xe6, 0xf1, 0xfc, 0x67, 0x6a, 0x7d, 0x70, 0x53, 0x5e, 0x49, 0x44,
+ 0x0f, 0x02, 0x15, 0x18, 0x3b, 0x36, 0x21, 0x2c, 0x0c, 0x01, 0x16, 0x1b,
+ 0x38, 0x35, 0x22, 0x2f, 0x64, 0x69, 0x7e, 0x73, 0x50, 0x5d, 0x4a, 0x47,
+ 0xdc, 0xd1, 0xc6, 0xcb, 0xe8, 0xe5, 0xf2, 0xff, 0xb4, 0xb9, 0xae, 0xa3,
+ 0x80, 0x8d, 0x9a, 0x97
+ ],
+
+ GEX: [
+ 0x00, 0x0e, 0x1c, 0x12, 0x38, 0x36, 0x24, 0x2a, 0x70, 0x7e, 0x6c, 0x62,
+ 0x48, 0x46, 0x54, 0x5a, 0xe0, 0xee, 0xfc, 0xf2, 0xd8, 0xd6, 0xc4, 0xca,
+ 0x90, 0x9e, 0x8c, 0x82, 0xa8, 0xa6, 0xb4, 0xba, 0xdb, 0xd5, 0xc7, 0xc9,
+ 0xe3, 0xed, 0xff, 0xf1, 0xab, 0xa5, 0xb7, 0xb9, 0x93, 0x9d, 0x8f, 0x81,
+ 0x3b, 0x35, 0x27, 0x29, 0x03, 0x0d, 0x1f, 0x11, 0x4b, 0x45, 0x57, 0x59,
+ 0x73, 0x7d, 0x6f, 0x61, 0xad, 0xa3, 0xb1, 0xbf, 0x95, 0x9b, 0x89, 0x87,
+ 0xdd, 0xd3, 0xc1, 0xcf, 0xe5, 0xeb, 0xf9, 0xf7, 0x4d, 0x43, 0x51, 0x5f,
+ 0x75, 0x7b, 0x69, 0x67, 0x3d, 0x33, 0x21, 0x2f, 0x05, 0x0b, 0x19, 0x17,
+ 0x76, 0x78, 0x6a, 0x64, 0x4e, 0x40, 0x52, 0x5c, 0x06, 0x08, 0x1a, 0x14,
+ 0x3e, 0x30, 0x22, 0x2c, 0x96, 0x98, 0x8a, 0x84, 0xae, 0xa0, 0xb2, 0xbc,
+ 0xe6, 0xe8, 0xfa, 0xf4, 0xde, 0xd0, 0xc2, 0xcc, 0x41, 0x4f, 0x5d, 0x53,
+ 0x79, 0x77, 0x65, 0x6b, 0x31, 0x3f, 0x2d, 0x23, 0x09, 0x07, 0x15, 0x1b,
+ 0xa1, 0xaf, 0xbd, 0xb3, 0x99, 0x97, 0x85, 0x8b, 0xd1, 0xdf, 0xcd, 0xc3,
+ 0xe9, 0xe7, 0xf5, 0xfb, 0x9a, 0x94, 0x86, 0x88, 0xa2, 0xac, 0xbe, 0xb0,
+ 0xea, 0xe4, 0xf6, 0xf8, 0xd2, 0xdc, 0xce, 0xc0, 0x7a, 0x74, 0x66, 0x68,
+ 0x42, 0x4c, 0x5e, 0x50, 0x0a, 0x04, 0x16, 0x18, 0x32, 0x3c, 0x2e, 0x20,
+ 0xec, 0xe2, 0xf0, 0xfe, 0xd4, 0xda, 0xc8, 0xc6, 0x9c, 0x92, 0x80, 0x8e,
+ 0xa4, 0xaa, 0xb8, 0xb6, 0x0c, 0x02, 0x10, 0x1e, 0x34, 0x3a, 0x28, 0x26,
+ 0x7c, 0x72, 0x60, 0x6e, 0x44, 0x4a, 0x58, 0x56, 0x37, 0x39, 0x2b, 0x25,
+ 0x0f, 0x01, 0x13, 0x1d, 0x47, 0x49, 0x5b, 0x55, 0x7f, 0x71, 0x63, 0x6d,
+ 0xd7, 0xd9, 0xcb, 0xc5, 0xef, 0xe1, 0xf3, 0xfd, 0xa7, 0xa9, 0xbb, 0xb5,
+ 0x9f, 0x91, 0x83, 0x8d
+ ],
+
+ // Key Schedule Core
+ core:function(word,iteration)
+ {
+ /* rotate the 32-bit word 8 bits to the left */
+ word = this.rotate(word);
+ /* apply S-Box substitution on all 4 parts of the 32-bit word */
+ for (var i = 0; i < 4; ++i)
+ word[i] = this.sbox[word[i]];
+ /* XOR the output of the rcon operation with i to the first part (leftmost) only */
+ word[0] = word[0]^this.Rcon[iteration];
+ return word;
+ },
+
+ /* Rijndael's key expansion
+ * expands an 128,192,256 key into an 176,208,240 bytes key
+ *
+ * expandedKey is a pointer to an char array of large enough size
+ * key is a pointer to a non-expanded key
+ */
+ expandKey:function(key,size)
+ {
+ var expandedKeySize = (16*(this.numberOfRounds(size)+1));
+
+ /* current expanded keySize, in bytes */
+ var currentSize = 0;
+ var rconIteration = 1;
+ var t = []; // temporary 4-byte variable
+
+ var expandedKey = [];
+ for(var i = 0;i < expandedKeySize;i++)
+ expandedKey[i] = 0;
+
+ /* set the 16,24,32 bytes of the expanded key to the input key */
+ for (var j = 0; j < size; j++)
+ expandedKey[j] = key[j];
+ currentSize += size;
+
+ while (currentSize < expandedKeySize)
+ {
+ /* assign the previous 4 bytes to the temporary value t */
+ for (var k = 0; k < 4; k++)
+ t[k] = expandedKey[(currentSize - 4) + k];
+
+ /* every 16,24,32 bytes we apply the core schedule to t
+ * and increment rconIteration afterwards
+ */
+ if(currentSize % size == 0)
+ t = this.core(t, rconIteration++);
+
+ /* For 256-bit keys, we add an extra sbox to the calculation */
+ if(size == this.keySize.SIZE_256 && ((currentSize % size) == 16))
+ for(var l = 0; l < 4; l++)
+ t[l] = this.sbox[t[l]];
+
+ /* We XOR t with the four-byte block 16,24,32 bytes before the new expanded key.
+ * This becomes the next four bytes in the expanded key.
+ */
+ for(var m = 0; m < 4; m++) {
+ expandedKey[currentSize] = expandedKey[currentSize - size] ^ t[m];
+ currentSize++;
+ }
+ }
+ return expandedKey;
+ },
+
+ // Adds (XORs) the round key to the state
+ addRoundKey:function(state,roundKey)
+ {
+ for (var i = 0; i < 16; i++)
+ state[i] ^= roundKey[i];
+ return state;
+ },
+
+ // Creates a round key from the given expanded key and the
+ // position within the expanded key.
+ createRoundKey:function(expandedKey,roundKeyPointer)
+ {
+ var roundKey = [];
+ for (var i = 0; i < 4; i++)
+ for (var j = 0; j < 4; j++)
+ roundKey[j*4+i] = expandedKey[roundKeyPointer + i*4 + j];
+ return roundKey;
+ },
+
+ /* substitute all the values from the state with the value in the SBox
+ * using the state value as index for the SBox
+ */
+ subBytes:function(state,isInv)
+ {
+ for (var i = 0; i < 16; i++)
+ state[i] = isInv?this.rsbox[state[i]]:this.sbox[state[i]];
+ return state;
+ },
+
+ /* iterate over the 4 rows and call shiftRow() with that row */
+ shiftRows:function(state,isInv)
+ {
+ for (var i = 0; i < 4; i++)
+ state = this.shiftRow(state,i*4, i,isInv);
+ return state;
+ },
+
+ /* each iteration shifts the row to the left by 1 */
+ shiftRow:function(state,statePointer,nbr,isInv)
+ {
+ for (var i = 0; i < nbr; i++)
+ {
+ if(isInv)
+ {
+ var tmp = state[statePointer + 3];
+ for (var j = 3; j > 0; j--)
+ state[statePointer + j] = state[statePointer + j-1];
+ state[statePointer] = tmp;
+ }
+ else
+ {
+ var tmp = state[statePointer];
+ for (var j = 0; j < 3; j++)
+ state[statePointer + j] = state[statePointer + j+1];
+ state[statePointer + 3] = tmp;
+ }
+ }
+ return state;
+ },
+
+ // galois multiplication of 8 bit characters a and b
+ galois_multiplication:function(a,b)
+ {
+ var p = 0;
+ for(var counter = 0; counter < 8; counter++)
+ {
+ if((b & 1) == 1)
+ p ^= a;
+ if(p > 0x100) p ^= 0x100;
+ var hi_bit_set = (a & 0x80); //keep p 8 bit
+ a <<= 1;
+ if(a > 0x100) a ^= 0x100; //keep a 8 bit
+ if(hi_bit_set == 0x80)
+ a ^= 0x1b;
+ if(a > 0x100) a ^= 0x100; //keep a 8 bit
+ b >>= 1;
+ if(b > 0x100) b ^= 0x100; //keep b 8 bit
+ }
+ return p;
+ },
+
+ // galois multipication of the 4x4 matrix
+ mixColumns:function(state,isInv)
+ {
+ var column = [];
+ /* iterate over the 4 columns */
+ for (var i = 0; i < 4; i++)
+ {
+ /* construct one column by iterating over the 4 rows */
+ for (var j = 0; j < 4; j++)
+ column[j] = state[(j*4)+i];
+ /* apply the mixColumn on one column */
+ column = this.mixColumn(column,isInv);
+ /* put the values back into the state */
+ for (var k = 0; k < 4; k++)
+ state[(k*4)+i] = column[k];
+ }
+ return state;
+ },
+
+ // galois multipication of 1 column of the 4x4 matrix
+ mixColumn:function(column,isInv)
+ {
+ var mult = [];
+ if(isInv)
+ mult = [14,9,13,11];
+ else
+ mult = [2,1,1,3];
+ var cpy = [];
+ for(var i = 0; i < 4; i++)
+ cpy[i] = column[i];
+
+ column[0] = this.galois_multiplication(cpy[0],mult[0]) ^
+ this.galois_multiplication(cpy[3],mult[1]) ^
+ this.galois_multiplication(cpy[2],mult[2]) ^
+ this.galois_multiplication(cpy[1],mult[3]);
+ column[1] = this.galois_multiplication(cpy[1],mult[0]) ^
+ this.galois_multiplication(cpy[0],mult[1]) ^
+ this.galois_multiplication(cpy[3],mult[2]) ^
+ this.galois_multiplication(cpy[2],mult[3]);
+ column[2] = this.galois_multiplication(cpy[2],mult[0]) ^
+ this.galois_multiplication(cpy[1],mult[1]) ^
+ this.galois_multiplication(cpy[0],mult[2]) ^
+ this.galois_multiplication(cpy[3],mult[3]);
+ column[3] = this.galois_multiplication(cpy[3],mult[0]) ^
+ this.galois_multiplication(cpy[2],mult[1]) ^
+ this.galois_multiplication(cpy[1],mult[2]) ^
+ this.galois_multiplication(cpy[0],mult[3]);
+ return column;
+ },
+
+ // applies the 4 operations of the forward round in sequence
+ round:function(state, roundKey)
+ {
+ state = this.subBytes(state,false);
+ state = this.shiftRows(state,false);
+ state = this.mixColumns(state,false);
+ state = this.addRoundKey(state, roundKey);
+ return state;
+ },
+
+ // applies the 4 operations of the inverse round in sequence
+ invRound:function(state,roundKey)
+ {
+ state = this.shiftRows(state,true);
+ state = this.subBytes(state,true);
+ state = this.addRoundKey(state, roundKey);
+ state = this.mixColumns(state,true);
+ return state;
+ },
+
+ /*
+ * Perform the initial operations, the standard round, and the final operations
+ * of the forward aes, creating a round key for each round
+ */
+ main:function(state,expandedKey,nbrRounds)
+ {
+ state = this.addRoundKey(state, this.createRoundKey(expandedKey,0));
+ for (var i = 1; i < nbrRounds; i++)
+ state = this.round(state, this.createRoundKey(expandedKey,16*i));
+ state = this.subBytes(state,false);
+ state = this.shiftRows(state,false);
+ state = this.addRoundKey(state, this.createRoundKey(expandedKey,16*nbrRounds));
+ return state;
+ },
+
+ /*
+ * Perform the initial operations, the standard round, and the final operations
+ * of the inverse aes, creating a round key for each round
+ */
+ invMain:function(state, expandedKey, nbrRounds)
+ {
+ state = this.addRoundKey(state, this.createRoundKey(expandedKey,16*nbrRounds));
+ for (var i = nbrRounds-1; i > 0; i--)
+ state = this.invRound(state, this.createRoundKey(expandedKey,16*i));
+ state = this.shiftRows(state,true);
+ state = this.subBytes(state,true);
+ state = this.addRoundKey(state, this.createRoundKey(expandedKey,0));
+ return state;
+ },
+
+ numberOfRounds:function(size)
+ {
+ var nbrRounds;
+ switch (size) /* set the number of rounds */
+ {
+ case this.keySize.SIZE_128:
+ nbrRounds = 10;
+ break;
+ case this.keySize.SIZE_192:
+ nbrRounds = 12;
+ break;
+ case this.keySize.SIZE_256:
+ nbrRounds = 14;
+ break;
+ default:
+ return null;
+ break;
+ }
+ return nbrRounds;
+ },
+
+ // encrypts a 128 bit input block against the given key of size specified
+ encrypt:function(input,key,size)
+ {
+ var output = [];
+ var block = []; /* the 128 bit block to encode */
+ var nbrRounds = this.numberOfRounds(size);
+ /* Set the block values, for the block:
+ * a0,0 a0,1 a0,2 a0,3
+ * a1,0 a1,1 a1,2 a1,3
+ * a2,0 a2,1 a2,2 a2,3
+ * a3,0 a3,1 a3,2 a3,3
+ * the mapping order is a0,0 a1,0 a2,0 a3,0 a0,1 a1,1 ... a2,3 a3,3
+ */
+ for (var i = 0; i < 4; i++) /* iterate over the columns */
+ for (var j = 0; j < 4; j++) /* iterate over the rows */
+ block[(i+(j*4))] = input[(i*4)+j];
+
+ /* expand the key into an 176, 208, 240 bytes key */
+ var expandedKey = this.expandKey(key, size); /* the expanded key */
+ /* encrypt the block using the expandedKey */
+ block = this.main(block, expandedKey, nbrRounds);
+ for (var k = 0; k < 4; k++) /* unmap the block again into the output */
+ for (var l = 0; l < 4; l++) /* iterate over the rows */
+ output[(k*4)+l] = block[(k+(l*4))];
+ return output;
+ },
+
+ // decrypts a 128 bit input block against the given key of size specified
+ decrypt:function(input, key, size)
+ {
+ var output = [];
+ var block = []; /* the 128 bit block to decode */
+ var nbrRounds = this.numberOfRounds(size);
+ /* Set the block values, for the block:
+ * a0,0 a0,1 a0,2 a0,3
+ * a1,0 a1,1 a1,2 a1,3
+ * a2,0 a2,1 a2,2 a2,3
+ * a3,0 a3,1 a3,2 a3,3
+ * the mapping order is a0,0 a1,0 a2,0 a3,0 a0,1 a1,1 ... a2,3 a3,3
+ */
+ for (var i = 0; i < 4; i++) /* iterate over the columns */
+ for (var j = 0; j < 4; j++) /* iterate over the rows */
+ block[(i+(j*4))] = input[(i*4)+j];
+ /* expand the key into an 176, 208, 240 bytes key */
+ var expandedKey = this.expandKey(key, size);
+ /* decrypt the block using the expandedKey */
+ block = this.invMain(block, expandedKey, nbrRounds);
+ for (var k = 0; k < 4; k++)/* unmap the block again into the output */
+ for (var l = 0; l < 4; l++)/* iterate over the rows */
+ output[(k*4)+l] = block[(k+(l*4))];
+ return output;
+ }
+ },
+ /*
+ * END AES SECTION
+ */
+
+ /*
+ * START MODE OF OPERATION SECTION
+ */
+ //structure of supported modes of operation
+ modeOfOperation:{
+ OFB:0,
+ CFB:1,
+ CBC:2
+ },
+
+ // get the next block of 16 bytes (aes operates on 128bits)
+ getNextBlock: function(bytesIn,start,end,mode)
+ {
+ if(end - start > 16)
+ end = start + 16;
+
+ return bytesIn.slice(start, end);
+ },
+
+ /*
+ * Mode of Operation Encryption
+ * bytesIn - Input String as array of bytes
+ * mode - mode of type modeOfOperation
+ * key - a number array of length 'size'
+ * size - the bit length of the key
+ * iv - the 128 bit number array Initialization Vector
+ */
+ encrypt: function (bytesIn, mode, key, iv)
+ {
+ var size = key.length;
+ if(iv.length%16)
+ {
+ throw 'iv length must be 128 bits.';
+ }
+ // the AES input/output
+ var byteArray = [];
+ var input = [];
+ var output = [];
+ var ciphertext = [];
+ var cipherOut = [];
+ // char firstRound
+ var firstRound = true;
+ if (mode == this.modeOfOperation.CBC)
+ this.padBytesIn(bytesIn);
+ if (bytesIn !== null)
+ {
+ for (var j = 0;j < Math.ceil(bytesIn.length/16); j++)
+ {
+ var start = j*16;
+ var end = j*16+16;
+ if(j*16+16 > bytesIn.length)
+ end = bytesIn.length;
+ byteArray = this.getNextBlock(bytesIn,start,end,mode);
+ if (mode == this.modeOfOperation.CFB)
+ {
+ if (firstRound)
+ {
+ output = this.aes.encrypt(iv, key, size);
+ firstRound = false;
+ }
+ else
+ output = this.aes.encrypt(input, key, size);
+ for (var i = 0; i < 16; i++)
+ ciphertext[i] = byteArray[i] ^ output[i];
+ for(var k = 0;k < end-start;k++)
+ cipherOut.push(ciphertext[k]);
+ input = ciphertext;
+ }
+ else if (mode == this.modeOfOperation.OFB)
+ {
+ if (firstRound)
+ {
+ output = this.aes.encrypt(iv, key, size);
+ firstRound = false;
+ }
+ else
+ output = this.aes.encrypt(input, key, size);
+ for (var i = 0; i < 16; i++)
+ ciphertext[i] = byteArray[i] ^ output[i];
+ for(var k = 0;k < end-start;k++)
+ cipherOut.push(ciphertext[k]);
+ input = output;
+ }
+ else if (mode == this.modeOfOperation.CBC)
+ {
+ for (var i = 0; i < 16; i++)
+ input[i] = byteArray[i] ^ ((firstRound) ? iv[i] : ciphertext[i]);
+ firstRound = false;
+ ciphertext = this.aes.encrypt(input, key, size);
+ // always 16 bytes because of the padding for CBC
+ for(var k = 0;k < 16;k++)
+ cipherOut.push(ciphertext[k]);
+ }
+ }
+ }
+ return cipherOut;
+ },
+
+ /*
+ * Mode of Operation Decryption
+ * cipherIn - Encrypted String as array of bytes
+ * originalsize - The unencrypted string length - required for CBC
+ * mode - mode of type modeOfOperation
+ * key - a number array of length 'size'
+ * size - the bit length of the key
+ * iv - the 128 bit number array Initialization Vector
+ */
+ decrypt:function(cipherIn,mode,key,iv)
+ {
+ var size = key.length;
+ if(iv.length%16)
+ {
+ throw 'iv length must be 128 bits.';
+ }
+ // the AES input/output
+ var ciphertext = [];
+ var input = [];
+ var output = [];
+ var byteArray = [];
+ var bytesOut = [];
+ // char firstRound
+ var firstRound = true;
+ if (cipherIn !== null)
+ {
+ for (var j = 0;j < Math.ceil(cipherIn.length/16); j++)
+ {
+ var start = j*16;
+ var end = j*16+16;
+ if(j*16+16 > cipherIn.length)
+ end = cipherIn.length;
+ ciphertext = this.getNextBlock(cipherIn,start,end,mode);
+ if (mode == this.modeOfOperation.CFB)
+ {
+ if (firstRound)
+ {
+ output = this.aes.encrypt(iv, key, size);
+ firstRound = false;
+ }
+ else
+ output = this.aes.encrypt(input, key, size);
+ for (i = 0; i < 16; i++)
+ byteArray[i] = output[i] ^ ciphertext[i];
+ for(var k = 0;k < end-start;k++)
+ bytesOut.push(byteArray[k]);
+ input = ciphertext;
+ }
+ else if (mode == this.modeOfOperation.OFB)
+ {
+ if (firstRound)
+ {
+ output = this.aes.encrypt(iv, key, size);
+ firstRound = false;
+ }
+ else
+ output = this.aes.encrypt(input, key, size);
+ for (i = 0; i < 16; i++)
+ byteArray[i] = output[i] ^ ciphertext[i];
+ for(var k = 0;k < end-start;k++)
+ bytesOut.push(byteArray[k]);
+ input = output;
+ }
+ else if(mode == this.modeOfOperation.CBC)
+ {
+ output = this.aes.decrypt(ciphertext, key, size);
+ for (i = 0; i < 16; i++)
+ byteArray[i] = ((firstRound) ? iv[i] : input[i]) ^ output[i];
+ firstRound = false;
+ for(var k = 0;k < end-start;k++)
+ bytesOut.push(byteArray[k]);
+ input = ciphertext;
+ }
+ }
+ if(mode == this.modeOfOperation.CBC)
+ this.unpadBytesOut(bytesOut);
+ }
+ return bytesOut;
+ },
+ padBytesIn: function(data) {
+ var len = data.length;
+ var padByte = 16 - (len % 16);
+ for (var i = 0; i < padByte; i++) {
+ data.push(padByte);
+ }
+ },
+ unpadBytesOut: function(data) {
+ var padCount = 0;
+ var padByte = -1;
+ var blockSize = 16;
+ for (var i = data.length - 1; i >= data.length-1 - blockSize; i--) {
+ if (data[i] <= blockSize) {
+ if (padByte == -1)
+ padByte = data[i];
+ if (data[i] != padByte) {
+ padCount = 0;
+ break;
+ }
+ padCount++;
+ } else
+ break;
+ if (padCount == padByte)
+ break;
+ }
+ if (padCount > 0)
+ data.splice(data.length - padCount, padCount);
+ }
+ /*
+ * END MODE OF OPERATION SECTION
+ */
+};
View
328 chromeipass/background.html
@@ -0,0 +1,328 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <script src="aes.js"></script>
+ <script src="cryptoHelpers.js"></script>
+</head>
+<body>
+ <script>
+ var keySize = 8; // wtf? stupid cryptoHelpers
+ var associated = false;
+ var errorMessage = null;
+ var KEEPASS_HTTP_URL = "http://localhost:19455/";
+ var CHROMEIPASS_CACHE_TIME = 30 * 1000; // millis
+
+ var KEYNAME = "chromeipass-cryptokey-name";
+ var KEYBODY = "chromeipass-key";
+
+ var _cache = {};
+
+ var to_s = cryptoHelpers.convertByteArrayToString;
+ var to_b = cryptoHelpers.convertStringToByteArray;
+
+ function b64e(d) {
+ return btoa(to_s(d));
+ }
+ function b64d(d) {
+ return to_b(atob(d));
+ }
+
+ function setBadge(text) {
+ //chrome.browserAction.setBadgeText({ text: text });
+ }
+ setBadge("?");
+
+ function showPageAction(callback, tab) {
+ chrome.pageAction.setPopup({ tabId: tab.id, popup: "popup.html" });
+ chrome.pageAction.show(tab.id);
+ }
+ function hidePageAction(callback, tab) {
+ chrome.pageAction.hide(tab.id);
+ }
+
+ function showAlert(callback, tab, message) {
+ alert(message);
+ }
+ var tab_login_list = {};
+ function selectLoginPopup(callback, tab, logins) {
+ // TODO set an icon indicating user action is required
+ chrome.pageAction.setPopup({
+ tabId: tab.id,
+ popup: "login_popup.html"
+ });
+ tab_login_list["tab" + tab.id] = logins;
+ chrome.pageAction.show(tab.id);
+ }
+
+ chrome.tabs.onRemoved.addListener(function(tabId, info) {
+ delete tab_login_list["tab" + tabId];
+ });
+
+ function selectFieldPopup(callback, tab) {
+ // TODO set an icon indicating user action is required
+ chrome.pageAction.setPopup({
+ tabId: tab.id,
+ popup: "field_popup.html"
+ });
+ chrome.pageAction.show(tab.id);
+ }
+
+ function getPasswords(callback, tab, url, submiturl, force) {
+ console.log("url + submiturl: [" + url + "] => [" + submiturl + "]");
+ _prune_cache();
+ showPageAction(null, tab);
+ var cached = _find_cache_item(url, submiturl);
+ if (cached && !force) {
+ callback(cached);
+ return;
+ }
+ if (!_test_associate()) return;
+ var request = {
+ RequestType: "get-logins"
+ };
+ var result = _set_verifier(request);
+ var id = result[0];
+ var key = result[1];
+ var iv = request.Nonce;
+ request.Url = b64e(slowAES.encrypt(to_b(url),
+ slowAES.modeOfOperation.CBC, b64d(key), b64d(iv)));
+ if (submiturl)
+ request.SubmitUrl = b64e(slowAES.encrypt(to_b(submiturl),
+ slowAES.modeOfOperation.CBC, b64d(key), b64d(iv)));
+ result = _send(request);
+ var s = result[0];
+ var response = result[1];
+ var entries = [];
+ if (_success(s)) {
+ var r = JSON.parse(response);
+ if (_verify_response(r, key, id)) {
+ var iv = r.Nonce;
+ for (var i = 0; i < r.Entries.length; i++) {
+ _decrypt_entry(r.Entries[i], key, iv);
+ }
+ entries = r.Entries;
+ _cache_item(url, submiturl, entries);
+ } else {
+ _cache_item(url, submiturl, []);
+ console.log("getPasswords for " + url + " rejected");
+ }
+ }
+ callback(entries);
+ }
+ function getStatus(callback) {
+ var configured = false;
+ var keyname;
+ if (KEYNAME in localStorage && KEYBODY in localStorage) {
+ configured = true;
+ keyname = localStorage[KEYNAME];
+ }
+ callback({
+ configured: configured,
+ keyname: keyname,
+ associated: associated,
+ error: errorMessage
+ });
+ errorMessage = null;
+ }
+ function associate() {
+ if (associated) return;
+ var rawkey = cryptoHelpers.generateSharedKey(keySize);
+ var key = b64e(rawkey);
+ var request = {
+ RequestType: "associate",
+ Key: key
+ };
+ _set_verifier(request, key);
+ var result = _send(request);
+ if (_success(result[0])) {
+ var r = JSON.parse(result[1]);
+ var id = r.Id;
+ if (!_verify_response(r, key)) {
+ setBadge("X");
+ errorMessage = "KeePass association failed, try again";
+ return;
+ }
+ _set_crypto_key(id, key);
+ associated = true;
+ }
+ }
+
+ var requestHandlers = {
+ 'show_actions': showPageAction,
+ 'get_passwords': getPasswords,
+ 'select_login': selectLoginPopup,
+ 'select_field': selectFieldPopup,
+ 'get_status': getStatus,
+ 'associate': associate,
+ 'alert': showAlert
+ };
+
+ function onRequest(request, sender, callback) {
+ if (request.action in requestHandlers) {
+ var args = request.args || [];
+ args.unshift(sender.tab);
+ args.unshift(callback);
+ requestHandlers[request.action].apply(this, args);
+ }
+ }
+ chrome.extension.onRequest.addListener(onRequest);
+
+///////////////////////////////////////////////////////////////////////////////
+
+ function _test_associate() {
+ if (associated) {
+ return true;
+ }
+ var request = {
+ "RequestType": "test-associate",
+ };
+ var info = _set_verifier(request);
+ if (!info) return false;
+ var id = info[0];
+ var key = info[1];
+ var result = _send(request);
+ var s = result[0];
+ var response = result[1];
+ if (_success(s)) {
+ var r = JSON.parse(response);
+ if (!_verify_response(r, key, id)) {
+ delete localStorage[KEYNAME];
+ errorMessage = "Encryption key is unrecognized";
+ console.log("Encryption key is unrecognized!");
+ }
+ }
+ if (associated) setBadge("");
+ return associated;
+ }
+ function _set_verifier(request, inkey) {
+ var key = null;
+ var id = null;
+ if (inkey) {
+ key = inkey;
+ } else {
+ var info = _get_crypto_key();
+ if (info == null) {
+ return null;
+ }
+ id = info[0];
+ key = info[1];
+ }
+ if (id) request.Id = id;
+ var iv = cryptoHelpers.generateSharedKey(keySize);
+ request.Nonce = b64e(iv);
+ var decodedKey = b64d(key);
+ request.Verifier = b64e(slowAES.encrypt(to_b(request.Nonce),
+ slowAES.modeOfOperation.CBC, b64d(key), iv));
+ return [id, key];
+ }
+ function _verify_response(response, key, id) {
+ associated = response.Success;
+ if (!response.Success) return false;
+ var iv = response.Nonce;
+ var crypted = response.Verifier;
+ var value = slowAES.decrypt(b64d(crypted),
+ slowAES.modeOfOperation.CBC, b64d(key), b64d(iv));
+ value = to_s(value);
+ associated = value == iv;
+ if (id) {
+ associated = associated && id == response.Id;
+ }
+ return associated;
+
+ }
+ function _get_crypto_key() {
+ var keyname = localStorage[KEYNAME];
+ var key = null;
+ if (keyname) {
+ key = localStorage[KEYBODY];
+ }
+ if (!key) {
+ setBadge("!!!");
+ }
+ return key ? [keyname, key] : null;
+ }
+ function _set_crypto_key(id, key) {
+ localStorage[KEYNAME] = id;
+ localStorage[KEYBODY] = key;
+ }
+
+ function _find_cache_item(url, submiturl) {
+ var key = url + "!!" + submiturl;
+ var item = _cache[key];
+ var now = Date.now();
+ if (item && (item.ts + CHROMEIPASS_CACHE_TIME) > now) {
+ item.ts = now;
+ return item.entries;
+ }
+ return null;
+ }
+ function _cache_item(url, submiturl, entries) {
+ var key = url + "!!" + submiturl;
+ var item = {};
+ item.ts = Date.now();
+ item.entries = entries;
+ _cache[key] = item;
+ }
+ function _prune_cache() {
+ var now = Date.now();
+ for (var i in _cache) {
+ var item = _cache[i];
+ if ((item.ts + CHROMEIPASS_CACHE_TIME) < now) delete _cache[i];
+ }
+ }
+ function _decrypt_entry(e, key, iv) {
+ e.Login = to_s(slowAES.decrypt(b64d(e.Login),
+ slowAES.modeOfOperation.CBC, b64d(key), b64d(iv)));
+ e.Uuid = to_s(slowAES.decrypt(b64d(e.Uuid),
+ slowAES.modeOfOperation.CBC, b64d(key), b64d(iv)));
+ e.Name = to_s(slowAES.decrypt(b64d(e.Name),
+ slowAES.modeOfOperation.CBC, b64d(key), b64d(iv)));
+ e.Password = to_s(slowAES.decrypt(b64d(e.Password),
+ slowAES.modeOfOperation.CBC, b64d(key), b64d(iv)));
+ }
+ function _success(s) {
+ var success = s >= 200 && s <= 299;
+ if (!success) {
+ setBadge("!!!");
+ errorMessage = "Unknown error: " + s;
+ console.log("error: "+ s);
+ if (s == 503) {
+ console.log("KeePass database is not open");
+ errorMessage = "KeePass database is not open";
+ }
+ } else {
+ setBadge("");
+ }
+ return success;
+ }
+ function _send(request) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("POST", KEEPASS_HTTP_URL, false);
+ xhr.setRequestHeader("Content-Type", "application/json");
+ try {
+ var r = JSON.stringify(request);
+ console.log("Request: " + r);
+ xhr.send(r);
+ }
+ catch (e) { console.log("KeePassHttp: " + e); }
+ console.log("Response: " + xhr.status + " => " + xhr.responseText);
+ return [xhr.status, xhr.responseText];
+ }
+
+ chrome.contextMenus.create({
+ "title": "Fill User + Pass",
+ "contexts": [ "editable" ],
+ "onclick": function(info, tab) {
+ chrome.tabs.sendRequest(tab.id, { action: "fill_user_pass" });
+ }
+ });
+ chrome.contextMenus.create({
+ "title": "Fill Pass Only",
+ "contexts": [ "editable" ],
+ "onclick": function(info, tab) {
+ chrome.tabs.sendRequest(tab.id, { action: "fill_pass_only" });
+ }
+ });
+ </script>
+</body>
+</html>
View
159 chromeipass/chromeipass.js
@@ -0,0 +1,159 @@
+(function() {
+var inputs = document.getElementsByTagName("input");
+var passwordinputs = [];
+
+function visible(e) {
+ var visible = true;
+ var p = e;
+ while (p && p.tagName.toLowerCase() != "body" && visible) {
+ var style = window.getComputedStyle(p);
+ visible = style.display != "none" && style.visibility != "hidden" &&
+ style.visibility != "collapsed";
+ p = p.parentNode;
+ }
+ return visible;
+}
+
+for (var i = 0; i < inputs.length; i++) {
+ var input = inputs.item(i);
+ if (input.hasAttribute("type")) {
+ var type = input.getAttribute("type").toLowerCase();
+ if (type == "password" && !input.hasAttribute("disabled") &&
+ visible(input))
+ passwordinputs.push(input);
+ }
+}
+
+function getFields(u, p) {
+ var form = u != null ? u.form : p.form;
+ var input = null;
+ if (form == null)
+ return [u,p];
+ for (var i = 0; i < form.elements.length; i++) {
+ var e = form.elements[i];
+ if (e.tagName.toLowerCase() == "input") {
+ if (u != null && u !== e && e.type.toLowerCase() == "password") {
+ p = e;
+ break;
+ }
+ if (e.type.toLowerCase() != "password")
+ input = e;
+ if ((p != null && p == e)) {
+ u = input;
+ break;
+ }
+ }
+ }
+ return [u,p];
+}
+
+var _logins = null;
+var _u = null;
+var _p = null;
+function logins_callback(logins) {
+ var u = getFields(null, passwordinputs[0])[0];
+ if (u)
+ u.setAttribute("autocomplete", "off");
+ if (logins.length == 1) {
+ if (u)
+ u.value = logins[0].Login;
+ passwordinputs[0].value = logins[0].Password;
+ } else if (logins.length > 1) {
+ var usernames = [];
+ for (var i = 0; i < logins.length; i++) {
+ usernames.push(logins[i].Login);
+ }
+ chrome.extension.sendRequest({
+ 'action': 'select_login',
+ 'args': [usernames]
+ });
+ _logins = logins;
+ _u = u;
+ }
+}
+function fillLogin(u, p) {
+ var form = u != null ? u.form : p.form;
+ chrome.extension.sendRequest({
+ 'action': 'get_passwords',
+ 'args': [ document.location.origin, form.action ]
+ }, function(logins) {
+ if (logins.length == 0) {
+ var message = "No logins found";
+ chrome.extension.sendRequest({ action: 'alert', args: [message] });
+ return;
+ }
+ if (logins.length == 1) {
+ if (u)
+ u.value = logins[0].Login;
+ if (p)
+ p.value = logins[0].Password;
+ } else {
+ _u = u;
+ _p = p;
+ _logins = logins;
+ var usernames = [];
+ for (var i = 0; i < logins.length; i++) {
+ usernames.push(logins[i].Login);
+ }
+ chrome.extension.sendRequest({
+ 'action': 'select_login',
+ 'args': [usernames, true]
+ });
+ var message = "More than one login was found in KeePass, " +
+ "press the ChromeIPass icon for more options";
+ chrome.extension.sendRequest({ action: 'alert', args: [message] });
+ }
+ });
+}
+chrome.extension.onRequest.addListener(function onRequest(req) {
+ if ('id' in req) {
+ if (_u)
+ _u.value = _logins[req.id].Login;
+ if (_p)
+ _p.value = _logins[req.id].Password;
+ // wish I could clear out _logins and _u, but a subsequent
+ // selection may be requested.
+ }
+ if ('action' in req) {
+ if (req.action == "fill_user_pass") {
+ var u = document.activeElement;
+ var p = getFields(u, null)[1];
+ if (p == null && u.type.toLowerCase() == "password") {
+ p = u;
+ u = getFields(null, p)[0];
+ }
+ fillLogin(u, p);
+ } else if (req.action == "fill_pass_only") {
+ var p = document.activeElement;
+ if (p.type.toLowerCase() != "password")
+ p = getFields(p, null)[1];
+ if (!p) {
+ var message = "Unable to find a password field";
+ chrome.extension.sendRequest({
+ action: 'alert',
+ args: [message]
+ });
+ return;
+ }
+ fillLogin(null, p);
+ }
+ }
+});
+
+if (passwordinputs.length == 0) {
+ chrome.extension.sendRequest({
+ 'action': 'hide_actions'
+ });
+} else if (passwordinputs.length == 1) {
+ _p = passwordinputs[0];
+ chrome.extension.sendRequest({
+ 'action': 'get_passwords',
+ 'args': [ document.location.origin, passwordinputs[0].form.action ]
+ }, logins_callback);
+} else if (passwordinputs.length > 1) {
+ chrome.extension.sendRequest({
+ 'action': 'select_field'
+ });
+}
+
+})();
View
181 chromeipass/cryptoHelpers.js
@@ -0,0 +1,181 @@
+/*
+ * cryptoHelpers.js: implements AES - Advanced Encryption Standard
+ * from the SlowAES project, http://code.google.com/p/slowaes/
+ *
+ * Copyright (c) 2008 Josh Davis ( http://www.josh-davis.org ),
+ * Mark Percival ( http://mpercival.com ),
+ * Johan Sundstrom ( http://ecmanaut.blogspot.com ),
+ * John Resig ( http://ejohn.org )
+ *
+ * Licensed under the Apache License, Version 2.0
+ * http://www.apache.org/licenses/
+ */
+
+var cryptoHelpers = {
+ // encodes a unicode string to UTF8 (8 bit characters are critical to AES functioning properly)
+ encode_utf8:function(s)
+ {
+ try{return unescape(encodeURIComponent(s));}
+ catch(e){throw 'error during utf8 encoding: cryptoHelpers.encode_utf8.';}
+ },
+
+ // decodes a UTF8 string back to unicode
+ decode_utf8:function(s)
+ {
+ try{return decodeURIComponent(escape(s));}
+ catch(e){throw('error during utf8 decoding: cryptoHelpers.decode_utf8.');}
+ },
+
+ //convert a number array to a hex string
+ toHex:function()
+ {
+ var array = [];
+ if(arguments.length == 1 && arguments[0].constructor == Array)
+ array = arguments[0];
+ else
+ array = arguments;
+ var ret = '';
+ for(var i = 0;i < array.length;i++)
+ ret += (array[i] < 16 ? '0' : '') + array[i].toString(16);
+ return ret.toLowerCase();
+ },
+
+ //convert a hex string to a number array
+ toNumbers:function(s)
+ {
+ var ret = [];
+ s.replace(/(..)/g,function(s){
+ ret.push(parseInt(s,16));
+ });
+ return ret;
+ },
+
+ // get a random number in the range [min,max]
+ getRandom:function(min,max)
+ {
+ if(min === null)
+ min = 0;
+ if(max === null)
+ max = 1;
+ return Math.floor(Math.random()*(max+1)) + min;
+ },
+
+ generateSharedKey:function(len)
+ {
+ if(len === null)
+ len = 16;
+ var key = [];
+ for(var i = 0; i < len*2; i++)
+ key.push(this.getRandom(0,255));
+ return key;
+ },
+
+ generatePrivateKey:function(s,size)
+ {
+ var sha = jsHash.sha2.arr_sha256(s);
+ return sha.slice(0,size);
+ },
+
+ convertStringToByteArray: function(s)
+ {
+ var byteArray = [];
+ for(var i = 0;i < s.length;i++)
+ {
+ byteArray.push(s.charCodeAt(i));
+ }
+ return byteArray;
+ },
+
+ convertByteArrayToString: function(byteArray)
+ {
+ var s = '';
+ for(var i = 0;i < byteArray.length;i++)
+ {
+ s += String.fromCharCode(byteArray[i])
+ }
+ return s;
+ },
+
+ base64: {
+ // Takes a Nx16x1 byte array and converts it to Base64
+ chars: [
+ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
+ 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
+ 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
+ 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
+ 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
+ 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
+ 'w', 'x', 'y', 'z', '0', '1', '2', '3',
+ '4', '5', '6', '7', '8', '9', '+', '/',
+ '=', // for decoding purposes
+ ],
+
+ encode_line: function(flatArr){
+ var b64 = '';
+
+ for (var i = 0; i < flatArr.length; i += 3){
+ b64 += this.chars[flatArr[i] >> 2];
+ b64 += this.chars[((flatArr[i] & 3) << 4) | (flatArr[i + 1] >> 4)];
+ if (!(flatArr[i + 1] == null)){
+ b64 += this.chars[((flatArr[i + 1] & 15) << 2) | (flatArr[i + 2] >> 6)];
+ }else{
+ b64 += '=';
+ }
+ if (!(flatArr[i + 2] == null)){
+ b64 += this.chars[flatArr[i + 2] & 63];
+ }else{
+ b64 += '=';
+ }
+ }
+ return b64;
+ },
+
+ encode: function(flatArr)
+ {
+ var b64 = this.encode_line(flatArr);
+ // OpenSSL is super particular about line breaks
+ var broken_b64 = b64.slice(0, 64) + '\n';
+ for (var i = 1; i < (Math.ceil(b64.length / 64)); i++)
+ {
+ broken_b64 += b64.slice(i * 64, i * 64 + 64) + (Math.ceil(b64.length / 64) == i + 1 ? '': '\n');
+ }
+ return broken_b64;
+ },
+
+ decode: function(string)
+ {
+ string = string.replace(/[\r\n\t ]+/g, '') + '===='; // drop all whitespaces and pad with '=' (end of b64 marker)
+ var flatArr = [];
+ var c = [];
+ var b = [];
+ for (var i = 0; ; i = i + 4){
+ c[0] = this.chars.indexOf(string.charAt(i));
+ if(c[0] == 64){
+ return flatArr;
+ }
+ c[1] = this.chars.indexOf(string.charAt(i + 1));
+ c[2] = this.chars.indexOf(string.charAt(i + 2));
+ c[3] = this.chars.indexOf(string.charAt(i + 3));
+
+ if(
+ (c[0] < 0) || // char1 is wrong
+ (c[1] < 0) || (c[1] == 64) || // char2 is wrong
+ (c[2] < 0) || // char3 is neither an valid char nor '='
+ (c[3] < 0) // char4 is neither an valid char nor '='
+ ){
+ throw 'error during base64 decoding at pos '+i+': cryptoHelpers.base64.decode.';
+ }
+
+ flatArr.push((c[0] << 2) | (c[1] >> 4));
+ if(c[2] >= 0 && c[2] < 64){
+ flatArr.push(((c[1] & 15) << 4) | (c[2] >> 2));
+ if(c[3] >= 0 && c[2] < 64){
+ flatArr.push(((c[2] & 3) << 6) | c[3]);
+ }
+ }
+ }
+ },
+
+ },
+
+};
View
15 chromeipass/field_popup.html
@@ -0,0 +1,15 @@
+<style>
+body {
+ font-family: sans-serif;
+ min-width:357px;
+ overflow-x:hidden;
+ background: #eee;
+}
+</style>
+<div>
+ <p>
+ ChromeIPass found more than one password field on this page. To enter your
+ logins, right-click on one of the password fields, and choose either the
+ "<code>Fill User + Pass</code>" or "<code>Fill Pass Only</code>" command.
+ </p>
+</div>
View
BIN  chromeipass/keepass-big.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN  chromeipass/keepass.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
52 chromeipass/login_popup.html
@@ -0,0 +1,52 @@
+<style>
+body {
+ font-family: sans-serif;
+ min-width:357px;
+ overflow-x:hidden;
+ background: #eee;
+}
+ul { margin-left: 0; margin-right: 0 }
+li {
+ list-style: none;
+ padding-left: 2em;
+ margin-left: 0;
+ margin-right: 2em;
+}
+a {
+ cursor: pointer;
+ display: block;
+ color: #336;
+}
+li:hover {
+ cursor: pointer;
+ background: #ccc;
+}
+</style>
+<div>
+ <p>
+ ChromeIPass found more than one login for this page, select the login
+ information you would like entered into the page.
+ </p>
+ <ul id="login-list"></ul>
+</div>
+<script>
+ var global = chrome.extension.getBackgroundPage();
+
+ chrome.tabs.getSelected(null, function(tab) {
+ var logins = global.tab_login_list["tab" + tab.id];
+ var ul = document.getElementById("login-list");
+ for (var i = 0; i < logins.length; i++) {
+ var li = document.createElement("li");
+ var a = document.createElement("a");
+ a.textContent = logins[i];
+ li.appendChild(a);
+ a.setAttribute("id", "" + i);
+ a.addEventListener('click', function(e) {
+ var id = e.target.id;
+ chrome.tabs.sendRequest(tab.id, { id: id });
+ close();
+ });
+ ul.appendChild(li);
+ }
+ });
+</script>
View
25 chromeipass/manifest.json
@@ -0,0 +1,25 @@
+{
+ "name": "ChromeIPass",
+ "version": "0.9.9",
+ "description": "Chrome and KeePass integration using KeePassHttp",
+ "icons": {
+ "16": "keepass.png",
+ "48": "keepass-big.png"
+ },
+ "page_action": {
+ "default_icon": "keepass.png",
+ "popup": "popup.html"
+ },
+ "background_page": "background.html",
+ "content_scripts": [
+ {
+ "matches": ["http://*/*", "https://*/*"],
+ "js": ["chromeipass.js"],
+ "run_at": "document_idle",
+ "all_frames": true
+ }
+ ],
+ "permissions": [
+ "contextMenus", "tabs", "http://localhost/"
+ ]
+}
View
123 chromeipass/popup.html
@@ -0,0 +1,123 @@
+<style>
+body {
+ font-family: sans-serif;
+ min-width: 357px;
+ overflow-x: hidden;
+ background: #eee;
+}
+
+</style>
+
+<div id="initial-state">
+ <p><img style="margin-right: 1em" src="throbber.gif"/> Checking status...</p>
+</div>
+
+<div id="not-configured" style="display: none">
+<p>
+ChromeIPass has not been configured. Press the connect button to register
+and pair with KeePassHttp
+</p>
+<div style="text-align: right">
+<button id="connect-button">Connect</button>
+</div>
+<script>
+ var b = document.getElementById("connect-button");
+ b.addEventListener("click", function() {
+ chrome.extension.sendRequest({ action: "associate" });
+ close();
+ }, false);
+</script>
+</div>
+
+<div id="need-reconfigure" style="display: none">
+<p>
+ChromeIPass has been disconnected from KeePassHttp.
+</p>
+<code id="need-reconfigure-message"></code>
+<p>
+Press the reconnect
+button to establish a new connection.
+</p>
+<div style="text-align: right">
+<button id="reconnect-button">Reconnect</button>
+</div>
+<script>
+ var b = document.getElementById("reconnect-button");
+ b.addEventListener("click", function() {
+ chrome.extension.sendRequest({ action: "associate" });
+ close();
+ }, false);
+</script>
+</div>
+
+<div id="configured-not-associated" style="display: none">
+ <p>
+ ChromeIPass has been configured using the keyname
+ <em id="unassociated-keyname"></em> and has not yet
+ connected to KeePassHttp
+ </p>
+</div>
+
+<div id="configured-and-associated" style="display: none">
+ <p>
+ ChromeIPass has been configured using the keyname
+ "<em id="associated-keyname"></em>" and is successfully
+ connected to KeePassHttp
+ </p>
+</div>
+
+<div id="error-encountered" style="display: none">
+ <p>
+ ChromeIPass has encountered an error:
+ </p>
+ <p>
+ <code style="margin-left: 1em" id="error-message"></code>
+ </p>
+<div style="text-align: right">
+<button id="clear-button">Clear</button>
+</div>
+<script>
+ var b = document.getElementById("clear-button");
+ b.addEventListener("click", function() {
+ last_response.error = null;
+ status_response(last_response);
+ }, false);
+</script>
+</div>
+
+<script>
+ function $(id) {
+ return document.getElementById(id);
+ }
+ var last_response = null;
+ function status_response(response) {
+ last_response = response;
+ var error = response.error;
+ var configured = response.configured;
+ var keyname = response.keyname;
+ var associated = response.associated;
+ $('initial-state').style.display = "none";
+ $('error-encountered').style.display = "none";
+ $('need-reconfigure').style.display = "none";
+ $('not-configured').style.display = "none";
+ $('configured-and-associated').style.display = "none";
+ $('configured-not-associated').style.display = "none";
+ console.log("error is: "+ error);
+ if (error && !configured) {
+ $('need-reconfigure').style.display = "block";
+ $('need-reconfigure-message').textContent = error;
+ } else if (error) {
+ $('error-encountered').style.display = "block";
+ $('error-message').textContent = error;
+ } else if (!configured) {
+ $('not-configured').style.display = "block";
+ } else if (keyname && !associated) {
+ $('unassociated-keyname').textContent = keyname;
+ $('configured-not-associated').style.display = "block";
+ } else if (keyname && associated) {
+ $('associated-keyname').textContent = keyname;
+ $('configured-and-associated').style.display = "block";
+ }
+ }
+ chrome.extension.sendRequest({ action: "get_status" }, status_response);
+</script>
View
BIN  chromeipass/throbber.gif
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Please sign in to comment.
Something went wrong with that request. Please try again.