diff options
Diffstat (limited to 'flash-src/third-party')
109 files changed, 21934 insertions, 0 deletions
diff --git a/flash-src/third-party/com/adobe/net/proxies/RFC2817Socket.as b/flash-src/third-party/com/adobe/net/proxies/RFC2817Socket.as new file mode 100644 index 0000000..c52ee39 --- /dev/null +++ b/flash-src/third-party/com/adobe/net/proxies/RFC2817Socket.as @@ -0,0 +1,204 @@ +/* + Adobe Systems Incorporated(r) Source Code License Agreement + Copyright(c) 2005 Adobe Systems Incorporated. All rights reserved. + + Please read this Source Code License Agreement carefully before using + the source code. + + Adobe Systems Incorporated grants to you a perpetual, worldwide, non-exclusive, + no-charge, royalty-free, irrevocable copyright license, to reproduce, + prepare derivative works of, publicly display, publicly perform, and + distribute this source code and such derivative works in source or + object code form without any attribution requirements. + + The name "Adobe Systems Incorporated" must not be used to endorse or promote products + derived from the source code without prior written permission. + + You agree to indemnify, hold harmless and defend Adobe Systems Incorporated from and + against any loss, damage, claims or lawsuits, including attorney's + fees that arise or result from your use or distribution of the source + code. + + THIS SOURCE CODE IS PROVIDED "AS IS" AND "WITH ALL FAULTS", WITHOUT + ANY TECHNICAL SUPPORT OR ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, + BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ALSO, THERE IS NO WARRANTY OF + NON-INFRINGEMENT, TITLE OR QUIET ENJOYMENT. IN NO EVENT SHALL MACROMEDIA + OR ITS SUPPLIERS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOURCE CODE, EVEN IF + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +package com.adobe.net.proxies +{ + import flash.events.Event; + import flash.events.IOErrorEvent; + import flash.events.ProgressEvent; + import flash.net.Socket; + + /** + * This class allows TCP socket connections through HTTP proxies in accordance with + * RFC 2817: + * + * ftp://ftp.rfc-editor.org/in-notes/rfc2817.txt + * + * It can also be used to make direct connections to a destination, as well. If you + * pass the host and port into the constructor, no proxy will be used. You can also + * call connect, passing in the host and the port, and if you didn't set the proxy + * info, a direct connection will be made. A proxy is only used after you have called + * the setProxyInfo function. + * + * The connection to and negotiation with the proxy is completely hidden. All the + * same events are thrown whether you are using a proxy or not, and the data you + * receive from the target server will look exact as it would if you were connected + * to it directly rather than through a proxy. + * + * @author Christian Cantrell + * + **/ + public class RFC2817Socket + extends Socket + { + private var proxyHost:String = null; + private var host:String = null; + private var proxyPort:int = 0; + private var port:int = 0; + private var deferredEventHandlers:Object = new Object(); + private var buffer:String = new String(); + + /** + * Construct a new RFC2817Socket object. If you pass in the host and the port, + * no proxy will be used. If you want to use a proxy, instantiate with no + * arguments, call setProxyInfo, then call connect. + **/ + public function RFC2817Socket(host:String = null, port:int = 0) + { + if (host != null && port != 0) + { + super(host, port); + } + } + + /** + * Set the proxy host and port number. Your connection will only proxied if + * this function has been called. + **/ + public function setProxyInfo(host:String, port:int):void + { + this.proxyHost = host; + this.proxyPort = port; + + var deferredSocketDataHandler:Object = this.deferredEventHandlers[ProgressEvent.SOCKET_DATA]; + var deferredConnectHandler:Object = this.deferredEventHandlers[Event.CONNECT]; + + if (deferredSocketDataHandler != null) + { + super.removeEventListener(ProgressEvent.SOCKET_DATA, deferredSocketDataHandler.listener, deferredSocketDataHandler.useCapture); + } + + if (deferredConnectHandler != null) + { + super.removeEventListener(Event.CONNECT, deferredConnectHandler.listener, deferredConnectHandler.useCapture); + } + } + + /** + * Connect to the specified host over the specified port. If you want your + * connection proxied, call the setProxyInfo function first. + **/ + public override function connect(host:String, port:int):void + { + if (this.proxyHost == null) + { + this.redirectConnectEvent(); + this.redirectSocketDataEvent(); + super.connect(host, port); + } + else + { + this.host = host; + this.port = port; + super.addEventListener(Event.CONNECT, this.onConnect); + super.addEventListener(ProgressEvent.SOCKET_DATA, this.onSocketData); + super.connect(this.proxyHost, this.proxyPort); + } + } + + private function onConnect(event:Event):void + { + this.writeUTFBytes("CONNECT "+this.host+":"+this.port+" HTTP/1.1\n\n"); + this.flush(); + this.redirectConnectEvent(); + } + + private function onSocketData(event:ProgressEvent):void + { + while (this.bytesAvailable != 0) + { + this.buffer += this.readUTFBytes(1); + if (this.buffer.search(/\r?\n\r?\n$/) != -1) + { + this.checkResponse(event); + break; + } + } + } + + private function checkResponse(event:ProgressEvent):void + { + var responseCode:String = this.buffer.substr(this.buffer.indexOf(" ")+1, 3); + + if (responseCode.search(/^2/) == -1) + { + var ioError:IOErrorEvent = new IOErrorEvent(IOErrorEvent.IO_ERROR); + ioError.text = "Error connecting to the proxy ["+this.proxyHost+"] on port ["+this.proxyPort+"]: " + this.buffer; + this.dispatchEvent(ioError); + } + else + { + this.redirectSocketDataEvent(); + this.dispatchEvent(new Event(Event.CONNECT)); + if (this.bytesAvailable > 0) + { + this.dispatchEvent(event); + } + } + this.buffer = null; + } + + private function redirectConnectEvent():void + { + super.removeEventListener(Event.CONNECT, onConnect); + var deferredEventHandler:Object = this.deferredEventHandlers[Event.CONNECT]; + if (deferredEventHandler != null) + { + super.addEventListener(Event.CONNECT, deferredEventHandler.listener, deferredEventHandler.useCapture, deferredEventHandler.priority, deferredEventHandler.useWeakReference); + } + } + + private function redirectSocketDataEvent():void + { + super.removeEventListener(ProgressEvent.SOCKET_DATA, onSocketData); + var deferredEventHandler:Object = this.deferredEventHandlers[ProgressEvent.SOCKET_DATA]; + if (deferredEventHandler != null) + { + super.addEventListener(ProgressEvent.SOCKET_DATA, deferredEventHandler.listener, deferredEventHandler.useCapture, deferredEventHandler.priority, deferredEventHandler.useWeakReference); + } + } + + public override function addEventListener(type:String, listener:Function, useCapture:Boolean = false, priority:int=0.0, useWeakReference:Boolean=false):void + { + if (type == Event.CONNECT || type == ProgressEvent.SOCKET_DATA) + { + this.deferredEventHandlers[type] = {listener:listener,useCapture:useCapture, priority:priority, useWeakReference:useWeakReference}; + } + else + { + super.addEventListener(type, listener, useCapture, priority, useWeakReference); + } + } + } +}
\ No newline at end of file diff --git a/flash-src/third-party/com/gsolo/encryption/MD5.as b/flash-src/third-party/com/gsolo/encryption/MD5.as new file mode 100644 index 0000000..e5d9c4a --- /dev/null +++ b/flash-src/third-party/com/gsolo/encryption/MD5.as @@ -0,0 +1,375 @@ +package com.gsolo.encryption {
+ public class MD5 {
+ /*
+ * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message
+ * Digest Algorithm, as defined in RFC 1321.
+ * Version 2.2-alpha Copyright (C) Paul Johnston 1999 - 2005
+ * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
+ * Distributed under the BSD License
+ * See http://pajhome.org.uk/crypt/md5 for more info.
+ *
+ * Converted to AS3 By Geoffrey Williams
+ */
+
+ /*
+ * Configurable variables. You may need to tweak these to be compatible with
+ * the server-side, but the defaults work in most cases.
+ */
+
+ public static const HEX_FORMAT_LOWERCASE:uint = 0;
+ public static const HEX_FORMAT_UPPERCASE:uint = 1;
+
+ public static const BASE64_PAD_CHARACTER_DEFAULT_COMPLIANCE:String = "";
+ public static const BASE64_PAD_CHARACTER_RFC_COMPLIANCE:String = "=";
+
+ public static var hexcase:uint = 0; /* hex output format. 0 - lowercase; 1 - uppercase */
+ public static var b64pad:String = ""; /* base-64 pad character. "=" for strict RFC compliance */
+
+ public static function encrypt (string:String):String {
+ return hex_md5 (string);
+ }
+
+ /*
+ * These are the functions you'll usually want to call
+ * They take string arguments and return either hex or base-64 encoded strings
+ */
+ public static function hex_md5 (string:String):String {
+ return rstr2hex (rstr_md5 (str2rstr_utf8 (string)));
+ }
+
+ public static function b64_md5 (string:String):String {
+ return rstr2b64 (rstr_md5 (str2rstr_utf8 (string)));
+ }
+
+ public static function any_md5 (string:String, encoding:String):String {
+ return rstr2any (rstr_md5 (str2rstr_utf8 (string)), encoding);
+ }
+ public static function hex_hmac_md5 (key:String, data:String):String {
+ return rstr2hex (rstr_hmac_md5 (str2rstr_utf8 (key), str2rstr_utf8 (data)));
+ }
+ public static function b64_hmac_md5 (key:String, data:String):String {
+ return rstr2b64 (rstr_hmac_md5 (str2rstr_utf8 (key), str2rstr_utf8 (data)));
+ }
+ public static function any_hmac_md5 (key:String, data:String, encoding:String):String {
+ return rstr2any(rstr_hmac_md5(str2rstr_utf8(key), str2rstr_utf8(data)), encoding);
+ }
+
+ /*
+ * Perform a simple self-test to see if the VM is working
+ */
+ public static function md5_vm_test ():Boolean {
+ return hex_md5 ("abc") == "900150983cd24fb0d6963f7d28e17f72";
+ }
+
+ /*
+ * Calculate the MD5 of a raw string
+ */
+ public static function rstr_md5 (string:String):String {
+ return binl2rstr (binl_md5 (rstr2binl (string), string.length * 8));
+ }
+
+ /*
+ * Calculate the HMAC-MD5, of a key and some data (raw strings)
+ */
+ public static function rstr_hmac_md5 (key:String, data:String):String {
+ var bkey:Array = rstr2binl (key);
+ if (bkey.length > 16) bkey = binl_md5 (bkey, key.length * 8);
+
+ var ipad:Array = new Array(16), opad:Array = new Array(16);
+ for(var i:Number = 0; i < 16; i++) {
+ ipad[i] = bkey[i] ^ 0x36363636;
+ opad[i] = bkey[i] ^ 0x5C5C5C5C;
+ }
+
+ var hash:Array = binl_md5 (ipad.concat (rstr2binl (data)), 512 + data.length * 8);
+ return binl2rstr (binl_md5 (opad.concat (hash), 512 + 128));
+ }
+
+ /*
+ * Convert a raw string to a hex string
+ */
+ public static function rstr2hex (input:String):String {
+ var hex_tab:String = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
+ var output:String = "";
+ var x:Number;
+ for(var i:Number = 0; i < input.length; i++) {
+ x = input.charCodeAt(i);
+ output += hex_tab.charAt((x >>> 4) & 0x0F)
+ + hex_tab.charAt( x & 0x0F);
+ }
+ return output;
+ }
+
+ /*
+ * Convert a raw string to a base-64 string
+ */
+ public static function rstr2b64 (input:String):String {
+ var tab:String = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+ var output:String = "";
+ var len:Number = input.length;
+ for(var i:Number = 0; i < len; i += 3) {
+ var triplet:Number = (input.charCodeAt(i) << 16)
+ | (i + 1 < len ? input.charCodeAt(i+1) << 8 : 0)
+ | (i + 2 < len ? input.charCodeAt(i+2) : 0);
+ for(var j:Number = 0; j < 4; j++) {
+ if(i * 8 + j * 6 > input.length * 8) output += b64pad;
+ else output += tab.charAt((triplet >>> 6*(3-j)) & 0x3F);
+ }
+ }
+ return output;
+ }
+
+ /*
+ * Convert a raw string to an arbitrary string encoding
+ */
+ public static function rstr2any(input:String, encoding:String):String {
+ var divisor:Number = encoding.length;
+ var remainders:Array = [];
+ var i:Number, q:Number, x:Number, quotient:Array;
+
+ /* Convert to an array of 16-bit big-endian values, forming the dividend */
+ var dividend:Array = new Array(input.length / 2);
+ for(i = 0; i < dividend.length; i++) {
+ dividend[i] = (input.charCodeAt(i * 2) << 8) | input.charCodeAt(i * 2 + 1);
+ }
+
+ /*
+ * Repeatedly perform a long division. The binary array forms the dividend,
+ * the length of the encoding is the divisor. Once computed, the quotient
+ * forms the dividend for the next step. We stop when the dividend is zero.
+ * All remainders are stored for later use.
+ */
+ while(dividend.length > 0) {
+ quotient = [];
+ x = 0;
+ for(i = 0; i < dividend.length; i++) {
+ x = (x << 16) + dividend[i];
+ q = Math.floor(x / divisor);
+ x -= q * divisor;
+ if(quotient.length > 0 || q > 0)
+ quotient[quotient.length] = q;
+ }
+ remainders[remainders.length] = x;
+ dividend = quotient;
+ }
+
+ /* Convert the remainders to the output string */
+ var output:String = "";
+ for(i = remainders.length - 1; i >= 0; i--)
+ output += encoding.charAt (remainders[i]);
+
+ return output;
+ }
+
+ /*
+ * Encode a string as utf-8.
+ * For efficiency, this assumes the input is valid utf-16.
+ */
+ public static function str2rstr_utf8 (input:String):String {
+ var output:String = "";
+ var i:Number = -1;
+ var x:Number, y:Number;
+
+ while(++i < input.length) {
+ /* Decode utf-16 surrogate pairs */
+ x = input.charCodeAt(i);
+ y = i + 1 < input.length ? input.charCodeAt(i + 1) : 0;
+ if(0xD800 <= x && x <= 0xDBFF && 0xDC00 <= y && y <= 0xDFFF) {
+ x = 0x10000 + ((x & 0x03FF) << 10) + (y & 0x03FF);
+ i++;
+ }
+
+ /* Encode output as utf-8 */
+ if(x <= 0x7F)
+ output += String.fromCharCode(x);
+ else if(x <= 0x7FF)
+ output += String.fromCharCode(0xC0 | ((x >>> 6 ) & 0x1F),
+ 0x80 | ( x & 0x3F));
+ else if(x <= 0xFFFF)
+ output += String.fromCharCode(0xE0 | ((x >>> 12) & 0x0F),
+ 0x80 | ((x >>> 6 ) & 0x3F),
+ 0x80 | ( x & 0x3F));
+ else if(x <= 0x1FFFFF)
+ output += String.fromCharCode(0xF0 | ((x >>> 18) & 0x07),
+ 0x80 | ((x >>> 12) & 0x3F),
+ 0x80 | ((x >>> 6 ) & 0x3F),
+ 0x80 | ( x & 0x3F));
+ }
+ return output;
+ }
+
+ /*
+ * Encode a string as utf-16
+ */
+ public static function str2rstr_utf16le (input:String):String {
+ var output:String = "";
+ for(var i:Number = 0; i < input.length; i++)
+ output += String.fromCharCode( input.charCodeAt(i) & 0xFF,
+ (input.charCodeAt(i) >>> 8) & 0xFF);
+ return output;
+ }
+
+ public static function str2rstr_utf16be (input:String):String {
+ var output:String = "";
+ for(var i:Number = 0; i < input.length; i++)
+ output += String.fromCharCode((input.charCodeAt(i) >>> 8) & 0xFF,
+ input.charCodeAt(i) & 0xFF);
+ return output;
+ }
+
+ /*
+ * Convert a raw string to an array of little-endian words
+ * Characters >255 have their high-byte silently ignored.
+ */
+ public static function rstr2binl (input:String):Array {
+ var output:Array = new Array(input.length >> 2);
+ for(var i:Number = 0; i < output.length; i++)
+ output[i] = 0;
+ for(i = 0; i < input.length * 8; i += 8)
+ output[i>>5] |= (input.charCodeAt(i / 8) & 0xFF) << (i%32);
+ return output;
+ }
+
+ /*
+ * Convert an array of little-endian words to a string
+ */
+ public static function binl2rstr (input:Array):String {
+ var output:String = "";
+ for(var i:Number = 0; i < input.length * 32; i += 8)
+ output += String.fromCharCode((input[i>>5] >>> (i % 32)) & 0xFF);
+ return output;
+ }
+
+ /*
+ * Calculate the MD5 of an array of little-endian words, and a bit length.
+ */
+ public static function binl_md5 (x:Array, len:Number):Array {
+ /* append padding */
+ x[len >> 5] |= 0x80 << ((len) % 32);
+ x[(((len + 64) >>> 9) << 4) + 14] = len;
+
+ var a:Number = 1732584193;
+ var b:Number = -271733879;
+ var c:Number = -1732584194;
+ var d:Number = 271733878;
+
+ for(var i:Number = 0; i < x.length; i += 16) {
+ var olda:Number = a;
+ var oldb:Number = b;
+ var oldc:Number = c;
+ var oldd:Number = d;
+
+ a = md5_ff(a, b, c, d, x[i+ 0], 7 , -680876936);
+ d = md5_ff(d, a, b, c, x[i+ 1], 12, -389564586);
+ c = md5_ff(c, d, a, b, x[i+ 2], 17, 606105819);
+ b = md5_ff(b, c, d, a, x[i+ 3], 22, -1044525330);
+ a = md5_ff(a, b, c, d, x[i+ 4], 7 , -176418897);
+ d = md5_ff(d, a, b, c, x[i+ 5], 12, 1200080426);
+ c = md5_ff(c, d, a, b, x[i+ 6], 17, -1473231341);
+ b = md5_ff(b, c, d, a, x[i+ 7], 22, -45705983);
+ a = md5_ff(a, b, c, d, x[i+ 8], 7 , 1770035416);
+ d = md5_ff(d, a, b, c, x[i+ 9], 12, -1958414417);
+ c = md5_ff(c, d, a, b, x[i+10], 17, -42063);
+ b = md5_ff(b, c, d, a, x[i+11], 22, -1990404162);
+ a = md5_ff(a, b, c, d, x[i+12], 7 , 1804603682);
+ d = md5_ff(d, a, b, c, x[i+13], 12, -40341101);
+ c = md5_ff(c, d, a, b, x[i+14], 17, -1502002290);
+ b = md5_ff(b, c, d, a, x[i+15], 22, 1236535329);
+
+ a = md5_gg(a, b, c, d, x[i+ 1], 5 , -165796510);
+ d = md5_gg(d, a, b, c, x[i+ 6], 9 , -1069501632);
+ c = md5_gg(c, d, a, b, x[i+11], 14, 643717713);
+ b = md5_gg(b, c, d, a, x[i+ 0], 20, -373897302);
+ a = md5_gg(a, b, c, d, x[i+ 5], 5 , -701558691);
+ d = md5_gg(d, a, b, c, x[i+10], 9 , 38016083);
+ c = md5_gg(c, d, a, b, x[i+15], 14, -660478335);
+ b = md5_gg(b, c, d, a, x[i+ 4], 20, -405537848);
+ a = md5_gg(a, b, c, d, x[i+ 9], 5 , 568446438);
+ d = md5_gg(d, a, b, c, x[i+14], 9 , -1019803690);
+ c = md5_gg(c, d, a, b, x[i+ 3], 14, -187363961);
+ b = md5_gg(b, c, d, a, x[i+ 8], 20, 1163531501);
+ a = md5_gg(a, b, c, d, x[i+13], 5 , -1444681467);
+ d = md5_gg(d, a, b, c, x[i+ 2], 9 , -51403784);
+ c = md5_gg(c, d, a, b, x[i+ 7], 14, 1735328473);
+ b = md5_gg(b, c, d, a, x[i+12], 20, -1926607734);
+
+ a = md5_hh(a, b, c, d, x[i+ 5], 4 , -378558);
+ d = md5_hh(d, a, b, c, x[i+ 8], 11, -2022574463);
+ c = md5_hh(c, d, a, b, x[i+11], 16, 1839030562);
+ b = md5_hh(b, c, d, a, x[i+14], 23, -35309556);
+ a = md5_hh(a, b, c, d, x[i+ 1], 4 , -1530992060);
+ d = md5_hh(d, a, b, c, x[i+ 4], 11, 1272893353);
+ c = md5_hh(c, d, a, b, x[i+ 7], 16, -155497632);
+ b = md5_hh(b, c, d, a, x[i+10], 23, -1094730640);
+ a = md5_hh(a, b, c, d, x[i+13], 4 , 681279174);
+ d = md5_hh(d, a, b, c, x[i+ 0], 11, -358537222);
+ c = md5_hh(c, d, a, b, x[i+ 3], 16, -722521979);
+ b = md5_hh(b, c, d, a, x[i+ 6], 23, 76029189);
+ a = md5_hh(a, b, c, d, x[i+ 9], 4 , -640364487);
+ d = md5_hh(d, a, b, c, x[i+12], 11, -421815835);
+ c = md5_hh(c, d, a, b, x[i+15], 16, 530742520);
+ b = md5_hh(b, c, d, a, x[i+ 2], 23, -995338651);
+
+ a = md5_ii(a, b, c, d, x[i+ 0], 6 , -198630844);
+ d = md5_ii(d, a, b, c, x[i+ 7], 10, 1126891415);
+ c = md5_ii(c, d, a, b, x[i+14], 15, -1416354905);
+ b = md5_ii(b, c, d, a, x[i+ 5], 21, -57434055);
+ a = md5_ii(a, b, c, d, x[i+12], 6 , 1700485571);
+ d = md5_ii(d, a, b, c, x[i+ 3], 10, -1894986606);
+ c = md5_ii(c, d, a, b, x[i+10], 15, -1051523);
+ b = md5_ii(b, c, d, a, x[i+ 1], 21, -2054922799);
+ a = md5_ii(a, b, c, d, x[i+ 8], 6 , 1873313359);
+ d = md5_ii(d, a, b, c, x[i+15], 10, -30611744);
+ c = md5_ii(c, d, a, b, x[i+ 6], 15, -1560198380);
+ b = md5_ii(b, c, d, a, x[i+13], 21, 1309151649);
+ a = md5_ii(a, b, c, d, x[i+ 4], 6 , -145523070);
+ d = md5_ii(d, a, b, c, x[i+11], 10, -1120210379);
+ c = md5_ii(c, d, a, b, x[i+ 2], 15, 718787259);
+ b = md5_ii(b, c, d, a, x[i+ 9], 21, -343485551);
+
+ a = safe_add(a, olda);
+ b = safe_add(b, oldb);
+ c = safe_add(c, oldc);
+ d = safe_add(d, oldd);
+ }
+ return [a, b, c, d];
+ }
+
+ /*
+ * These functions implement the four basic operations the algorithm uses.
+ */
+ public static function md5_cmn (q:Number, a:Number, b:Number, x:Number, s:Number, t:Number):Number {
+ return safe_add (bit_rol (safe_add (safe_add (a, q), safe_add(x, t)), s), b);
+ }
+ public static function md5_ff (a:Number, b:Number, c:Number, d:Number, x:Number, s:Number, t:Number):Number {
+ return md5_cmn ((b & c) | ((~b) & d), a, b, x, s, t);
+ }
+ public static function md5_gg (a:Number, b:Number, c:Number, d:Number, x:Number, s:Number, t:Number):Number {
+ return md5_cmn ((b & d) | (c & (~d)), a, b, x, s, t);
+ }
+ public static function md5_hh (a:Number, b:Number, c:Number, d:Number, x:Number, s:Number, t:Number):Number {
+ return md5_cmn (b ^ c ^ d, a, b, x, s, t);
+ }
+ public static function md5_ii (a:Number, b:Number, c:Number, d:Number, x:Number, s:Number, t:Number):Number {
+ return md5_cmn (c ^ (b | (~d)), a, b, x, s, t);
+ }
+
+ /*
+ * Add integers, wrapping at 2^32. This uses 16-bit operations internally
+ * to work around bugs in some JS interpreters.
+ */
+ public static function safe_add (x:Number, y:Number):Number {
+ var lsw:Number = (x & 0xFFFF) + (y & 0xFFFF);
+ var msw:Number = (x >> 16) + (y >> 16) + (lsw >> 16);
+ return (msw << 16) | (lsw & 0xFFFF);
+ }
+
+ /*
+ * Bitwise rotate a 32-bit number to the left.
+ */
+ public static function bit_rol (num:Number, cnt:Number):Number {
+ return (num << cnt) | (num >>> (32 - cnt));
+ }
+
+ }
+}
diff --git a/flash-src/third-party/com/hurlant/crypto/Crypto.as b/flash-src/third-party/com/hurlant/crypto/Crypto.as new file mode 100644 index 0000000..32ec97a --- /dev/null +++ b/flash-src/third-party/com/hurlant/crypto/Crypto.as @@ -0,0 +1,287 @@ +/**
+ * Crypto
+ *
+ * An abstraction layer to instanciate our crypto algorithms
+ * Copyright (c) 2007 Henri Torgemane
+ *
+ * See LICENSE.txt for full license information.
+ */
+package com.hurlant.crypto
+{
+ import com.hurlant.crypto.hash.HMAC;
+ import com.hurlant.crypto.hash.MAC;
+ import com.hurlant.crypto.hash.IHash;
+ import com.hurlant.crypto.hash.MD2;
+ import com.hurlant.crypto.hash.MD5;
+ import com.hurlant.crypto.hash.SHA1;
+ import com.hurlant.crypto.hash.SHA224;
+ import com.hurlant.crypto.hash.SHA256;
+ import com.hurlant.crypto.prng.ARC4;
+ import com.hurlant.crypto.rsa.RSAKey;
+ import com.hurlant.crypto.symmetric.AESKey;
+ import com.hurlant.crypto.symmetric.BlowFishKey;
+ import com.hurlant.crypto.symmetric.CBCMode;
+ import com.hurlant.crypto.symmetric.CFB8Mode;
+ import com.hurlant.crypto.symmetric.CFBMode;
+ import com.hurlant.crypto.symmetric.CTRMode;
+ import com.hurlant.crypto.symmetric.DESKey;
+ import com.hurlant.crypto.symmetric.ECBMode;
+ import com.hurlant.crypto.symmetric.ICipher;
+ import com.hurlant.crypto.symmetric.IMode;
+ import com.hurlant.crypto.symmetric.IPad;
+ import com.hurlant.crypto.symmetric.ISymmetricKey;
+ import com.hurlant.crypto.symmetric.IVMode;
+ import com.hurlant.crypto.symmetric.NullPad;
+ import com.hurlant.crypto.symmetric.OFBMode;
+ import com.hurlant.crypto.symmetric.PKCS5;
+ import com.hurlant.crypto.symmetric.SimpleIVMode;
+ import com.hurlant.crypto.symmetric.TripleDESKey;
+ import com.hurlant.crypto.symmetric.XTeaKey;
+ import com.hurlant.util.Base64;
+
+ import flash.utils.ByteArray;
+
+ /**
+ * A class to make it easy to use the rest of the framework.
+ * As a side-effect, using this class will cause most of the framework
+ * to be linked into your application, which is not always what you want.
+ *
+ * If you want to optimize your download size, don't use this class.
+ * (But feel free to read it to get ideas on how to get the algorithm you want.)
+ */
+ public class Crypto
+ {
+ private var b64:Base64; // we don't use it, but we want the swc to include it, so cheap trick.
+
+ public function Crypto(){
+ }
+
+ /**
+ * Things that should work, among others:
+ * "aes"
+ * "aes-128-ecb"
+ * "aes-128-cbc"
+ * "aes-128-cfb"
+ * "aes-128-cfb8"
+ * "aes-128-ofb"
+ * "aes-192-cfb"
+ * "aes-256-ofb"
+ * "blowfish-cbc"
+ * "des-ecb"
+ * "xtea"
+ * "xtea-ecb"
+ * "xtea-cbc"
+ * "xtea-cfb"
+ * "xtea-cfb8"
+ * "xtea-ofb"
+ * "rc4"
+ * "simple-aes-cbc"
+ */
+ public static function getCipher(name:String, key:ByteArray, pad:IPad=null):ICipher {
+ // split name into an array.
+ var keys:Array = name.split("-");
+ switch (keys[0]) {
+ /**
+ * "simple" is a special case. It means:
+ * "If using an IV mode, prepend the IV to the ciphertext"
+ */
+ case "simple":
+ keys.shift();
+ name = keys.join("-");
+ var cipher:ICipher = getCipher(name, key, pad);
+ if (cipher is IVMode) {
+ return new SimpleIVMode(cipher as IVMode);
+ } else {
+ return cipher;
+ }
+ /**
+ * we support both "aes-128" and "aes128"
+ * Technically, you could use "aes192-128", but you'd
+ * only be hurting yourself.
+ */
+ case "aes":
+ case "aes128":
+ case "aes192":
+ case "aes256":
+ keys.shift();
+ if (key.length*8==keys[0]) {
+ // support for "aes-128-..." and such.
+ keys.shift();
+ }
+ return getMode(keys[0], new AESKey(key), pad);
+ break;
+ case "bf":
+ case "blowfish":
+ keys.shift();
+ return getMode(keys[0], new BlowFishKey(key), pad);
+ /**
+ * des-ede and des-ede3 are both equivalent to des3.
+ * the choice between 2tdes and 3tdes is made based
+ * on the length of the key provided.
+ */
+ case "des":
+ keys.shift();
+ if (keys[0]!="ede" && keys[0]!="ede3") {
+ return getMode(keys[0], new DESKey(key), pad);
+ }
+ if (keys.length==1) {
+ keys.push("ecb"); // default mode for 2tdes and 3tdes with openssl enc
+ }
+ // fall-through to triple des
+ case "3des":
+ case "des3":
+ keys.shift();
+ return getMode(keys[0], new TripleDESKey(key), pad);
+ case "xtea":
+ keys.shift();
+ return getMode(keys[0], new XTeaKey(key), pad);
+ break;
+ /**
+ * Technically, you could say "rc4-128" or whatever,
+ * but really, the length of the key is what counts here.
+ */
+ case "rc4":
+ keys.shift();
+ return new ARC4(key);
+ break;
+ }
+ return null;
+ }
+
+ /**
+ * Returns the size of a key for a given cipher identifier.
+ */
+ public static function getKeySize(name:String):uint {
+ var keys:Array = name.split("-");
+ switch (keys[0]) {
+ case "simple":
+ keys.shift();
+ return getKeySize(keys.join("-"));
+ case "aes128":
+ return 16;
+ case "aes192":
+ return 24;
+ case "aes256":
+ return 32;
+ case "aes":
+ keys.shift();
+ return parseInt(keys[0])/8;
+ case "bf":
+ case "blowfish":
+ return 16;
+ case "des":
+ keys.shift();
+ switch (keys[0]) {
+ case "ede":
+ return 16;
+ case "ede3":
+ return 24;
+ default:
+ return 8;
+ }
+ case "3des":
+ case "des3":
+ return 24;
+ case "xtea":
+ return 8;
+ case "rc4":
+ if (parseInt(keys[1])>0) {
+ return parseInt(keys[1])/8;
+ }
+ return 16; // why not.
+ }
+ return 0; // unknown;
+ }
+
+ private static function getMode(name:String, alg:ISymmetricKey, padding:IPad=null):IMode {
+ switch (name) {
+ case "ecb":
+ return new ECBMode(alg, padding);
+ case "cfb":
+ return new CFBMode(alg, padding);
+ case "cfb8":
+ return new CFB8Mode(alg, padding);
+ case "ofb":
+ return new OFBMode(alg, padding);
+ case "ctr":
+ return new CTRMode(alg, padding);
+ case "cbc":
+ default:
+ return new CBCMode(alg, padding);
+ }
+ }
+
+ /**
+ * Things that should work:
+ * "md5"
+ * "sha"
+ * "sha1"
+ * "sha224"
+ * "sha256"
+ */
+ public static function getHash(name:String):IHash {
+ switch(name) {
+ case "md2":
+ return new MD2;
+ case "md5":
+ return new MD5;
+ case "sha": // let's hope you didn't mean sha-0
+ case "sha1":
+ return new SHA1;
+ case "sha224":
+ return new SHA224;
+ case "sha256":
+ return new SHA256;
+ }
+ return null;
+ }
+
+ /**
+ * Things that should work:
+ * "sha1"
+ * "md5-64"
+ * "hmac-md5-96"
+ * "hmac-sha1-128"
+ * "hmac-sha256-192"
+ * etc.
+ */
+ public static function getHMAC(name:String):HMAC {
+ var keys:Array = name.split("-");
+ if (keys[0]=="hmac") keys.shift();
+ var bits:uint = 0;
+ if (keys.length>1) {
+ bits = parseInt(keys[1]);
+ }
+ return new HMAC(getHash(keys[0]), bits);
+ }
+
+
+ public static function getMAC(name:String):MAC {
+
+ var keys:Array = name.split("-");
+ if (keys[0]=="mac") keys.shift();
+ var bits:uint = 0;
+ if (keys.length > 1) {
+ bits = parseInt(keys[1]);
+ }
+ return new MAC(getHash(keys[0]), bits);
+ }
+
+
+ public static function getPad(name:String):IPad {
+ switch(name) {
+ case "null":
+ return new NullPad;
+ case "pkcs5":
+ default:
+ return new PKCS5;
+ }
+ }
+
+ /** mostly useless.
+ */
+ public static function getRSA(E:String, M:String):RSAKey {
+ return RSAKey.parsePublicKey(M,E);
+ }
+ }
+}
\ No newline at end of file diff --git a/flash-src/third-party/com/hurlant/crypto/cert/MozillaRootCertificates.as b/flash-src/third-party/com/hurlant/crypto/cert/MozillaRootCertificates.as new file mode 100755 index 0000000..cc2e269 --- /dev/null +++ b/flash-src/third-party/com/hurlant/crypto/cert/MozillaRootCertificates.as @@ -0,0 +1,3235 @@ +/* THIS IS A GENERATED FILE */ +/** + * MozillaRootCertificates + * + * A list of built-in Certificate Authorities, + * pilfered from Mozilla. + * + * See certs/tool/grabRootCAs.pl for details. + * + * Copyright (c) 2007 Henri Torgemane + * + * See LICENSE.txt for full license information. + */ +package com.hurlant.crypto.cert { + public class MozillaRootCertificates extends X509CertificateCollection { + public function MozillaRootCertificates() { + super.addPEMCertificate("Verisign/RSA Secure Server CA", + // X500 Subject, for lookups. + "MF8xCzAJBgNVBAYTAlVTMSAwHgYDVQQKExdSU0EgRGF0YSBTZWN1cml0eSwgSW5jLjEuMCwGA1UE"+ + "CxMlU2VjdXJlIFNlcnZlciBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eQ==", + "-----BEGIN CERTIFICATE-----\n"+ + "MIICNDCCAaECEAKtZn5ORf5eV288mBle3cAwDQYJKoZIhvcNAQECBQAwXzELMAkG\n"+ + "A1UEBhMCVVMxIDAeBgNVBAoTF1JTQSBEYXRhIFNlY3VyaXR5LCBJbmMuMS4wLAYD\n"+ + "VQQLEyVTZWN1cmUgU2VydmVyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk0\n"+ + "MTEwOTAwMDAwMFoXDTEwMDEwNzIzNTk1OVowXzELMAkGA1UEBhMCVVMxIDAeBgNV\n"+ + "BAoTF1JTQSBEYXRhIFNlY3VyaXR5LCBJbmMuMS4wLAYDVQQLEyVTZWN1cmUgU2Vy\n"+ + "dmVyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGbMA0GCSqGSIb3DQEBAQUAA4GJ\n"+ + "ADCBhQJ+AJLOesGugz5aqomDV6wlAXYMra6OLDfO6zV4ZFQD5YRAUcm/jwjiioII\n"+ + "0haGN1XpsSECrXZogZoFokvJSyVmIlZsiAeP94FZbYQHZXATcXY+m3dM41CJVphI\n"+ + "uR2nKRoTLkoRWZweFdVJVCxzOmmCsZc5nG1wZ0jl3S3WyB57AgMBAAEwDQYJKoZI\n"+ + "hvcNAQECBQADfgBl3X7hsuyw4jrg7HFGmhkRuNPHoLQDQCYCPgmc4RKz0Vr2N6W3\n"+ + "YQO2WxZpO8ZECAyIUwxrl0nHPjXcbLm7qt9cuzovk2C2qUtN8iD3zV9/ZHuO3ABc\n"+ + "1/p3yjkWWW8O6tO1g39NTUJWdrTJXwT4OPjr0l91X817/OWOgHz8UA==\n"+ + "-----END CERTIFICATE-----"); + super.addPEMCertificate("GTE CyberTrust Root CA", + // X500 Subject, for lookups. + "MEUxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9HVEUgQ29ycG9yYXRpb24xHDAaBgNVBAMTE0dURSBD"+ + "eWJlclRydXN0IFJvb3Q=", + "-----BEGIN CERTIFICATE-----\n"+ + "MIIB+jCCAWMCAgGjMA0GCSqGSIb3DQEBBAUAMEUxCzAJBgNVBAYTAlVTMRgwFgYD\n"+ + "VQQKEw9HVEUgQ29ycG9yYXRpb24xHDAaBgNVBAMTE0dURSBDeWJlclRydXN0IFJv\n"+ + "b3QwHhcNOTYwMjIzMjMwMTAwWhcNMDYwMjIzMjM1OTAwWjBFMQswCQYDVQQGEwJV\n"+ + "UzEYMBYGA1UEChMPR1RFIENvcnBvcmF0aW9uMRwwGgYDVQQDExNHVEUgQ3liZXJU\n"+ + "cnVzdCBSb290MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC45k+625h8cXyv\n"+ + "RLfTD0bZZOWTwUKOx7pJjTUteueLveUFMVnGsS8KDPufpz+iCWaEVh43KRuH6X4M\n"+ + "ypqfpX/1FZSj1aJGgthoTNE3FQZor734sLPwKfWVWgkWYXcKIiXUT0Wqx73llt/5\n"+ + "1KiOQswkwB6RJ0q1bQaAYznEol44AwIDAQABMA0GCSqGSIb3DQEBBAUAA4GBABKz\n"+ + "dcZfHeFhVYAA1IFLezEPI2PnPfMD+fQ2qLvZ46WXTeorKeDWanOB5sCJo9Px4KWl\n"+ + "IjeaY8JIILTbcuPI9tl8vrGvU9oUtCG41tWW4/5ODFlitppK+ULdjG+BqXH/9Apy\n"+ + "bW1EDp3zdHSo1TRJ6V6e6bR64eVaH4QwnNOfpSXY\n"+ + "-----END CERTIFICATE-----"); + super.addPEMCertificate("GTE CyberTrust Global Root", + // X500 Subject, for lookups. + "MHUxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9HVEUgQ29ycG9yYXRpb24xJzAlBgNVBAsTHkdURSBD"+ + "eWJlclRydXN0IFNvbHV0aW9ucywgSW5jLjEjMCEGA1UEAxMaR1RFIEN5YmVyVHJ1c3QgR2xvYmFs"+ + "IFJvb3Q=", + "-----BEGIN CERTIFICATE-----\n"+ + "MIICWjCCAcMCAgGlMA0GCSqGSIb3DQEBBAUAMHUxCzAJBgNVBAYTAlVTMRgwFgYD\n"+ + "VQQKEw9HVEUgQ29ycG9yYXRpb24xJzAlBgNVBAsTHkdURSBDeWJlclRydXN0IFNv\n"+ + "bHV0aW9ucywgSW5jLjEjMCEGA1UEAxMaR1RFIEN5YmVyVHJ1c3QgR2xvYmFsIFJv\n"+ + "b3QwHhcNOTgwODEzMDAyOTAwWhcNMTgwODEzMjM1OTAwWjB1MQswCQYDVQQGEwJV\n"+ + "UzEYMBYGA1UEChMPR1RFIENvcnBvcmF0aW9uMScwJQYDVQQLEx5HVEUgQ3liZXJU\n"+ + "cnVzdCBTb2x1dGlvbnMsIEluYy4xIzAhBgNVBAMTGkdURSBDeWJlclRydXN0IEds\n"+ + "b2JhbCBSb290MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCVD6C28FCc6HrH\n"+ + "iM3dFw4usJTQGz0O9pTAipTHBsiQl8i4ZBp6fmw8U+E3KHNgf7KXUwefU/ltWJTS\n"+ + "r41tiGeA5u2ylc9yMcqlHHK6XALnZELn+aks1joNrI1CqiQBOeacPwGFVw1Yh0X4\n"+ + "04Wqk2kmhXBIgD8SFcd5tB8FLztimQIDAQABMA0GCSqGSIb3DQEBBAUAA4GBAG3r\n"+ + "GwnpXtlR22ciYaQqPEh346B8pt5zohQDhT37qw4wxYMWM4ETCJ57NE7fQMh017l9\n"+ + "3PR2VX2bY1QY6fDq81yx2YtCHrnAlU66+tXifPVoYb+O7AWXX1uw16OFNMQkpw0P\n"+ + "lZPvy5TYnh+dXIVtx6quTx8itc2VrbqnzPmrC3p/\n"+ + "-----END CERTIFICATE-----"); + super.addPEMCertificate("Thawte Personal Basic CA", + // X500 Subject, for lookups. + "MIHLMQswCQYDVQQGEwJaQTEVMBMGA1UECBMMV2VzdGVybiBDYXBlMRIwEAYDVQQHEwlDYXBlIFRv"+ + "d24xGjAYBgNVBAoTEVRoYXd0ZSBDb25zdWx0aW5nMSgwJgYDVQQLEx9DZXJ0aWZpY2F0aW9uIFNl"+ + "cnZpY2VzIERpdmlzaW9uMSEwHwYDVQQDExhUaGF3dGUgUGVyc29uYWwgQmFzaWMgQ0ExKDAmBgkq"+ + "hkiG9w0BCQEWGXBlcnNvbmFsLWJhc2ljQHRoYXd0ZS5jb20=", + "-----BEGIN CERTIFICATE-----\n"+ + "MIIDITCCAoqgAwIBAgIBADANBgkqhkiG9w0BAQQFADCByzELMAkGA1UEBhMCWkEx\n"+ + "FTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMRowGAYD\n"+ + "VQQKExFUaGF3dGUgQ29uc3VsdGluZzEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBT\n"+ + "ZXJ2aWNlcyBEaXZpc2lvbjEhMB8GA1UEAxMYVGhhd3RlIFBlcnNvbmFsIEJhc2lj\n"+ + "IENBMSgwJgYJKoZIhvcNAQkBFhlwZXJzb25hbC1iYXNpY0B0aGF3dGUuY29tMB4X\n"+ + "DTk2MDEwMTAwMDAwMFoXDTIwMTIzMTIzNTk1OVowgcsxCzAJBgNVBAYTAlpBMRUw\n"+ + "EwYDVQQIEwxXZXN0ZXJuIENhcGUxEjAQBgNVBAcTCUNhcGUgVG93bjEaMBgGA1UE\n"+ + "ChMRVGhhd3RlIENvbnN1bHRpbmcxKDAmBgNVBAsTH0NlcnRpZmljYXRpb24gU2Vy\n"+ + "dmljZXMgRGl2aXNpb24xITAfBgNVBAMTGFRoYXd0ZSBQZXJzb25hbCBCYXNpYyBD\n"+ + "QTEoMCYGCSqGSIb3DQEJARYZcGVyc29uYWwtYmFzaWNAdGhhd3RlLmNvbTCBnzAN\n"+ + "BgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAvLyTU23AUE+CFeZIlDWmWr5vQvoPR+53\n"+ + "dXLdjUmbllegeNTKP1GzaQuRdhciB5dqxFGTS+CN7zeVoQxN2jSQHReJl+A1OFdK\n"+ + "wPQIcOk8RHtQfmGakOMj04gRRif1CwcOu93RfyAKiLlWCy4cgNrx454p7xS9CkT7\n"+ + "G1sY0b8jkyECAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQQF\n"+ + "AAOBgQAt4plrsD16iddZopQBHyvdEktTwq1/qqcAXJFAVyVKOKqEcLnZgA+le1z7\n"+ + "c8a914phXAPjLSeoF+CEhULcXpvGt7Jtu3Sv5D/Lp7ew4F2+eIMllNLbgQ95B21P\n"+ + "9DkVWlIBe94y1k049hJcBlDfBVu9FEuh3ym6O0GN92NWod8isQ==\n"+ + "-----END CERTIFICATE-----"); + super.addPEMCertificate("Thawte Personal Premium CA", + // X500 Subject, for lookups. + "MIHPMQswCQYDVQQGEwJaQTEVMBMGA1UECBMMV2VzdGVybiBDYXBlMRIwEAYDVQQHEwlDYXBlIFRv"+ + "d24xGjAYBgNVBAoTEVRoYXd0ZSBDb25zdWx0aW5nMSgwJgYDVQQLEx9DZXJ0aWZpY2F0aW9uIFNl"+ + "cnZpY2VzIERpdmlzaW9uMSMwIQYDVQQDExpUaGF3dGUgUGVyc29uYWwgUHJlbWl1bSBDQTEqMCgG"+ + "CSqGSIb3DQEJARYbcGVyc29uYWwtcHJlbWl1bUB0aGF3dGUuY29t", + "-----BEGIN CERTIFICATE-----\n"+ + "MIIDKTCCApKgAwIBAgIBADANBgkqhkiG9w0BAQQFADCBzzELMAkGA1UEBhMCWkEx\n"+ + "FTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMRowGAYD\n"+ + "VQQKExFUaGF3dGUgQ29uc3VsdGluZzEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBT\n"+ + "ZXJ2aWNlcyBEaXZpc2lvbjEjMCEGA1UEAxMaVGhhd3RlIFBlcnNvbmFsIFByZW1p\n"+ + "dW0gQ0ExKjAoBgkqhkiG9w0BCQEWG3BlcnNvbmFsLXByZW1pdW1AdGhhd3RlLmNv\n"+ + "bTAeFw05NjAxMDEwMDAwMDBaFw0yMDEyMzEyMzU5NTlaMIHPMQswCQYDVQQGEwJa\n"+ + "QTEVMBMGA1UECBMMV2VzdGVybiBDYXBlMRIwEAYDVQQHEwlDYXBlIFRvd24xGjAY\n"+ + "BgNVBAoTEVRoYXd0ZSBDb25zdWx0aW5nMSgwJgYDVQQLEx9DZXJ0aWZpY2F0aW9u\n"+ + "IFNlcnZpY2VzIERpdmlzaW9uMSMwIQYDVQQDExpUaGF3dGUgUGVyc29uYWwgUHJl\n"+ + "bWl1bSBDQTEqMCgGCSqGSIb3DQEJARYbcGVyc29uYWwtcHJlbWl1bUB0aGF3dGUu\n"+ + "Y29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDJZtn4B0TPuYwu8KHvE0Vs\n"+ + "Bd/eJxZRNkERbGw77f4QfRKe5ZtCmv5gMcNmt3M6SK5O0DI3lIi1DbbZ8/JE2dWI\n"+ + "Et12TfIa/G8jHnrx2JhFTgcQ7xZC0EN1bUre4qrJMf8fAHB8Zs8QJQi6+u4A6UYD\n"+ + "ZicRFTuqW/KY3TZCstqIdQIDAQABoxMwETAPBgNVHRMBAf8EBTADAQH/MA0GCSqG\n"+ + "SIb3DQEBBAUAA4GBAGk2ifc0KjNyL2071CKyuG+axTZmDhs8obF1Wub9NdP4qPIH\n"+ + "b4Vnjt4rueIXsDqg8A6iAJrf8xQVbrvIhVqYgPn/vnQdPfP+MCXRNzRn+qVxeTBh\n"+ + "KXLA4CxM+1bkOqhv5TJZUtt1KFBZDPgLGeSs2a+WjS9Q2wfD6h+rM+D1KzGJ\n"+ + "-----END CERTIFICATE-----"); + super.addPEMCertificate("Thawte Personal Freemail CA", + // X500 Subject, for lookups. + "MIHRMQswCQYDVQQGEwJaQTEVMBMGA1UECBMMV2VzdGVybiBDYXBlMRIwEAYDVQQHEwlDYXBlIFRv"+ + "d24xGjAYBgNVBAoTEVRoYXd0ZSBDb25zdWx0aW5nMSgwJgYDVQQLEx9DZXJ0aWZpY2F0aW9uIFNl"+ + "cnZpY2VzIERpdmlzaW9uMSQwIgYDVQQDExtUaGF3dGUgUGVyc29uYWwgRnJlZW1haWwgQ0ExKzAp"+ + "BgkqhkiG9w0BCQEWHHBlcnNvbmFsLWZyZWVtYWlsQHRoYXd0ZS5jb20=", + "-----BEGIN CERTIFICATE-----\n"+ + "MIIDLTCCApagAwIBAgIBADANBgkqhkiG9w0BAQQFADCB0TELMAkGA1UEBhMCWkEx\n"+ + "FTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMRowGAYD\n"+ + "VQQKExFUaGF3dGUgQ29uc3VsdGluZzEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBT\n"+ + "ZXJ2aWNlcyBEaXZpc2lvbjEkMCIGA1UEAxMbVGhhd3RlIFBlcnNvbmFsIEZyZWVt\n"+ + "YWlsIENBMSswKQYJKoZIhvcNAQkBFhxwZXJzb25hbC1mcmVlbWFpbEB0aGF3dGUu\n"+ + "Y29tMB4XDTk2MDEwMTAwMDAwMFoXDTIwMTIzMTIzNTk1OVowgdExCzAJBgNVBAYT\n"+ + "AlpBMRUwEwYDVQQIEwxXZXN0ZXJuIENhcGUxEjAQBgNVBAcTCUNhcGUgVG93bjEa\n"+ + "MBgGA1UEChMRVGhhd3RlIENvbnN1bHRpbmcxKDAmBgNVBAsTH0NlcnRpZmljYXRp\n"+ + "b24gU2VydmljZXMgRGl2aXNpb24xJDAiBgNVBAMTG1RoYXd0ZSBQZXJzb25hbCBG\n"+ + "cmVlbWFpbCBDQTErMCkGCSqGSIb3DQEJARYccGVyc29uYWwtZnJlZW1haWxAdGhh\n"+ + "d3RlLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA1GnX1LCUZFtx6UfY\n"+ + "DFG26nKRsIRefS0Nj3sS34UldSh0OkIsYyeflXtL734Zhx2G6qPduc6WZBrCFG5E\n"+ + "rHzmj+hND3EfQDimAKOHePb5lIZererAXnbr2RSjXW56fAylS1V/Bhkpf56aJtVq\n"+ + "uzgkCGqYx7Hao5iR/Xnb5VrEHLkCAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zAN\n"+ + "BgkqhkiG9w0BAQQFAAOBgQDH7JJ+Tvj1lqVnYiqk8E0RYNBvjWBYYawmu1I1XAjP\n"+ + "MPuoSpaKH2JCI4wXD/S6ZJwXrEcp352YXtJsYHFcoqzceePnbgBHH7UNKOgCneSa\n"+ + "/RP0ptl8sfjcXyMmCZGAc9AUG95DqYMl8uacLxXK/qarigd1iwzdUYRr5PjRznei\n"+ + "gQ==\n"+ + "-----END CERTIFICATE-----"); + super.addPEMCertificate("Thawte Server CA", + // X500 Subject, for lookups. + "MIHEMQswCQYDVQQGEwJaQTEVMBMGA1UECBMMV2VzdGVybiBDYXBlMRIwEAYDVQQHEwlDYXBlIFRv"+ + "d24xHTAbBgNVBAoTFFRoYXd0ZSBDb25zdWx0aW5nIGNjMSgwJgYDVQQLEx9DZXJ0aWZpY2F0aW9u"+ + "IFNlcnZpY2VzIERpdmlzaW9uMRkwFwYDVQQDExBUaGF3dGUgU2VydmVyIENBMSYwJAYJKoZIhvcN"+ + "AQkBFhdzZXJ2ZXItY2VydHNAdGhhd3RlLmNvbQ==", + "-----BEGIN CERTIFICATE-----\n"+ + "MIIDEzCCAnygAwIBAgIBATANBgkqhkiG9w0BAQQFADCBxDELMAkGA1UEBhMCWkEx\n"+ + "FTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMR0wGwYD\n"+ + "VQQKExRUaGF3dGUgQ29uc3VsdGluZyBjYzEoMCYGA1UECxMfQ2VydGlmaWNhdGlv\n"+ + "biBTZXJ2aWNlcyBEaXZpc2lvbjEZMBcGA1UEAxMQVGhhd3RlIFNlcnZlciBDQTEm\n"+ + "MCQGCSqGSIb3DQEJARYXc2VydmVyLWNlcnRzQHRoYXd0ZS5jb20wHhcNOTYwODAx\n"+ + "MDAwMDAwWhcNMjAxMjMxMjM1OTU5WjCBxDELMAkGA1UEBhMCWkExFTATBgNVBAgT\n"+ + "DFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMR0wGwYDVQQKExRUaGF3\n"+ + "dGUgQ29uc3VsdGluZyBjYzEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNl\n"+ + "cyBEaXZpc2lvbjEZMBcGA1UEAxMQVGhhd3RlIFNlcnZlciBDQTEmMCQGCSqGSIb3\n"+ + "DQEJARYXc2VydmVyLWNlcnRzQHRoYXd0ZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQAD\n"+ + "gY0AMIGJAoGBANOkUG7I/1Zr5s9dtuoMaHVHoqrC2oQl/Kj0R1HahbUgdJSGHg91\n"+ + "yekIYfUGbTBuFRkC6VLAYttNmZ7iagxEOM3+vuNkCXDF/rFrKbYvScg71CcEJRCX\n"+ + "L+eQbcAoQpnXTEPew/UhbVSfXcNY4cDk2VuwuNy0e982OsK1ZiIS1ocNAgMBAAGj\n"+ + "EzARMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEEBQADgYEAB/pMaVz7lcxG\n"+ + "7oWDTSEwjsrZqG9JGubaUeNgcGyEYRGhGshIPllDfU+VPaGLtwtimHp1it2ITk6e\n"+ + "QNuozDJ0uW8NxuOzRAvZim+aKZuZGCg70eNAKJpaPNW15yAbi8qkq43pUdniTCxZ\n"+ + "qdq5snUb9kLy78fyGPmJvKP/iiMucEc=\n"+ + "-----END CERTIFICATE-----"); + super.addPEMCertificate("Thawte Premium Server CA", + // X500 Subject, for lookups. + "MIHOMQswCQYDVQQGEwJaQTEVMBMGA1UECBMMV2VzdGVybiBDYXBlMRIwEAYDVQQHEwlDYXBlIFRv"+ + "d24xHTAbBgNVBAoTFFRoYXd0ZSBDb25zdWx0aW5nIGNjMSgwJgYDVQQLEx9DZXJ0aWZpY2F0aW9u"+ + "IFNlcnZpY2VzIERpdmlzaW9uMSEwHwYDVQQDExhUaGF3dGUgUHJlbWl1bSBTZXJ2ZXIgQ0ExKDAm"+ + "BgkqhkiG9w0BCQEWGXByZW1pdW0tc2VydmVyQHRoYXd0ZS5jb20=", + "-----BEGIN CERTIFICATE-----\n"+ + "MIIDJzCCApCgAwIBAgIBATANBgkqhkiG9w0BAQQFADCBzjELMAkGA1UEBhMCWkEx\n"+ + "FTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMR0wGwYD\n"+ + "VQQKExRUaGF3dGUgQ29uc3VsdGluZyBjYzEoMCYGA1UECxMfQ2VydGlmaWNhdGlv\n"+ + "biBTZXJ2aWNlcyBEaXZpc2lvbjEhMB8GA1UEAxMYVGhhd3RlIFByZW1pdW0gU2Vy\n"+ + "dmVyIENBMSgwJgYJKoZIhvcNAQkBFhlwcmVtaXVtLXNlcnZlckB0aGF3dGUuY29t\n"+ + "MB4XDTk2MDgwMTAwMDAwMFoXDTIwMTIzMTIzNTk1OVowgc4xCzAJBgNVBAYTAlpB\n"+ + "MRUwEwYDVQQIEwxXZXN0ZXJuIENhcGUxEjAQBgNVBAcTCUNhcGUgVG93bjEdMBsG\n"+ + "A1UEChMUVGhhd3RlIENvbnN1bHRpbmcgY2MxKDAmBgNVBAsTH0NlcnRpZmljYXRp\n"+ + "b24gU2VydmljZXMgRGl2aXNpb24xITAfBgNVBAMTGFRoYXd0ZSBQcmVtaXVtIFNl\n"+ + "cnZlciBDQTEoMCYGCSqGSIb3DQEJARYZcHJlbWl1bS1zZXJ2ZXJAdGhhd3RlLmNv\n"+ + "bTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA0jY2aovXwlue2oFBYo847kkE\n"+ + "VdbQ7xwblRZH7xhINTpS9CtqBo87L+pW46+GjZ4X9560ZXUCTe/LCaIhUdib0GfQ\n"+ + "ug2SBhRz1JPLlyoAnFxODLz6FVL88kRu2hFKbgifLy3j+ao6hnO2RlNYyIkFvYMR\n"+ + "uHM/qgeN9EJN50CdHDcCAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG\n"+ + "9w0BAQQFAAOBgQAmSCwWwlj66BZ0DKqqX1Q/8tfJeGBeXm43YyJ3Nn6yF8Q0ufUI\n"+ + "hfzJATj/Tb7yFkJD57taRvvBxhEf8UqwKEbJw8RCfbz6q1lu1bdRiBHjpIUZa4JM\n"+ + "pAwSremkrj/xw0llmozFyD4lt5SZu5IycQfwhl7tUCemDaYj+bvLpgcUQg==\n"+ + "-----END CERTIFICATE-----"); + super.addPEMCertificate("Equifax Secure CA", + // X500 Subject, for lookups. + "ME4xCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFcXVpZmF4MS0wKwYDVQQLEyRFcXVpZmF4IFNlY3Vy"+ + "ZSBDZXJ0aWZpY2F0ZSBBdXRob3JpdHk=", + "-----BEGIN CERTIFICATE-----\n"+ + "MIIDIDCCAomgAwIBAgIENd70zzANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQGEwJV\n"+ + "UzEQMA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUgQ2Vy\n"+ + "dGlmaWNhdGUgQXV0aG9yaXR5MB4XDTk4MDgyMjE2NDE1MVoXDTE4MDgyMjE2NDE1\n"+ + "MVowTjELMAkGA1UEBhMCVVMxEDAOBgNVBAoTB0VxdWlmYXgxLTArBgNVBAsTJEVx\n"+ + "dWlmYXggU2VjdXJlIENlcnRpZmljYXRlIEF1dGhvcml0eTCBnzANBgkqhkiG9w0B\n"+ + "AQEFAAOBjQAwgYkCgYEAwV2xWGcIYu6gmi0fCG2RFGiYCh7+2gRvE4RiIcPRfM6f\n"+ + "BeC4AfBONOziipUEZKzxa1NfBbPLZ4C/QgKO/t0BCezhABRP/PvwDN1Dulsr4R+A\n"+ + "cJkVV5MW8Q+XarfCaCMczE1ZMKxRHjuvK9buY0V7xdlfUNLjUA86iOe/FP3gx7kC\n"+ + "AwEAAaOCAQkwggEFMHAGA1UdHwRpMGcwZaBjoGGkXzBdMQswCQYDVQQGEwJVUzEQ\n"+ + "MA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUgQ2VydGlm\n"+ + "aWNhdGUgQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMBoGA1UdEAQTMBGBDzIwMTgw\n"+ + "ODIyMTY0MTUxWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUSOZo+SvSspXXR9gj\n"+ + "IBBPM5iQn9QwHQYDVR0OBBYEFEjmaPkr0rKV10fYIyAQTzOYkJ/UMAwGA1UdEwQF\n"+ + "MAMBAf8wGgYJKoZIhvZ9B0EABA0wCxsFVjMuMGMDAgbAMA0GCSqGSIb3DQEBBQUA\n"+ + "A4GBAFjOKer89961zgK5F7WF0bnj4JXMJTENAKaSbn+2kmOeUJXRmm/kEd5jhW6Y\n"+ + "7qj/WsjTVbJmcVfewCHrPSqnI0kBBIZCe/zuf6IWUrVnZ9NA2zsmWLIodz2uFHdh\n"+ + "1voqZiegDfqnc1zqcPGUIWVEX/r87yloqaKHee9570+sB3c4\n"+ + "-----END CERTIFICATE-----"); + super.addPEMCertificate("ABAecom (sub., Am. Bankers Assn.) Root CA", + // X500 Subject, for lookups. + "MIGJMQswCQYDVQQGEwJVUzELMAkGA1UECBMCREMxEzARBgNVBAcTCldhc2hpbmd0b24xFzAVBgNV"+ + "BAoTDkFCQS5FQ09NLCBJTkMuMRkwFwYDVQQDExBBQkEuRUNPTSBSb290IENBMSQwIgYJKoZIhvcN"+ + "AQkBFhVhZG1pbkBkaWdzaWd0cnVzdC5jb20=", + "-----BEGIN CERTIFICATE-----\n"+ + "MIIDtTCCAp2gAwIBAgIRANAeQJAAAEZSAAAAAQAAAAQwDQYJKoZIhvcNAQEFBQAw\n"+ + "gYkxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJEQzETMBEGA1UEBxMKV2FzaGluZ3Rv\n"+ + "bjEXMBUGA1UEChMOQUJBLkVDT00sIElOQy4xGTAXBgNVBAMTEEFCQS5FQ09NIFJv\n"+ + "b3QgQ0ExJDAiBgkqhkiG9w0BCQEWFWFkbWluQGRpZ3NpZ3RydXN0LmNvbTAeFw05\n"+ + "OTA3MTIxNzMzNTNaFw0wOTA3MDkxNzMzNTNaMIGJMQswCQYDVQQGEwJVUzELMAkG\n"+ + "A1UECBMCREMxEzARBgNVBAcTCldhc2hpbmd0b24xFzAVBgNVBAoTDkFCQS5FQ09N\n"+ + "LCBJTkMuMRkwFwYDVQQDExBBQkEuRUNPTSBSb290IENBMSQwIgYJKoZIhvcNAQkB\n"+ + "FhVhZG1pbkBkaWdzaWd0cnVzdC5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw\n"+ + "ggEKAoIBAQCx0xHgeVVDBwhMywVCAOINg0Y95JO6tgbTDVm9PsHOQ2cBiiGo77zM\n"+ + "0KLMsFWWU4RmBQDaREmA2FQKpSWGlO1jVv9wbKOhGdJ4vmgqRF4vz8wYXke8OrFG\n"+ + "PR7wuSw0X4x8TAgpnUBV6zx9g9618PeKgw6hTLQ6pbNfWiKX7BmbwQVo/ea3qZGU\n"+ + "LOR4SCQaJRk665WcOQqKz0Ky8BzVX/tr7WhWezkscjiw7pOp03t3POtxA6k4ShZs\n"+ + "iSrK2jMTecJVjO2cu/LLWxD4LmE1xilMKtAqY9FlWbT4zfn0AIS2V0KFnTKo+SpU\n"+ + "+/94Qby9cSj0u5C8/5Y0BONFnqFGKECBAgMBAAGjFjAUMBIGA1UdEwEB/wQIMAYB\n"+ + "Af8CAQgwDQYJKoZIhvcNAQEFBQADggEBAARvJYbk5pYntNlCwNDJALF/VD6Hsm0k\n"+ + "qS8Kfv2kRLD4VAe9G52dyntQJHsRW0mjpr8SdNWJt7cvmGQlFLdh6X9ggGvTZOir\n"+ + "vRrWUfrAtF13Gn9kCF55xgVM8XrdTX3O5kh7VNJhkoHWG9YA8A6eKHegTYjHInYZ\n"+ + "w8eeG6Z3ePhfm1bR8PIXrI6dWeYf/le22V7hXZ9F7GFoGUHhsiAm/lowdiT/QHI8\n"+ + "eZ98IkirRs3bs4Ysj78FQdPB4xTjQRcm0HyncUwZ6EoPclgxfexgeqMiKL0ZJGA/\n"+ + "O4dzwGvky663qyVDslUte6sGDnVdNOVdc22esnVApVnJTzFxiNmIf1Q=\n"+ + "-----END CERTIFICATE-----"); + super.addPEMCertificate("Digital Signature Trust Co. Global CA 1", + // X500 Subject, for lookups. + "MEYxCzAJBgNVBAYTAlVTMSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xETAP"+ + "BgNVBAsTCERTVENBIEUx", + "-----BEGIN CERTIFICATE-----\n"+ + "MIIDKTCCApKgAwIBAgIENnAVljANBgkqhkiG9w0BAQUFADBGMQswCQYDVQQGEwJV\n"+ + "UzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMREwDwYDVQQL\n"+ + "EwhEU1RDQSBFMTAeFw05ODEyMTAxODEwMjNaFw0xODEyMTAxODQwMjNaMEYxCzAJ\n"+ + "BgNVBAYTAlVTMSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4x\n"+ + "ETAPBgNVBAsTCERTVENBIEUxMIGdMA0GCSqGSIb3DQEBAQUAA4GLADCBhwKBgQCg\n"+ + "bIGpzzQeJN3+hijM3oMv+V7UQtLodGBmE5gGHKlREmlvMVW5SXIACH7TpWJENySZ\n"+ + "j9mDSI+ZbZUTu0M7LklOiDfBu1h//uG9+LthzfNHwJmm8fOR6Hh8AMthyUQncWlV\n"+ + "Sn5JTe2io74CTADKAqjuAQIxZA9SLRN0dja1erQtcQIBA6OCASQwggEgMBEGCWCG\n"+ + "SAGG+EIBAQQEAwIABzBoBgNVHR8EYTBfMF2gW6BZpFcwVTELMAkGA1UEBhMCVVMx\n"+ + "JDAiBgNVBAoTG0RpZ2l0YWwgU2lnbmF0dXJlIFRydXN0IENvLjERMA8GA1UECxMI\n"+ + "RFNUQ0EgRTExDTALBgNVBAMTBENSTDEwKwYDVR0QBCQwIoAPMTk5ODEyMTAxODEw\n"+ + "MjNagQ8yMDE4MTIxMDE4MTAyM1owCwYDVR0PBAQDAgEGMB8GA1UdIwQYMBaAFGp5\n"+ + "fpFpRhgTCgJ3pVlbYJglDqL4MB0GA1UdDgQWBBRqeX6RaUYYEwoCd6VZW2CYJQ6i\n"+ + "+DAMBgNVHRMEBTADAQH/MBkGCSqGSIb2fQdBAAQMMAobBFY0LjADAgSQMA0GCSqG\n"+ + "SIb3DQEBBQUAA4GBACIS2Hod3IEGtgllsofIH160L+nEHvI8wbsEkBFKg05+k7lN\n"+ + "QseSJqBcNJo4cvj9axY+IO6CizEqkzaFI4iKPANo08kJD038bKTaKHKTDomAsH3+\n"+ + "gG9lbRgzl4vCa4nuYD3Im+9/KzJic5PLPON74nZ4RbyhkwS7hp86W0N6w4pl\n"+ + "-----END CERTIFICATE-----"); + super.addPEMCertificate("Digital Signature Trust Co. Global CA 3", + // X500 Subject, for lookups. + "MEYxCzAJBgNVBAYTAlVTMSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xETAP"+ + "BgNVBAsTCERTVENBIEUy", + "-----BEGIN CERTIFICATE-----\n"+ + "MIIDKTCCApKgAwIBAgIENm7TzjANBgkqhkiG9w0BAQUFADBGMQswCQYDVQQGEwJV\n"+ + "UzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMREwDwYDVQQL\n"+ + "EwhEU1RDQSBFMjAeFw05ODEyMDkxOTE3MjZaFw0xODEyMDkxOTQ3MjZaMEYxCzAJ\n"+ + "BgNVBAYTAlVTMSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4x\n"+ + "ETAPBgNVBAsTCERTVENBIEUyMIGdMA0GCSqGSIb3DQEBAQUAA4GLADCBhwKBgQC/\n"+ + "k48Xku8zExjrEH9OFr//Bo8qhbxe+SSmJIi2A7fBw18DW9Fvrn5C6mYjuGODVvso\n"+ + "LeE4i7TuqAHhzhy2iCoiRoX7n6dwqUcUP87eZfCocfdPJmyMvMa1795JJ/9IKn3o\n"+ + "TQPMx7JSxhcxEzu1TdvIxPbDDyQq2gyd55FbgM2UnQIBA6OCASQwggEgMBEGCWCG\n"+ + "SAGG+EIBAQQEAwIABzBoBgNVHR8EYTBfMF2gW6BZpFcwVTELMAkGA1UEBhMCVVMx\n"+ + "JDAiBgNVBAoTG0RpZ2l0YWwgU2lnbmF0dXJlIFRydXN0IENvLjERMA8GA1UECxMI\n"+ + "RFNUQ0EgRTIxDTALBgNVBAMTBENSTDEwKwYDVR0QBCQwIoAPMTk5ODEyMDkxOTE3\n"+ + "MjZagQ8yMDE4MTIwOTE5MTcyNlowCwYDVR0PBAQDAgEGMB8GA1UdIwQYMBaAFB6C\n"+ + "TShlgDzJQW6sNS5ay97u+DlbMB0GA1UdDgQWBBQegk0oZYA8yUFurDUuWsve7vg5\n"+ + "WzAMBgNVHRMEBTADAQH/MBkGCSqGSIb2fQdBAAQMMAobBFY0LjADAgSQMA0GCSqG\n"+ + "SIb3DQEBBQUAA4GBAEeNg61i8tuwnkUiBbmi1gMOOHLnnvx75pO2mqWilMg0HZHR\n"+ + "xdf0CiUPPXiBng+xZ8SQTGPdXqfiup/1902lMXucKS1M/mQ+7LZT/uqb7YLbdHVL\n"+ + "B3luHtgZg3Pe9T7Qtd7nS2h9Qy4qIOF+oHhEngj1mPnHfxsb1gYgAlihw6ID\n"+ + "-----END CERTIFICATE-----"); + super.addPEMCertificate("Digital Signature Trust Co. Global CA 2", + // X500 Subject, for lookups. + "MIGpMQswCQYDVQQGEwJ1czENMAsGA1UECBMEVXRhaDEXMBUGA1UEBxMOU2FsdCBMYWtlIENpdHkx"+ + "JDAiBgNVBAoTG0RpZ2l0YWwgU2lnbmF0dXJlIFRydXN0IENvLjERMA8GA1UECxMIRFNUQ0EgWDEx"+ + "FjAUBgNVBAMTDURTVCBSb290Q0EgWDExITAfBgkqhkiG9w0BCQEWEmNhQGRpZ3NpZ3RydXN0LmNv"+ + "bQ==", + "-----BEGIN CERTIFICATE-----\n"+ + "MIID2DCCAsACEQDQHkCLAAACfAAAAAIAAAABMA0GCSqGSIb3DQEBBQUAMIGpMQsw\n"+ + "CQYDVQQGEwJ1czENMAsGA1UECBMEVXRhaDEXMBUGA1UEBxMOU2FsdCBMYWtlIENp\n"+ + "dHkxJDAiBgNVBAoTG0RpZ2l0YWwgU2lnbmF0dXJlIFRydXN0IENvLjERMA8GA1UE\n"+ + "CxMIRFNUQ0EgWDExFjAUBgNVBAMTDURTVCBSb290Q0EgWDExITAfBgkqhkiG9w0B\n"+ + "CQEWEmNhQGRpZ3NpZ3RydXN0LmNvbTAeFw05ODEyMDExODE4NTVaFw0wODExMjgx\n"+ + "ODE4NTVaMIGpMQswCQYDVQQGEwJ1czENMAsGA1UECBMEVXRhaDEXMBUGA1UEBxMO\n"+ + "U2FsdCBMYWtlIENpdHkxJDAiBgNVBAoTG0RpZ2l0YWwgU2lnbmF0dXJlIFRydXN0\n"+ + "IENvLjERMA8GA1UECxMIRFNUQ0EgWDExFjAUBgNVBAMTDURTVCBSb290Q0EgWDEx\n"+ + "ITAfBgkqhkiG9w0BCQEWEmNhQGRpZ3NpZ3RydXN0LmNvbTCCASIwDQYJKoZIhvcN\n"+ + "AQEBBQADggEPADCCAQoCggEBANLGJrbnpT3BxGjVUG9TxW9JEwm4ryxIjRRqoxdf\n"+ + "WvnTLnUv2Chi0ZMv/E3Uq4flCMeZ55I/db3rJbQVwZsZPdJEjdd0IG03Ao9pk1uK\n"+ + "xBmd9LIO/BZsubEFkoPRhSxglD5FVaDZqwgh5mDoO3TymVBRaNADLbGAvqPYUrBE\n"+ + "zUNKcI5YhZXhTizWLUFv1oTnyJhEykfbLCSlaSbPa7gnYsP0yXqSI+0TZ4KuRS5F\n"+ + "5X5yP4WdlGIQ5jyRoa13AOAV7POEgHJ6jm5gl8ckWRA0g1vhpaRptlc1HHhZxtMv\n"+ + "OnNn7pTKBBMFYgZwI7P0fO5F2WQLW0mqpEPOJsREEmy43XkCAwEAATANBgkqhkiG\n"+ + "9w0BAQUFAAOCAQEAojeyP2n714Z5VEkxlTMr89EJFEliYIalsBHiUMIdBlc+Legz\n"+ + "ZL6bqq1fG03UmZWii5rJYnK1aerZWKs17RWiQ9a2vAd5ZWRzfdd5ynvVWlHG4VME\n"+ + "lo04z6MXrDlxawHDi1M8Y+nuecDkvpIyZHqzH5eUYr3qsiAVlfuX8ngvYzZAOONG\n"+ + "Dx3drJXK50uQe7FLqdTF65raqtWjlBRGjS0f8zrWkzr2Pnn86Oawde3uPclwx12q\n"+ + "gUtGJRzHbBXjlU4PqjI3lAoXJJIThFjSY28r9+ZbYgsTF7ANUkz+/m9c4pFuHf2k\n"+ + "Ytdo+o56T9II2pPc8JIRetDccpMMc5NihWjQ9A==\n"+ + "-----END CERTIFICATE-----"); + super.addPEMCertificate("Digital Signature Trust Co. Global CA 4", + // X500 Subject, for lookups. + "MIGpMQswCQYDVQQGEwJ1czENMAsGA1UECBMEVXRhaDEXMBUGA1UEBxMOU2FsdCBMYWtlIENpdHkx"+ + "JDAiBgNVBAoTG0RpZ2l0YWwgU2lnbmF0dXJlIFRydXN0IENvLjERMA8GA1UECxMIRFNUQ0EgWDIx"+ + "FjAUBgNVBAMTDURTVCBSb290Q0EgWDIxITAfBgkqhkiG9w0BCQEWEmNhQGRpZ3NpZ3RydXN0LmNv"+ + "bQ==", + "-----BEGIN CERTIFICATE-----\n"+ + "MIID2DCCAsACEQDQHkCLAAB3bQAAAAEAAAAEMA0GCSqGSIb3DQEBBQUAMIGpMQsw\n"+ + "CQYDVQQGEwJ1czENMAsGA1UECBMEVXRhaDEXMBUGA1UEBxMOU2FsdCBMYWtlIENp\n"+ + "dHkxJDAiBgNVBAoTG0RpZ2l0YWwgU2lnbmF0dXJlIFRydXN0IENvLjERMA8GA1UE\n"+ + "CxMIRFNUQ0EgWDIxFjAUBgNVBAMTDURTVCBSb290Q0EgWDIxITAfBgkqhkiG9w0B\n"+ + "CQEWEmNhQGRpZ3NpZ3RydXN0LmNvbTAeFw05ODExMzAyMjQ2MTZaFw0wODExMjcy\n"+ + "MjQ2MTZaMIGpMQswCQYDVQQGEwJ1czENMAsGA1UECBMEVXRhaDEXMBUGA1UEBxMO\n"+ + "U2FsdCBMYWtlIENpdHkxJDAiBgNVBAoTG0RpZ2l0YWwgU2lnbmF0dXJlIFRydXN0\n"+ + "IENvLjERMA8GA1UECxMIRFNUQ0EgWDIxFjAUBgNVBAMTDURTVCBSb290Q0EgWDIx\n"+ + "ITAfBgkqhkiG9w0BCQEWEmNhQGRpZ3NpZ3RydXN0LmNvbTCCASIwDQYJKoZIhvcN\n"+ + "AQEBBQADggEPADCCAQoCggEBANx18IzAdZaawGIfJvfE4Zrq4FZzW5nNAUSoCLbV\n"+ + "p9oaBBg5kkp4o4HC9Xd6ULRw/5qrxsfKboNPQpj7Jgva3G3WqZlVUmfpKAOS3OWw\n"+ + "BZoPFflrWXJW8vo5/Kpo7g8fEIMv/J36F5bdguPmRX3AS4BEH+0s4IT9kVySVGkl\n"+ + "5WJp3OXuAFK9MwutdQKFp2RQLcUZGTDAJtvJ0/0uma1ZtQtN1EGuhUhDWdy3qOKi\n"+ + "3sOP17ihYqZoUFLkzzGnlIXan0YyF1bl8utmPRL/Q9uY73fPy4GNNLHGUEom0eQ+\n"+ + "QVCvbK4iNC7Va26Dunm4dmVI2gkpZGMiuftHdoWMhkTLCdsCAwEAATANBgkqhkiG\n"+ + "9w0BAQUFAAOCAQEAtTYOXeFhKFoRZcA/gwN5Tb4opgsHAlKFzfiR0BBstWogWxyQ\n"+ + "2TA8xkieil5k+aFxd+8EJx8H6+Qm93N0yUQYGmbT4EOvkTvRyyzYdFQ6HE3K1GjN\n"+ + "I3wdEJ5F6fYAbqbNGf9PLCmPV03Ed5K+4EwJ+11EhmYhqLkyolbV6YyDfFk/xPEL\n"+ + "553snr2cGA4+wjl5KLcDDQjLxufZATdQEOzMYRZA1K8xdHv8PzGn0EdzMzkbzE5q\n"+ + "10mDEQb+64JYMzJM8FasHpwvVpp7wUocpf1VNs78lk30sPDst2yC7S8xmUJMqbIN\n"+ + "uBVd8d+6ybVK1GSYsyapMMj9puyrliGtf8J4tg==\n"+ + "-----END CERTIFICATE-----"); + super.addPEMCertificate("Verisign Class 1 Public Primary Certification Authority", + // X500 Subject, for lookups. + "MF8xCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE3MDUGA1UECxMuQ2xhc3Mg"+ + "MSBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eQ==", + "-----BEGIN CERTIFICATE-----\n"+ + "MIICPTCCAaYCEQDNun9W8N/kvFT+IqyzcqpVMA0GCSqGSIb3DQEBAgUAMF8xCzAJ\n"+ + "BgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE3MDUGA1UECxMuQ2xh\n"+ + "c3MgMSBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw05\n"+ + "NjAxMjkwMDAwMDBaFw0yODA4MDEyMzU5NTlaMF8xCzAJBgNVBAYTAlVTMRcwFQYD\n"+ + "VQQKEw5WZXJpU2lnbiwgSW5jLjE3MDUGA1UECxMuQ2xhc3MgMSBQdWJsaWMgUHJp\n"+ + "bWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCBnzANBgkqhkiG9w0BAQEFAAOB\n"+ + "jQAwgYkCgYEA5Rm/baNWYS2ZSHH2Z965jeu3noaACpEO+jglr0aIguVzqKCbJF0N\n"+ + "H8xlbgyw0FaEGIeaBpsQoXPftFg5a27B9hXVqKg/qhIGjTGsf7A01480Z4gJzRQR\n"+ + "4k5FVmkfeAKA2txHkSm7NsljXMXg1y2He6G3MrB7MLoqLzGq7qNn2tsCAwEAATAN\n"+ + "BgkqhkiG9w0BAQIFAAOBgQBMP7iLxmjf7kMzDl3ppssHhE16M/+SG/Q2rdiVIjZo\n"+ + "EWx8QszznC7EBz8UsA9P/5CSdvnivErpj82ggAr3xSnxgiJduLHdgSOjeyUVRjB5\n"+ + "FvjqBUuUfx3CHMjjt/QQQDwTw18fU+hI5Ia0e6E1sHslurjTjqs/OJ0ANACY89Fx\n"+ + "lA==\n"+ + "-----END CERTIFICATE-----"); + super.addPEMCertificate("Verisign Class 2 Public Primary Certification Authority", + // X500 Subject, for lookups. + "MF8xCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE3MDUGA1UECxMuQ2xhc3Mg"+ + "MiBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eQ==", + "-----BEGIN CERTIFICATE-----\n"+ + "MIICPDCCAaUCEC0b/EoXjaOR6+f/9YtFvgswDQYJKoZIhvcNAQECBQAwXzELMAkG\n"+ + "A1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFz\n"+ + "cyAyIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk2\n"+ + "MDEyOTAwMDAwMFoXDTI4MDgwMTIzNTk1OVowXzELMAkGA1UEBhMCVVMxFzAVBgNV\n"+ + "BAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAyIFB1YmxpYyBQcmlt\n"+ + "YXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUAA4GN\n"+ + "ADCBiQKBgQC2WoujDWojg4BrzzmH9CETMwZMJaLtVRKXxaeAufqDwSCg+i8VDXyh\n"+ + "YGt+eSz6Bg86rvYbb7HS/y8oUl+DfUvEerf4Zh+AVPy3wo5ZShRXRtGak75BkQO7\n"+ + "FYCTXOvnzAhsPz6zSvz/S2wj1VCCJkQZjiPDceoZJEcEnnW/yKYAHwIDAQABMA0G\n"+ + "CSqGSIb3DQEBAgUAA4GBAIobK/o5wXTXXtgZZKJYSi034DNHD6zt96rbHuSLBlxg\n"+ + "J8pFUs4W7z8GZOeUaHxgMxURaa+dYo2jA1Rrpr7l7gUYYAS/QoD90KioHgE796Nc\n"+ + "r6Pc5iaAIzy4RHT3Cq5Ji2F4zCS/iIqnDupzGUH9TQPwiNHleI2lKk/2lw0Xd8rY\n"+ + "-----END CERTIFICATE-----"); + super.addPEMCertificate("Verisign Class 3 Public Primary Certification Authority", + // X500 Subject, for lookups. + "MF8xCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE3MDUGA1UECxMuQ2xhc3Mg"+ + "MyBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eQ==", + "-----BEGIN CERTIFICATE-----\n"+ + "MIICPDCCAaUCEHC65B0Q2Sk0tjjKewPMur8wDQYJKoZIhvcNAQECBQAwXzELMAkG\n"+ + "A1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFz\n"+ + "cyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk2\n"+ + "MDEyOTAwMDAwMFoXDTI4MDgwMTIzNTk1OVowXzELMAkGA1UEBhMCVVMxFzAVBgNV\n"+ + "BAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAzIFB1YmxpYyBQcmlt\n"+ + "YXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUAA4GN\n"+ + "ADCBiQKBgQDJXFme8huKARS0EN8EQNvjV69qRUCPhAwL0TPZ2RHP7gJYHyX3KqhE\n"+ + "BarsAx94f56TuZoAqiN91qyFomNFx3InzPRMxnVx0jnvT0Lwdd8KkMaOIG+YD/is\n"+ + "I19wKTakyYbnsZogy1Olhec9vn2a/iRFM9x2Fe0PonFkTGUugWhFpwIDAQABMA0G\n"+ + "CSqGSIb3DQEBAgUAA4GBALtMEivPLCYATxQT3ab7/AoRhIzzKBxnki98tsX63/Do\n"+ + "lbwdj2wsqFHMc9ikwFPwTtYmwHYBV4GSXiHx0bH/59AhWM1pF+NEHJwZRDmJXNyc\n"+ + "AA9WjQKZ7aKQRUzkuxCkPfAyAw7xzvjoyVGM5mKf5p/AfbdynMk2OmufTqj/ZA1k\n"+ + "-----END CERTIFICATE-----"); + super.addPEMCertificate("Verisign Class 1 Public Primary Certification Authority - G2", + // X500 Subject, for lookups. + "MIHBMQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xPDA6BgNVBAsTM0NsYXNz"+ + "IDEgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMjE6MDgGA1UECxMx"+ + "KGMpIDE5OTggVmVyaVNpZ24sIEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTEfMB0GA1UE"+ + "CxMWVmVyaVNpZ24gVHJ1c3QgTmV0d29yaw==", + "-----BEGIN CERTIFICATE-----\n"+ + "MIIDAjCCAmsCEEzH6qqYPnHTkxD4PTqJkZIwDQYJKoZIhvcNAQEFBQAwgcExCzAJ\n"+ + "BgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xh\n"+ + "c3MgMSBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcy\n"+ + "MTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3Jp\n"+ + "emVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMB4X\n"+ + "DTk4MDUxODAwMDAwMFoXDTI4MDgwMTIzNTk1OVowgcExCzAJBgNVBAYTAlVTMRcw\n"+ + "FQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xhc3MgMSBQdWJsaWMg\n"+ + "UHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMTowOAYDVQQLEzEo\n"+ + "YykgMTk5OCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5\n"+ + "MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMIGfMA0GCSqGSIb3DQEB\n"+ + "AQUAA4GNADCBiQKBgQCq0Lq+Fi24g9TK0g+8djHKlNgdk4xWArzZbxpvUjZudVYK\n"+ + "VdPfQ4chEWWKfo+9Id5rMj8bhDSVBZ1BNeuS65bdqlk/AVNtmU/t5eIqWpDBucSm\n"+ + "Fc/IReumXY6cPvBkJHalzasab7bYe1FhbqZ/h8jit+U03EGI6glAvnOSPWvndQID\n"+ + "AQABMA0GCSqGSIb3DQEBBQUAA4GBAKlPww3HZ74sy9mozS11534Vnjty637rXC0J\n"+ + "h9ZrbWB85a7FkCMMXErQr7Fd88e2CtvgFZMN3QO8x3aKtd1Pw5sTdbgBwObJW2ul\n"+ + "uIncrKTdcu1OofdPvAbT6shkdHvClUGcZXNY8ZCaPGqxmMnEh7zPRW1F4m4iP/68\n"+ + "DzFc6PLZ\n"+ + "-----END CERTIFICATE-----"); + super.addPEMCertificate("Verisign Class 2 Public Primary Certification Authority - G2", + // X500 Subject, for lookups. + "MIHBMQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xPDA6BgNVBAsTM0NsYXNz"+ + "IDIgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMjE6MDgGA1UECxMx"+ + "KGMpIDE5OTggVmVyaVNpZ24sIEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTEfMB0GA1UE"+ + "CxMWVmVyaVNpZ24gVHJ1c3QgTmV0d29yaw==", + "-----BEGIN CERTIFICATE-----\n"+ + "MIIDAzCCAmwCEQC5L2DMiJ+hekYJuFtwbIqvMA0GCSqGSIb3DQEBBQUAMIHBMQsw\n"+ + "CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xPDA6BgNVBAsTM0Ns\n"+ + "YXNzIDIgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBH\n"+ + "MjE6MDgGA1UECxMxKGMpIDE5OTggVmVyaVNpZ24sIEluYy4gLSBGb3IgYXV0aG9y\n"+ + "aXplZCB1c2Ugb25seTEfMB0GA1UECxMWVmVyaVNpZ24gVHJ1c3QgTmV0d29yazAe\n"+ + "Fw05ODA1MTgwMDAwMDBaFw0yODA4MDEyMzU5NTlaMIHBMQswCQYDVQQGEwJVUzEX\n"+ + "MBUGA1UEChMOVmVyaVNpZ24sIEluYy4xPDA6BgNVBAsTM0NsYXNzIDIgUHVibGlj\n"+ + "IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMjE6MDgGA1UECxMx\n"+ + "KGMpIDE5OTggVmVyaVNpZ24sIEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25s\n"+ + "eTEfMB0GA1UECxMWVmVyaVNpZ24gVHJ1c3QgTmV0d29yazCBnzANBgkqhkiG9w0B\n"+ + "AQEFAAOBjQAwgYkCgYEAp4gBIXQs5xoD8JjhlzwPIQjxnNuX6Zr8wgQGE75fUsjM\n"+ + "HiwSViy4AWkszJkfrbCWrnkE8hM5wXuYuggs6MKEEyyqaekJ9MepAqRCwiNPStjw\n"+ + "DqL7MWzJ5m+ZJwf15vRMeJ5t60aG+rmGyVTyssSv1EYcWskVMP8NbPUtDm3Of3cC\n"+ + "AwEAATANBgkqhkiG9w0BAQUFAAOBgQByLvl/0fFx+8Se9sVeUYpAmLho+Jscg9ji\n"+ + "nb3/7aHmZuovCfTK1+qlK5X2JGCGTUQug6XELaDTrnhpb3LabK4I8GOSN+a7xDAX\n"+ + "rXfMSTWqz9iP0b63GJZHc2pUIjRkLbYWm1lbtFFZOrMLFPQS32eg9K0yZF6xRnIn\n"+ + "jBJ7xUS0rg==\n"+ + "-----END CERTIFICATE-----"); + super.addPEMCertificate("Verisign Class 3 Public Primary Certification Authority - G2", + // X500 Subject, for lookups. + "MIHBMQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xPDA6BgNVBAsTM0NsYXNz"+ + "IDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMjE6MDgGA1UECxMx"+ + "KGMpIDE5OTggVmVyaVNpZ24sIEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTEfMB0GA1UE"+ + "CxMWVmVyaVNpZ24gVHJ1c3QgTmV0d29yaw==", + "-----BEGIN CERTIFICATE-----\n"+ + "MIIDAjCCAmsCEH3Z/gfPqB63EHln+6eJNMYwDQYJKoZIhvcNAQEFBQAwgcExCzAJ\n"+ + "BgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xh\n"+ + "c3MgMyBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcy\n"+ + "MTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3Jp\n"+ + "emVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMB4X\n"+ + "DTk4MDUxODAwMDAwMFoXDTI4MDgwMTIzNTk1OVowgcExCzAJBgNVBAYTAlVTMRcw\n"+ + "FQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xhc3MgMyBQdWJsaWMg\n"+ + "UHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMTowOAYDVQQLEzEo\n"+ + "YykgMTk5OCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5\n"+ + "MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMIGfMA0GCSqGSIb3DQEB\n"+ + "AQUAA4GNADCBiQKBgQDMXtERXVxp0KvTuWpMmR9ZmDCOFoUgRm1HP9SFIIThbbP4\n"+ + "pO0M8RcPO/mn+SXXwc+EY/J8Y8+iR/LGWzOOZEAEaMGAuWQcRXfH2G71lSk8UOg0\n"+ + "13gfqLptQ5GVj0VXXn7F+8qkBOvqlzdUMG+7AUcyM83cV5tkaWH4mx0ciU9cZwID\n"+ + "AQABMA0GCSqGSIb3DQEBBQUAA4GBAFFNzb5cy5gZnBWyATl4Lk0PZ3BwmcYQWpSk\n"+ + "U01UbSuvDV1Ai2TT1+7eVmGSX6bEHRBhNtMsJzzoKQm5EWR0zLVznxxIqbxhAe7i\n"+ + "F6YM40AIOw7n60RzKprxaZLvcRTDOaxxp5EJb+RxBrO6WVcmeQD2+A2iMzAo1KpY\n"+ + "oJ2daZH9\n"+ + "-----END CERTIFICATE-----"); + super.addPEMCertificate("Verisign Class 4 Public Primary Certification Authority - G2", + // X500 Subject, for lookups. + "MIHBMQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xPDA6BgNVBAsTM0NsYXNz"+ + "IDQgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMjE6MDgGA1UECxMx"+ + "KGMpIDE5OTggVmVyaVNpZ24sIEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTEfMB0GA1UE"+ + "CxMWVmVyaVNpZ24gVHJ1c3QgTmV0d29yaw==", + "-----BEGIN CERTIFICATE-----\n"+ + "MIIDAjCCAmsCEDKIjprS9esTR/h/xCA3JfgwDQYJKoZIhvcNAQEFBQAwgcExCzAJ\n"+ + "BgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xh\n"+ + "c3MgNCBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcy\n"+ + "MTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3Jp\n"+ + "emVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMB4X\n"+ + "DTk4MDUxODAwMDAwMFoXDTI4MDgwMTIzNTk1OVowgcExCzAJBgNVBAYTAlVTMRcw\n"+ + "FQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xhc3MgNCBQdWJsaWMg\n"+ + "UHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMTowOAYDVQQLEzEo\n"+ + "YykgMTk5OCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5\n"+ + "MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMIGfMA0GCSqGSIb3DQEB\n"+ + "AQUAA4GNADCBiQKBgQC68OTP+cSuhVS5B1f5j8V/aBH4xBewRNzjMHPVKmIquNDM\n"+ + "HO0oW369atyzkSTKQWI8/AIBvxwWMZQFl3Zuoq29YRdsTjCG8FE3KlDHqGKB3FtK\n"+ + "qsGgtG7rL+VXxbErQHDbWk2hjh+9Ax/YA9SPTJlxvOKCzFjomDqG04Y48wApHwID\n"+ + "AQABMA0GCSqGSIb3DQEBBQUAA4GBAIWMEsGnuVAVess+rLhDityq3RS6iYF+ATwj\n"+ + "cSGIL4LcY/oCRaxFWdcqWERbt5+BO5JoPeI3JPV7bI92NZYJqFmduc4jq3TWg/0y\n"+ + "cyfYaT5DdPauxYma51N86Xv2S/PBZYPejYqcPIiNOVn8qj8ijaHBZlCBckztImRP\n"+ + "T8qAkbYp\n"+ + "-----END CERTIFICATE-----"); + super.addPEMCertificate("GlobalSign Root CA", + // X500 Subject, for lookups. + "MFcxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290"+ + "IENBMRswGQYDVQQDExJHbG9iYWxTaWduIFJvb3QgQ0E=", + "-----BEGIN CERTIFICATE-----\n"+ + "MIIDdTCCAl2gAwIBAgILAgAAAAAA1ni3lAUwDQYJKoZIhvcNAQEEBQAwVzELMAkG\n"+ + "A1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jv\n"+ + "b3QgQ0ExGzAZBgNVBAMTEkdsb2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAw\n"+ + "MDBaFw0xNDAxMjgxMjAwMDBaMFcxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9i\n"+ + "YWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQDExJHbG9iYWxT\n"+ + "aWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDaDuaZ\n"+ + "jc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavp\n"+ + "xy0Sy6scTHAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp\n"+ + "1Wrjsok6Vjk4bwY8iGlbKk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdG\n"+ + "snUOhugZitVtbNV4FpWi6cgKOOvyJBNPc1STE4U6G7weNLWLBYy5d4ux2x8gkasJ\n"+ + "U26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrXgzT/LCrBbBlDSgeF59N8\n"+ + "9iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIABjAdBgNVHQ4EFgQU\n"+ + "YHtmGkUNl8qJUC99BM00qP/8/UswDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0B\n"+ + "AQQFAAOCAQEArqqf/LfSyx9fOSkoGJ40yWxPbxrwZKJwSk8ThptgKJ7ogUmYfQq7\n"+ + "5bCdPTbbjwVR/wkxKh/diXeeDy5slQTthsu0AD+EAk2AaioteAuubyuig0SDH81Q\n"+ + "gkwkr733pbTIWg/050deSY43lv6aiAU62cDbKYfmGZZHpzqmjIs8d/5GY6dT2iHR\n"+ + "rH5Jokvmw2dZL7OKDrssvamqQnw1wdh/1acxOk5jQzmvCLBhNIzTmKlDNPYPhyk7\n"+ + "ncJWWJh3w/cbrPad+D6qp1RF8PX51TFl/mtYnHGzHtdS6jIX/EBgHcl5JLL2bP2o\n"+ + "Zg6C3ZjL2sJETy6ge/L3ayx2EYRGinij4w==\n"+ + "-----END CERTIFICATE-----"); + super.addPEMCertificate("GlobalSign Root CA - R2", + // X500 Subject, for lookups. + "MEwxIDAeBgNVBAsTF0dsb2JhbFNpZ24gUm9vdCBDQSAtIFIyMRMwEQYDVQQKEwpHbG9iYWxTaWdu"+ + "MRMwEQYDVQQDEwpHbG9iYWxTaWdu", + "-----BEGIN CERTIFICATE-----\n"+ + "MIIDujCCAqKgAwIBAgILBAAAAAABD4Ym5g0wDQYJKoZIhvcNAQEFBQAwTDEgMB4G\n"+ + "A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjIxEzARBgNVBAoTCkdsb2JhbFNp\n"+ + "Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDYxMjE1MDgwMDAwWhcNMjExMjE1\n"+ + "MDgwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMjETMBEG\n"+ + "A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI\n"+ + "hvcNAQEBBQADggEPADCCAQoCggEBAKbPJA6+Lm8omUVCxKs+IVSbC9N/hHD6ErPL\n"+ + "v4dfxn+G07IwXNb9rfF73OX4YJYJkhD10FPe+3t+c4isUoh7SqbKSaZeqKeMWhG8\n"+ + "eoLrvozps6yWJQeXSpkqBy+0Hne/ig+1AnwblrjFuTosvNYSuetZfeLQBoZfXklq\n"+ + "tTleiDTsvHgMCJiEbKjNS7SgfQx5TfC4LcshytVsW33hoCmEofnTlEnLJGKRILzd\n"+ + "C9XZzPnqJworc5HGnRusyMvo4KD0L5CLTfuwNhv2GXqF4G3yYROIXJ/gkwpRl4pa\n"+ + "zq+r1feqCapgvdzZX99yqWATXgAByUr6P6TqBwMhAo6CygPCm48CAwEAAaOBnDCB\n"+ + "mTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUm+IH\n"+ + "V2ccHsBqBt5ZtJot39wZhi4wNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL2NybC5n\n"+ + "bG9iYWxzaWduLm5ldC9yb290LXIyLmNybDAfBgNVHSMEGDAWgBSb4gdXZxwewGoG\n"+ + "3lm0mi3f3BmGLjANBgkqhkiG9w0BAQUFAAOCAQEAmYFThxxol4aR7OBKuEQLq4Gs\n"+ + "J0/WwbgcQ3izDJr86iw8bmEbTUsp9Z8FHSbBuOmDAGJFtqkIk7mpM0sYmsL4h4hO\n"+ + "291xNBrBVNpGP+DTKqttVCL1OmLNIG+6KYnX3ZHu01yiPqFbQfXf5WRDLenVOavS\n"+ + "ot+3i9DAgBkcRcAtjOj4LaR0VknFBbVPFd5uRHg5h6h+u/N5GJG79G+dwfCMNYxd\n"+ + "AfvDbbnvRG15RjF+Cv6pgsH/76tuIMRQyV+dTZsXjAzlAcmgQWpzU/qlULRuJQ/7\n"+ + "TBj0/VLZjmmx6BEP3ojY+x1J96relc8geMJgEtslQIxq/H5COEBkEveegeGTLg==\n"+ + "-----END CERTIFICATE-----"); + super.addPEMCertificate("ValiCert Class 1 VA", + // X500 Subject, for lookups. + "MIG7MSQwIgYDVQQHExtWYWxpQ2VydCBWYWxpZGF0aW9uIE5ldHdvcmsxFzAVBgNVBAoTDlZhbGlD"+ + "ZXJ0LCBJbmMuMTUwMwYDVQQLEyxWYWxpQ2VydCBDbGFzcyAxIFBvbGljeSBWYWxpZGF0aW9uIEF1"+ + "dGhvcml0eTEhMB8GA1UEAxMYaHR0cDovL3d3dy52YWxpY2VydC5jb20vMSAwHgYJKoZIhvcNAQkB"+ + "FhFpbmZvQHZhbGljZXJ0LmNvbQ==", + "-----BEGIN CERTIFICATE-----\n"+ + "MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0\n"+ + "IFZhbGlkYXRpb24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAz\n"+ + "BgNVBAsTLFZhbGlDZXJ0IENsYXNzIDEgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9y\n"+ + "aXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG\n"+ + "9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYyNTIyMjM0OFoXDTE5MDYy\n"+ + "NTIyMjM0OFowgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0d29y\n"+ + "azEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENs\n"+ + "YXNzIDEgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRw\n"+ + "Oi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNl\n"+ + "cnQuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDYWYJ6ibiWuqYvaG9Y\n"+ + "LqdUHAZu9OqNSLwxlBfw8068srg1knaw0KWlAdcAAxIiGQj4/xEjm84H9b9pGib+\n"+ + "TunRf50sQB1ZaG6m+FiwnRqP0z/x3BkGgagO4DrdyFNFCQbmD3DD+kCmDuJWBQ8Y\n"+ + "TfwggtFzVXSNdnKgHZ0dwN0/cQIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAFBoPUn0\n"+ + "LBwGlN+VYH+Wexf+T3GtZMjdd9LvWVXoP+iOBSoh8gfStadS/pyxtuJbdxdA6nLW\n"+ + "I8sogTLDAHkY7FkXicnGah5xyf23dKUlRWnFSKsZ4UWKJWsZ7uW7EvV/96aNUcPw\n"+ + "nXS3qT6gpf+2SQMT2iLM7XGCK5nPOrf1LXLI\n"+ + "-----END CERTIFICATE-----"); + super.addPEMCertificate("ValiCert Class 2 VA", + // X500 Subject, for lookups. + "MIG7MSQwIgYDVQQHExtWYWxpQ2VydCBWYWxpZGF0aW9uIE5ldHdvcmsxFzAVBgNVBAoTDlZhbGlD"+ + "ZXJ0LCBJbmMuMTUwMwYDVQQLEyxWYWxpQ2VydCBDbGFzcyAyIFBvbGljeSBWYWxpZGF0aW9uIEF1"+ + "dGhvcml0eTEhMB8GA1UEAxMYaHR0cDovL3d3dy52YWxpY2VydC5jb20vMSAwHgYJKoZIhvcNAQkB"+ + "FhFpbmZvQHZhbGljZXJ0LmNvbQ==", + "-----BEGIN CERTIFICATE-----\n"+ + "MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0\n"+ + "IFZhbGlkYXRpb24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAz\n"+ + "BgNVBAsTLFZhbGlDZXJ0IENsYXNzIDIgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9y\n"+ + "aXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG\n"+ + "9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYyNjAwMTk1NFoXDTE5MDYy\n"+ + "NjAwMTk1NFowgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0d29y\n"+ + "azEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENs\n"+ + "YXNzIDIgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRw\n"+ + "Oi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNl\n"+ + "cnQuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDOOnHK5avIWZJV16vY\n"+ + "dA757tn2VUdZZUcOBVXc65g2PFxTXdMwzzjsvUGJ7SVCCSRrCl6zfN1SLUzm1NZ9\n"+ + "WlmpZdRJEy0kTRxQb7XBhVQ7/nHk01xC+YDgkRoKWzk2Z/M/VXwbP7RfZHM047QS\n"+ + "v4dk+NoS/zcnwbNDu+97bi5p9wIDAQABMA0GCSqGSIb3DQEBBQUAA4GBADt/UG9v\n"+ + "UJSZSWI4OB9L+KXIPqeCgfYrx+jFzug6EILLGACOTb2oWH+heQC1u+mNr0HZDzTu\n"+ + "IYEZoDJJKPTEjlbVUjP9UNV+mWwD5MlM/Mtsq2azSiGM5bUMMj4QssxsodyamEwC\n"+ + "W/POuZ6lcg5Ktz885hZo+L7tdEy8W9ViH0Pd\n"+ + "-----END CERTIFICATE-----"); + super.addPEMCertificate("RSA Root Certificate 1", + // X500 Subject, for lookups. + "MIG7MSQwIgYDVQQHExtWYWxpQ2VydCBWYWxpZGF0aW9uIE5ldHdvcmsxFzAVBgNVBAoTDlZhbGlD"+ + "ZXJ0LCBJbmMuMTUwMwYDVQQLEyxWYWxpQ2VydCBDbGFzcyAzIFBvbGljeSBWYWxpZGF0aW9uIEF1"+ + "dGhvcml0eTEhMB8GA1UEAxMYaHR0cDovL3d3dy52YWxpY2VydC5jb20vMSAwHgYJKoZIhvcNAQkB"+ + "FhFpbmZvQHZhbGljZXJ0LmNvbQ==", + "-----BEGIN CERTIFICATE-----\n"+ + "MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0\n"+ + "IFZhbGlkYXRpb24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAz\n"+ + "BgNVBAsTLFZhbGlDZXJ0IENsYXNzIDMgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9y\n"+ + "aXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG\n"+ + "9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYyNjAwMjIzM1oXDTE5MDYy\n"+ + "NjAwMjIzM1owgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0d29y\n"+ + "azEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENs\n"+ + "YXNzIDMgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRw\n"+ + "Oi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNl\n"+ + "cnQuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDjmFGWHOjVsQaBalfD\n"+ + "cnWTq8+epvzzFlLWLU2fNUSoLgRNB0mKOCn1dzfnt6td3zZxFJmP3MKS8edgkpfs\n"+ + "2Ejcv8ECIMYkpChMMFp2bbFc893enhBxoYjHW5tBbcqwuI4V7q0zK89HBFx1cQqY\n"+ + "JJgpp0lZpd34t0NiYfPT4tBVPwIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAFa7AliE\n"+ + "Zwgs3x/be0kz9dNnnfS0ChCzycUs4pJqcXgn8nCDQtM+z6lU9PHYkhaM0QTLS6vJ\n"+ + "n0WuPIqpsHEzXcjFV9+vqDWzf4mH6eglkrh/hXqu1rweN1gqZ8mRzyqBPu3GOd/A\n"+ + "PhmcGcwTTYJBtYze4D1gCCAPRX5ron+jjBXu\n"+ + "-----END CERTIFICATE-----"); + super.addPEMCertificate("Verisign Class 1 Public Primary Certification Authority - G3", + // X500 Subject, for lookups. + "MIHKMQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlT"+ + "aWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9y"+ + "IGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDEgUHVibGljIFBy"+ + "aW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMw==", + "-----BEGIN CERTIFICATE-----\n"+ + "MIIEGjCCAwICEQCLW3VWhFSFCwDPrzhIzrGkMA0GCSqGSIb3DQEBBQUAMIHKMQsw\n"+ + "CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZl\n"+ + "cmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWdu\n"+ + "LCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlT\n"+ + "aWduIENsYXNzIDEgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3Jp\n"+ + "dHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQswCQYD\n"+ + "VQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlT\n"+ + "aWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJ\n"+ + "bmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWdu\n"+ + "IENsYXNzIDEgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg\n"+ + "LSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAN2E1Lm0+afY8wR4\n"+ + "nN493GwTFtl63SRRZsDHJlkNrAYIwpTRMx/wgzUfbhvI3qpuFU5UJ+/EbRrsC+MO\n"+ + "8ESlV8dAWB6jRx9x7GD2bZTIGDnt/kIYVt/kTEkQeE4BdjVjEjbdZrwBBDajVWjV\n"+ + "ojYJrKshJlQGrT/KFOCsyq0GHZXi+J3x4GD/wn91K0zM2v6HmSHquv4+VNfSWXjb\n"+ + "PG7PoBMAGrgnoeS+Z5bKoMWznN3JdZ7rMJpfo83ZrngZPyPpXNspva1VyBtUjGP2\n"+ + "6KbqxzcSXKMpHgLZ2x87tNcPVkeBFQRKr4Mn0cVYiMHd9qqnoxjaaKptEVHhv2Vr\n"+ + "n5Z20T0CAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAq2aN17O6x5q25lXQBfGfMY1a\n"+ + "qtmqRiYPce2lrVNWYgFHKkTp/j90CxObufRNG7LRX7K20ohcs5/Ny9Sn2WCVhDr4\n"+ + "wTcdYcrnsMXlkdpUpqwxga6X3s0IrLjAl4B/bnKk52kTlWUfxJM8/XmPBNQ+T+r3\n"+ + "ns7NZ3xPZQL/kYVUc8f/NveGLezQXk//EZ9yBta4GvFMDSZl4kSAHsef493oCtrs\n"+ + "pSCAaWihT37ha88HQfqDjrw43bAuEbFrskLMmrz5SCJ5ShkPshw+IHTZasO+8ih4\n"+ + "E1Z5T21Q6huwtVexN2ZYI/PcD98Kh8TvhgXVOBRgmaNL3gaWcSzy27YfpO8/7g==\n"+ + "-----END CERTIFICATE-----"); + super.addPEMCertificate("Verisign Class 2 Public Primary Certification Authority - G3", + // X500 Subject, for lookups. + "MIHKMQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlT"+ + "aWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9y"+ + "IGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDIgUHVibGljIFBy"+ + "aW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMw==", + "-----BEGIN CERTIFICATE-----\n"+ + "MIIEGTCCAwECEGFwy0mMX5hFKeewptlQW3owDQYJKoZIhvcNAQEFBQAwgcoxCzAJ\n"+ + "BgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjEfMB0GA1UECxMWVmVy\n"+ + "aVNpZ24gVHJ1c3QgTmV0d29yazE6MDgGA1UECxMxKGMpIDE5OTkgVmVyaVNpZ24s\n"+ + "IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTFFMEMGA1UEAxM8VmVyaVNp\n"+ + "Z24gQ2xhc3MgMiBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0\n"+ + "eSAtIEczMB4XDTk5MTAwMTAwMDAwMFoXDTM2MDcxNjIzNTk1OVowgcoxCzAJBgNV\n"+ + "BAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjEfMB0GA1UECxMWVmVyaVNp\n"+ + "Z24gVHJ1c3QgTmV0d29yazE6MDgGA1UECxMxKGMpIDE5OTkgVmVyaVNpZ24sIElu\n"+ + "Yy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTFFMEMGA1UEAxM8VmVyaVNpZ24g\n"+ + "Q2xhc3MgMiBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAt\n"+ + "IEczMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArwoNwtUs22e5LeWU\n"+ + "J92lvuCwTY+zYVY81nzD9M0+hsuiiOLh2KRpxbXiv8GmR1BeRjmL1Za6tW8UvxDO\n"+ + "JxOeBUebMXoT2B/Z0wI3i60sR/COgQanDTAM6/c8DyAd3HJG7qUCyFvDyVZpTMUY\n"+ + "wZF7C9UTAJu878NIPkZgIIUq1ZC2zYugzDLdt/1AVbJQHFauzI13TccgTacxdu9o\n"+ + "koqQHgiBVrKtaaNS0MscxCM9H5n+TOgWY47GCI72MfbS+uV23bUckqNJzc0BzWjN\n"+ + "qWm6o+sdDZykIKbBoMXRRkwXbdKsZj+WjOCE1Db/IlnF+RFgqF8EffIa9iVCYQ/E\n"+ + "Srg+iQIDAQABMA0GCSqGSIb3DQEBBQUAA4IBAQA0JhU8wI1NQ0kdvekhktdmnLfe\n"+ + "xbjQ5F1fdiLAJvmEOjr5jLX77GDx6M4EsMjdpwOPMPOY36TmpDHf0xwLRtxyID+u\n"+ + "7gU8pDM/CzmscHhzS5kr3zDCVLCoO1Wh/hYozUK9dG6A2ydEp85EXdQbkJgNHkKU\n"+ + "sQAsBNB0owIFImNjzYO1+8FtYmtpdf1dcEG59b98377BMnMiIYtYgXsVkXq642RI\n"+ + "sH/7NiXaldDxJBQX3RiAa0YjOVT1jmIJBB2UkKab5iXiQkWquJCtvgiPqQtCGJTP\n"+ + "cjnhsUPgKM+351psE2tJs//jGHyJizNdrDPXp/naOlXJWBD5qu9ats9LS98q\n"+ + "-----END CERTIFICATE-----"); + super.addPEMCertificate("Verisign Class 3 Public Primary Certification Authority - G3", + // X500 Subject, for lookups. + "MIHKMQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlT"+ + "aWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9y"+ + "IGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDMgUHVibGljIFBy"+ + "aW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMw==", + "-----BEGIN CERTIFICATE-----\n"+ + "MIIEGjCCAwICEQCbfgZJoz5iudXukEhxKe9XMA0GCSqGSIb3DQEBBQUAMIHKMQsw\n"+ + "CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZl\n"+ + "cmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWdu\n"+ + "LCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlT\n"+ + "aWduIENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3Jp\n"+ + "dHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQswCQYD\n"+ + "VQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlT\n"+ + "aWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJ\n"+ + "bmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWdu\n"+ + "IENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg\n"+ + "LSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMu6nFL8eB8aHm8b\n"+ + "N3O9+MlrlBIwT/A2R/XQkQr1F8ilYcEWQE37imGQ5XYgwREGfassbqb1EUGO+i2t\n"+ + "KmFZpGcmTNDovFJbcCAEWNF6yaRpvIMXZK0Fi7zQWM6NjPXr8EJJC52XJ2cybuGu\n"+ + "kxUccLwgTS8Y3pKI6GyFVxEa6X7jJhFUokWWVYPKMIno3Nij7SqAP395ZVc+FSBm\n"+ + "CC+Vk7+qRy+oRpfwEuL+wgorUeZ25rdGt+INpsyow0xZVYnm6FNcHOqd8GIWC6fJ\n"+ + "Xwzw3sJ2zq/3avL6QaaiMxTJ5Xpj055iN9WFZZ4O5lMkdBteHRJTW8cs54NJOxWu\n"+ + "imi5V5cCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAERSWwauSCPc/L8my/uRan2Te\n"+ + "2yFPhpk0djZX3dAVL8WtfxUfN2JzPtTnX84XA9s1+ivbrmAJXx5fj267Cz3qWhMe\n"+ + "DGBvtcC1IyIuBwvLqXTLR7sdwdela8wv0kL9Sd2nic9TutoAWii/gt/4uhMdUIaC\n"+ + "/Y4wjylGsB49Ndo4YhYYSq3mtlFs3q9i6wHQHiT+eo8SGhJouPtmmRQURVyu565p\n"+ + "F4ErWjfJXir0xuKhXFSbplQAz/DxwceYMBo7Nhbbo27q/a2ywtrvAkcTisDxszGt\n"+ + "TxzhT5yvDwyd93gN2PQ1VoDat20Xj50egWTh/sVFuq1ruQp6Tk9LhO5L8X3dEQ==\n"+ + "-----END CERTIFICATE-----"); + super.addPEMCertificate("Verisign Class 4 Public Primary Certification Authority - G3", + // X500 Subject, for lookups. + "MIHKMQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlT"+ + "aWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9y"+ + "IGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDQgUHVibGljIFBy"+ + "aW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMw==", + "-----BEGIN CERTIFICATE-----\n"+ + "MIIEGjCCAwICEQDsoKeLbnVqAc/EfMwvlF7XMA0GCSqGSIb3DQEBBQUAMIHKMQsw\n"+ + "CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZl\n"+ + "cmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWdu\n"+ + "LCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlT\n"+ + "aWduIENsYXNzIDQgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3Jp\n"+ + "dHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQswCQYD\n"+ + "VQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlT\n"+ + "aWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJ\n"+ + "bmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWdu\n"+ + "IENsYXNzIDQgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg\n"+ + "LSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAK3LpRFpxlmr8Y+1\n"+ + "GQ9Wzsy1HyDkniYlS+BzZYlZ3tCD5PUPtbut8XzoIfzk6AzufEUiGXaStBO3IFsJ\n"+ + "+mGuqPKljYXCKtbeZjbSmwL0qJJgfJxptI8kHtCGUvYynEFYHiK9zUVilQhu0Gbd\n"+ + "U6LM8BDcVHOLBKFGMzNcF0C5nk3T875Vg+ixiY5afJqWIpA7iCXy0lOIAgwLePLm\n"+ + "NxdLMEYH5IBtptiWLugs+BGzOA1mppvqySNb247i8xOOGlktqgLw7KSHZtzBP/XY\n"+ + "ufTsgsbSPZUd5cBPhMnZo0QoBmrXRazwa2rvTl/4EYIeOGM0ZlDUPpNz+jDDZq3/\n"+ + "ky2X7wMCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAj/ola09b5KROJ1WrIhVZPMq1\n"+ + "CtRK26vdoV9TxaBXOcLORyu+OshWv8LZJxA6sQU8wHcxuzrTBXttmhwwjIDLk5Mq\n"+ + "g6sFUYICABFna/OIYUdfA5PVWw3g8dShMjWFsjrbsIKr0csKvE+MW8VLADsfKoKm\n"+ + "fjaF3H48ZwC15DtS4KjrXRX5xm3wrR0OhbepmnMUWluPQSjA1egtTaRezarZ7c7c\n"+ + "2NU8Qh0XwRJdRTjDOPP8hS6DRkiy1yBfkjaP53kPmF6Z6PDQpLv1U70qzlmwr25/\n"+ + "bLvSHgCwIe34QWKCudiyxLtGUPMxxY8BqHTr9Xgn2uf3ZkPznoM+IKrDNWCRzg==\n"+ + "-----END CERTIFICATE-----"); + super.addPEMCertificate("Entrust.net Secure Server CA", + // X500 Subject, for lookups. + "MIHDMQswCQYDVQQGEwJVUzEUMBIGA1UEChMLRW50cnVzdC5uZXQxOzA5BgNVBAsTMnd3dy5lbnRy"+ + "dXN0Lm5ldC9DUFMgaW5jb3JwLiBieSByZWYuIChsaW1pdHMgbGlhYi4pMSUwIwYDVQQLExwoYykg"+ + "MTk5OSBFbnRydXN0Lm5ldCBMaW1pdGVkMTowOAYDVQQDEzFFbnRydXN0Lm5ldCBTZWN1cmUgU2Vy"+ + "dmVyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5", + "-----BEGIN CERTIFICATE-----\n"+ + "MIIE2DCCBEGgAwIBAgIEN0rSQzANBgkqhkiG9w0BAQUFADCBwzELMAkGA1UEBhMC\n"+ + "VVMxFDASBgNVBAoTC0VudHJ1c3QubmV0MTswOQYDVQQLEzJ3d3cuZW50cnVzdC5u\n"+ + "ZXQvQ1BTIGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxpYWIuKTElMCMGA1UECxMc\n"+ + "KGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDE6MDgGA1UEAxMxRW50cnVzdC5u\n"+ + "ZXQgU2VjdXJlIFNlcnZlciBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw05OTA1\n"+ + "MjUxNjA5NDBaFw0xOTA1MjUxNjM5NDBaMIHDMQswCQYDVQQGEwJVUzEUMBIGA1UE\n"+ + "ChMLRW50cnVzdC5uZXQxOzA5BgNVBAsTMnd3dy5lbnRydXN0Lm5ldC9DUFMgaW5j\n"+ + "b3JwLiBieSByZWYuIChsaW1pdHMgbGlhYi4pMSUwIwYDVQQLExwoYykgMTk5OSBF\n"+ + "bnRydXN0Lm5ldCBMaW1pdGVkMTowOAYDVQQDEzFFbnRydXN0Lm5ldCBTZWN1cmUg\n"+ + "U2VydmVyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGdMA0GCSqGSIb3DQEBAQUA\n"+ + "A4GLADCBhwKBgQDNKIM0VBuJ8w+vN5Ex/68xYMmo6LIQaO2f55M28Qpku0f1BBc/\n"+ + "I0dNxScZgSYMVHINiC3ZH5oSn7yzcdOAGT9HZnuMNSjSuQrfJNqc1lB5gXpa0zf3\n"+ + "wkrYKZImZNHkmGw6AIr1NJtl+O3jEP/9uElY3KDegjlrgbEWGWG5VLbmQwIBA6OC\n"+ + "AdcwggHTMBEGCWCGSAGG+EIBAQQEAwIABzCCARkGA1UdHwSCARAwggEMMIHeoIHb\n"+ + "oIHYpIHVMIHSMQswCQYDVQQGEwJVUzEUMBIGA1UEChMLRW50cnVzdC5uZXQxOzA5\n"+ + "BgNVBAsTMnd3dy5lbnRydXN0Lm5ldC9DUFMgaW5jb3JwLiBieSByZWYuIChsaW1p\n"+ + "dHMgbGlhYi4pMSUwIwYDVQQLExwoYykgMTk5OSBFbnRydXN0Lm5ldCBMaW1pdGVk\n"+ + "MTowOAYDVQQDEzFFbnRydXN0Lm5ldCBTZWN1cmUgU2VydmVyIENlcnRpZmljYXRp\n"+ + "b24gQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMCmgJ6AlhiNodHRwOi8vd3d3LmVu\n"+ + "dHJ1c3QubmV0L0NSTC9uZXQxLmNybDArBgNVHRAEJDAigA8xOTk5MDUyNTE2MDk0\n"+ + "MFqBDzIwMTkwNTI1MTYwOTQwWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAU8Bdi\n"+ + "E1U9s/8KAGv7UISX8+1i0BowHQYDVR0OBBYEFPAXYhNVPbP/CgBr+1CEl/PtYtAa\n"+ + "MAwGA1UdEwQFMAMBAf8wGQYJKoZIhvZ9B0EABAwwChsEVjQuMAMCBJAwDQYJKoZI\n"+ + "hvcNAQEFBQADgYEAkNwwAvpkdMKnCqV8IY00F6j7Rw7/JXyNEwr75Ji174z4xRAN\n"+ + "95K+8cPV1ZVqBLssziY2ZcgxxufuP+NXdYR6Ee9GTxj005i7qIcyunL2POI9n9cd\n"+ + "2cNgQ4xYDiKWL2KjLB+6rQXvqzJ4h6BUcxm1XAX5Uj5tLUUL9wqT6u0G+bI=\n"+ + "-----END CERTIFICATE-----"); + super.addPEMCertificate("Entrust.net Secure Personal CA", + // X500 Subject, for lookups. + "MIHJMQswCQYDVQQGEwJVUzEUMBIGA1UEChMLRW50cnVzdC5uZXQxSDBGBgNVBAsUP3d3dy5lbnRy"+ + "dXN0Lm5ldC9DbGllbnRfQ0FfSW5mby9DUFMgaW5jb3JwLiBieSByZWYuIGxpbWl0cyBsaWFiLjEl"+ + "MCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEGA1UEAxMqRW50cnVzdC5u"+ + "ZXQgQ2xpZW50IENlcnRpZmljYXRpb24gQXV0aG9yaXR5", + "-----BEGIN CERTIFICATE-----\n"+ + "MIIE7TCCBFagAwIBAgIEOAOR7jANBgkqhkiG9w0BAQQFADCByTELMAkGA1UEBhMC\n"+ + "VVMxFDASBgNVBAoTC0VudHJ1c3QubmV0MUgwRgYDVQQLFD93d3cuZW50cnVzdC5u\n"+ + "ZXQvQ2xpZW50X0NBX0luZm8vQ1BTIGluY29ycC4gYnkgcmVmLiBsaW1pdHMgbGlh\n"+ + "Yi4xJTAjBgNVBAsTHChjKSAxOTk5IEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNV\n"+ + "BAMTKkVudHJ1c3QubmV0IENsaWVudCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAe\n"+ + "Fw05OTEwMTIxOTI0MzBaFw0xOTEwMTIxOTU0MzBaMIHJMQswCQYDVQQGEwJVUzEU\n"+ + "MBIGA1UEChMLRW50cnVzdC5uZXQxSDBGBgNVBAsUP3d3dy5lbnRydXN0Lm5ldC9D\n"+ + "bGllbnRfQ0FfSW5mby9DUFMgaW5jb3JwLiBieSByZWYuIGxpbWl0cyBsaWFiLjEl\n"+ + "MCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEGA1UEAxMq\n"+ + "RW50cnVzdC5uZXQgQ2xpZW50IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGdMA0G\n"+ + "CSqGSIb3DQEBAQUAA4GLADCBhwKBgQDIOpleMRffrCdvkHvkGf9FozTC28GoT/Bo\n"+ + "6oT9n3V5z8GKUZSvx1cDR2SerYIbWtp/N3hHuzeYEpbOxhN979IMMFGpOZ5V+Pux\n"+ + "5zDeg7K6PvHViTs7hbqqdCz+PzFur5GVbgbUB01LLFZHGARS2g4Qk79jkJvh34zm\n"+ + "AqTmT173iwIBA6OCAeAwggHcMBEGCWCGSAGG+EIBAQQEAwIABzCCASIGA1UdHwSC\n"+ + "ARkwggEVMIHkoIHhoIHepIHbMIHYMQswCQYDVQQGEwJVUzEUMBIGA1UEChMLRW50\n"+ + "cnVzdC5uZXQxSDBGBgNVBAsUP3d3dy5lbnRydXN0Lm5ldC9DbGllbnRfQ0FfSW5m\n"+ + "by9DUFMgaW5jb3JwLiBieSByZWYuIGxpbWl0cyBsaWFiLjElMCMGA1UECxMcKGMp\n"+ + "IDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEGA1UEAxMqRW50cnVzdC5uZXQg\n"+ + "Q2xpZW50IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMCyg\n"+ + "KqAohiZodHRwOi8vd3d3LmVudHJ1c3QubmV0L0NSTC9DbGllbnQxLmNybDArBgNV\n"+ + "HRAEJDAigA8xOTk5MTAxMjE5MjQzMFqBDzIwMTkxMDEyMTkyNDMwWjALBgNVHQ8E\n"+ + "BAMCAQYwHwYDVR0jBBgwFoAUxPucKXuXzUyW/O5bs8qZdIuV6kwwHQYDVR0OBBYE\n"+ + "FMT7nCl7l81MlvzuW7PKmXSLlepMMAwGA1UdEwQFMAMBAf8wGQYJKoZIhvZ9B0EA\n"+ + "BAwwChsEVjQuMAMCBJAwDQYJKoZIhvcNAQEEBQADgYEAP66K8ddmAwWePvrqHEa7\n"+ + "pFuPeJoSSJn59DXeDDYHAmsQOokUgZwxpnyyQbJq5wcBoUv5nyU7lsqZwz6hURzz\n"+ + "wy5E97BnRqqS5TvaHBkUODDV4qIxJS7x7EU47fgGWANzYrAQMY9Av2TgXD7FTx/a\n"+ + "EkP/TOYGJqibGapEPHayXOw=\n"+ + "-----END CERTIFICATE-----"); + super.addPEMCertificate("Entrust.net Premium 2048 Secure Server CA", + // X500 Subject, for lookups. + "MIG0MRQwEgYDVQQKEwtFbnRydXN0Lm5ldDFAMD4GA1UECxQ3d3d3LmVudHJ1c3QubmV0L0NQU18y"+ + "MDQ4IGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxpYWIuKTElMCMGA1UECxMcKGMpIDE5OTkgRW50"+ + "cnVzdC5uZXQgTGltaXRlZDEzMDEGA1UEAxMqRW50cnVzdC5uZXQgQ2VydGlmaWNhdGlvbiBBdXRo"+ + "b3JpdHkgKDIwNDgp", + "-----BEGIN CERTIFICATE-----\n"+ + "MIIEXDCCA0SgAwIBAgIEOGO5ZjANBgkqhkiG9w0BAQUFADCBtDEUMBIGA1UEChML\n"+ + "RW50cnVzdC5uZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9DUFNfMjA0OCBp\n"+ + "bmNvcnAuIGJ5IHJlZi4gKGxpbWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAxOTk5\n"+ + "IEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNVBAMTKkVudHJ1c3QubmV0IENlcnRp\n"+ + "ZmljYXRpb24gQXV0aG9yaXR5ICgyMDQ4KTAeFw05OTEyMjQxNzUwNTFaFw0xOTEy\n"+ + "MjQxODIwNTFaMIG0MRQwEgYDVQQKEwtFbnRydXN0Lm5ldDFAMD4GA1UECxQ3d3d3\n"+ + "LmVudHJ1c3QubmV0L0NQU18yMDQ4IGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxp\n"+ + "YWIuKTElMCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEG\n"+ + "A1UEAxMqRW50cnVzdC5uZXQgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgKDIwNDgp\n"+ + "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArU1LqRKGsuqjIAcVFmQq\n"+ + "K0vRvwtKTY7tgHalZ7d4QMBzQshowNtTK91euHaYNZOLGp18EzoOH1u3Hs/lJBQe\n"+ + "sYGpjX24zGtLA/ECDNyrpUAkAH90lKGdCCmziAv1h3edVc3kw37XamSrhRSGlVuX\n"+ + "MlBvPci6Zgzj/L24ScF2iUkZ/cCovYmjZy/Gn7xxGWC4LeksyZB2ZnuU4q941mVT\n"+ + "XTzWnLLPKQP5L6RQstRIzgUyVYr9smRMDuSYB3Xbf9+5CFVghTAp+XtIpGmG4zU/\n"+ + "HoZdenoVve8AjhUiVBcAkCaTvA5JaJG/+EfTnZVCwQ5N328mz8MYIWJmQ3DW1cAH\n"+ + "4QIDAQABo3QwcjARBglghkgBhvhCAQEEBAMCAAcwHwYDVR0jBBgwFoAUVeSB0RGA\n"+ + "vtiJuQijMfmhJAkWuXAwHQYDVR0OBBYEFFXkgdERgL7YibkIozH5oSQJFrlwMB0G\n"+ + "CSqGSIb2fQdBAAQQMA4bCFY1LjA6NC4wAwIEkDANBgkqhkiG9w0BAQUFAAOCAQEA\n"+ + "WUesIYSKF8mciVMeuoCFGsY8Tj6xnLZ8xpJdGGQC49MGCBFhfGPjK50xA3B20qMo\n"+ + "oPS7mmNz7W3lKtvtFKkrxjYR0CvrB4ul2p5cGZ1WEvVUKcgF7bISKo30Axv/55IQ\n"+ + "h7A6tcOdBTcSo8f0FbnVpDkWm1M6I5HxqIKiaohowXkCIryqptau37AUX7iH0N18\n"+ + "f3v/rxzP5tsHrV7bhZ3QKw0z2wTR5klAEyt2+z7pnIkPFc4YsIV4IU9rTw76NmfN\n"+ + "B/L/CNDi3tm/Kq+4h4YhPATKt5Rof8886ZjXOP/swNlQ8C5LWK5Gb9Auw2DaclVy\n"+ + "vUxFnmG6v4SBkgPR0ml8xQ==\n"+ + "-----END CERTIFICATE-----"); + super.addPEMCertificate("Baltimore CyberTrust Root", + // X500 Subject, for lookups. + "MFoxCzAJBgNVBAYTAklFMRIwEAYDVQQKEwlCYWx0aW1vcmUxEzARBgNVBAsTCkN5YmVyVHJ1c3Qx"+ + "IjAgBgNVBAMTGUJhbHRpbW9yZSBDeWJlclRydXN0IFJvb3Q=", + "-----BEGIN CERTIFICATE-----\n"+ + "MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJ\n"+ + "RTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYD\n"+ + "VQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoX\n"+ + "DTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMCSUUxEjAQBgNVBAoTCUJhbHRpbW9y\n"+ + "ZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFsdGltb3JlIEN5YmVy\n"+ + "VHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKMEuyKr\n"+ + "mD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjr\n"+ + "IZ3AQSsBUnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeK\n"+ + "mpYcqWe4PwzV9/lSEy/CG9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSu\n"+ + "XmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9XbIGevOF6uvUA65ehD5f/xXtabz5OTZy\n"+ + "dc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjprl3RjM71oGDHweI12v/ye\n"+ + "jl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoIVDaGezq1\n"+ + "BE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3\n"+ + "DQEBBQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT92\n"+ + "9hkTI7gQCvlYpNRhcL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3Wgx\n"+ + "jkzSswF07r51XgdIGn9w/xZchMB5hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0\n"+ + "Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsaY71k5h+3zvDyny67G7fyUIhz\n"+ + "ksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9HRCwBXbsdtTLS\n"+ + "R9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp\n"+ + "-----END CERTIFICATE-----"); + super.addPEMCertificate("Equifax Secure Global eBusiness CA", + // X500 Subject, for lookups. + "MFoxCzAJBgNVBAYTAlVTMRwwGgYDVQQKExNFcXVpZmF4IFNlY3VyZSBJbmMuMS0wKwYDVQQDEyRF"+ + "cXVpZmF4IFNlY3VyZSBHbG9iYWwgZUJ1c2luZXNzIENBLTE=", + "-----BEGIN CERTIFICATE-----\n"+ + "MIICkDCCAfmgAwIBAgIBATANBgkqhkiG9w0BAQQFADBaMQswCQYDVQQGEwJVUzEc\n"+ + "MBoGA1UEChMTRXF1aWZheCBTZWN1cmUgSW5jLjEtMCsGA1UEAxMkRXF1aWZheCBT\n"+ + "ZWN1cmUgR2xvYmFsIGVCdXNpbmVzcyBDQS0xMB4XDTk5MDYyMTA0MDAwMFoXDTIw\n"+ + "MDYyMTA0MDAwMFowWjELMAkGA1UEBhMCVVMxHDAaBgNVBAoTE0VxdWlmYXggU2Vj\n"+ + "dXJlIEluYy4xLTArBgNVBAMTJEVxdWlmYXggU2VjdXJlIEdsb2JhbCBlQnVzaW5l\n"+ + "c3MgQ0EtMTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAuucXkAJlsTRVPEnC\n"+ + "UdXfp9E3j9HngXNBUmCbnaEXJnitx7HoJpQytd4zjTov2/KaelpzmKNc6fuKcxtc\n"+ + "58O/gGzNqfTWK8D3+ZmqY6KxRwIP1ORROhI8bIpaVIRw28HFkM9yRcuoWcDNM50/\n"+ + "o5brhTMhHD4ePmBudpxnhcXIw2ECAwEAAaNmMGQwEQYJYIZIAYb4QgEBBAQDAgAH\n"+ + "MA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUvqigdHJQa0S3ySPY+6j/s1dr\n"+ + "aGwwHQYDVR0OBBYEFL6ooHRyUGtEt8kj2Puo/7NXa2hsMA0GCSqGSIb3DQEBBAUA\n"+ + "A4GBADDiAVGqx+pf2rnQZQ8w1j7aDRRJbpGTJxQx78T3LUX47Me/okENI7SS+RkA\n"+ + "Z70Br83gcfxaz2TE4JaY0KNA4gGK7ycH8WUBikQtBmV1UsCGECAhX2xrD2yuCRyv\n"+ + "8qIYNMR1pHMc8Y3c7635s3a0kr/clRAevsvIO1qEYBlWlKlV\n"+ + "-----END CERTIFICATE-----"); + super.addPEMCertificate("Equifax Secure eBusiness CA 1", + // X500 Subject, for lookups. + "MFMxCzAJBgNVBAYTAlVTMRwwGgYDVQQKExNFcXVpZmF4IFNlY3VyZSBJbmMuMSYwJAYDVQQDEx1F"+ + "cXVpZmF4IFNlY3VyZSBlQnVzaW5lc3MgQ0EtMQ==", + "-----BEGIN CERTIFICATE-----\n"+ + "MIICgjCCAeugAwIBAgIBBDANBgkqhkiG9w0BAQQFADBTMQswCQYDVQQGEwJVUzEc\n"+ + "MBoGA1UEChMTRXF1aWZheCBTZWN1cmUgSW5jLjEmMCQGA1UEAxMdRXF1aWZheCBT\n"+ + "ZWN1cmUgZUJ1c2luZXNzIENBLTEwHhcNOTkwNjIxMDQwMDAwWhcNMjAwNjIxMDQw\n"+ + "MDAwWjBTMQswCQYDVQQGEwJVUzEcMBoGA1UEChMTRXF1aWZheCBTZWN1cmUgSW5j\n"+ + "LjEmMCQGA1UEAxMdRXF1aWZheCBTZWN1cmUgZUJ1c2luZXNzIENBLTEwgZ8wDQYJ\n"+ + "KoZIhvcNAQEBBQADgY0AMIGJAoGBAM4vGbwXt3fek6lfWg0XTzQaDJj0ItlZ1MRo\n"+ + "RvC0NcWFAyDGr0WlIVFFQesWWDYyb+JQYmT5/VGcqiTZ9J2DKocKIdMSODRsjQBu\n"+ + "WqDZQu4aIZX5UkxVWsUPOE9G+m34LjXWHXzr4vCwdYDIqROsvojvOm6rXyo4YgKw\n"+ + "Env+j6YDAgMBAAGjZjBkMBEGCWCGSAGG+EIBAQQEAwIABzAPBgNVHRMBAf8EBTAD\n"+ + "AQH/MB8GA1UdIwQYMBaAFEp4MlIR21kWNl7fwRQ2QGpHfEyhMB0GA1UdDgQWBBRK\n"+ + "eDJSEdtZFjZe38EUNkBqR3xMoTANBgkqhkiG9w0BAQQFAAOBgQB1W6ibAxHm6VZM\n"+ + "zfmpTMANmvPMZWnmJXbMWbfWVMMdzZmsGd20hdXgPfxiIKeES1hl8eL5lSE/9dR+\n"+ + "WB5Hh1Q+WKG1tfgq73HnvMP2sUlG4tega+VWeponmHxGYhTnyfxuAxJ5gDgdSIKN\n"+ + "/Bf+KpYrtWKmpj29f5JZzVoqgrI3eQ==\n"+ + "-----END CERTIFICATE-----"); + super.addPEMCertificate("Equifax Secure eBusiness CA 2", + // X500 Subject, for lookups. + "ME4xCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5FcXVpZmF4IFNlY3VyZTEmMCQGA1UECxMdRXF1aWZh"+ + "eCBTZWN1cmUgZUJ1c2luZXNzIENBLTI=", + "-----BEGIN CERTIFICATE-----\n"+ + "MIIDIDCCAomgAwIBAgIEN3DPtTANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQGEwJV\n"+ + "UzEXMBUGA1UEChMORXF1aWZheCBTZWN1cmUxJjAkBgNVBAsTHUVxdWlmYXggU2Vj\n"+ + "dXJlIGVCdXNpbmVzcyBDQS0yMB4XDTk5MDYyMzEyMTQ0NVoXDTE5MDYyMzEyMTQ0\n"+ + "NVowTjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDkVxdWlmYXggU2VjdXJlMSYwJAYD\n"+ + "VQQLEx1FcXVpZmF4IFNlY3VyZSBlQnVzaW5lc3MgQ0EtMjCBnzANBgkqhkiG9w0B\n"+ + "AQEFAAOBjQAwgYkCgYEA5Dk5kx5SBhsoNviyoynF7Y6yEb3+6+e0dMKP/wXn2Z0G\n"+ + "vxLIPw7y1tEkshHe0XMJitSxLJgJDR5QRrKDpkWNYmi7hRsgcDKqQM2mll/EcTc/\n"+ + "BPO3QSQ5BxoeLmFYoBIL5aXfxavqN3HMHMg3OrmXUqesxWoklE6ce8/AatbfIb0C\n"+ + "AwEAAaOCAQkwggEFMHAGA1UdHwRpMGcwZaBjoGGkXzBdMQswCQYDVQQGEwJVUzEX\n"+ + "MBUGA1UEChMORXF1aWZheCBTZWN1cmUxJjAkBgNVBAsTHUVxdWlmYXggU2VjdXJl\n"+ + "IGVCdXNpbmVzcyBDQS0yMQ0wCwYDVQQDEwRDUkwxMBoGA1UdEAQTMBGBDzIwMTkw\n"+ + "NjIzMTIxNDQ1WjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUUJ4L6q9euSBIplBq\n"+ + "y/3YIHqngnYwHQYDVR0OBBYEFFCeC+qvXrkgSKZQasv92CB6p4J2MAwGA1UdEwQF\n"+ + "MAMBAf8wGgYJKoZIhvZ9B0EABA0wCxsFVjMuMGMDAgbAMA0GCSqGSIb3DQEBBQUA\n"+ + "A4GBAAyGgq3oThr1jokn4jVYPSm0B482UJW/bsGe68SQsoWou7dC4A8HOd/7npCy\n"+ + "0cE+U58DRLB+S/Rv5Hwf5+Kx5Lia78O9zt4LMjTZ3ijtM2vE1Nc9ElirfQkty3D1\n"+ + "E4qUoSek1nDFbZS1yX2doNLGCEnZZpum0/QL3MUmV+GRMOrN\n"+ + "-----END CERTIFICATE-----"); + super.addPEMCertificate("Visa International Global Root 2", + // X500 Subject, for lookups. + "MGExCzAJBgNVBAYTAlVTMQ0wCwYDVQQKEwRWSVNBMS8wLQYDVQQLEyZWaXNhIEludGVybmF0aW9u"+ + "YWwgU2VydmljZSBBc3NvY2lhdGlvbjESMBAGA1UEAxMJR1AgUm9vdCAy", + "-----BEGIN CERTIFICATE-----\n"+ + "MIIDgDCCAmigAwIBAgICAx4wDQYJKoZIhvcNAQEFBQAwYTELMAkGA1UEBhMCVVMx\n"+ + "DTALBgNVBAoTBFZJU0ExLzAtBgNVBAsTJlZpc2EgSW50ZXJuYXRpb25hbCBTZXJ2\n"+ + "aWNlIEFzc29jaWF0aW9uMRIwEAYDVQQDEwlHUCBSb290IDIwHhcNMDAwODE2MjI1\n"+ + "MTAwWhcNMjAwODE1MjM1OTAwWjBhMQswCQYDVQQGEwJVUzENMAsGA1UEChMEVklT\n"+ + "QTEvMC0GA1UECxMmVmlzYSBJbnRlcm5hdGlvbmFsIFNlcnZpY2UgQXNzb2NpYXRp\n"+ + "b24xEjAQBgNVBAMTCUdQIFJvb3QgMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC\n"+ + "AQoCggEBAKkBcLWqxEDwq2omYXkZAPy/mzdZDK9vZBv42pWUJGkzEXDK41Z0ohdX\n"+ + "ZFwgBuHW73G3O/erwWnQSaSxBNf0V2KJXLB1LRckaeNCYOTudNargFbYiCjh+20i\n"+ + "/SN8RnNPflRzHqgsVVh1t0zzWkWlAhr62p3DRcMiXvOL8WAp0sdftAw6UYPvMPjU\n"+ + "58fy+pmjIlC++QU3o63tmsPm7IgbthknGziLgE3sucfFicv8GjLtI/C1AVj59o/g\n"+ + "halMCXI5Etuz9c9OYmTaxhkVOmMd6RdVoUwiPDQyRvhlV7or7zaMavrZ2UT0qt2E\n"+ + "1w0cslSsMoW0ZA3eQbuxNMYBhjJk1Z8CAwEAAaNCMEAwHQYDVR0OBBYEFJ59SzS/\n"+ + "ca3CBfYDdYDOqU8axCRMMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEG\n"+ + "MA0GCSqGSIb3DQEBBQUAA4IBAQAhpXYUVfmtJ3CPPPTVbMjMCqujmAuKBiPFyWHb\n"+ + "mQdpNSYx/scuhMKZYdQN6X0uEyt8joW2hcdLzzW2LEc9zikv2G+fiRxkk78IvXbQ\n"+ + "kIqUs38oW26sTTMs7WXcFsziza6kPWKSBpUmv9+55CCmc2rBvveURNZNbyoLaxhN\n"+ + "dBA2aGpawWqn3TYpjLgwi08hPwAuVDAHOrqK5MOeyti12HvOdUVmB/RtLdh6yumJ\n"+ + "ivIj2C/LbgA2T/vwLwHMD8AiZfSr4k5hLQOCfZEWtTDVFN5ex5D8ofyrEK9ca3Cn\n"+ + "B+8phuiyJccg/ybdd+95RBTEvd07xQObdyPsoOy7Wjm1zK0G\n"+ + "-----END CERTIFICATE-----"); + super.addPEMCertificate("beTRUSTed Root CA", + // X500 Subject, for lookups. + "MFoxCzAJBgNVBAYTAldXMRIwEAYDVQQKEwliZVRSVVNUZWQxGzAZBgNVBAMTEmJlVFJVU1RlZCBS"+ + "b290IENBczEaMBgGA1UEAxMRYmVUUlVTVGVkIFJvb3QgQ0E=", + "-----BEGIN CERTIFICATE-----\n"+ + "MIIFLDCCBBSgAwIBAgIEOU99hzANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJX\n"+ + "VzESMBAGA1UEChMJYmVUUlVTVGVkMRswGQYDVQQDExJiZVRSVVNUZWQgUm9vdCBD\n"+ + "QXMxGjAYBgNVBAMTEWJlVFJVU1RlZCBSb290IENBMB4XDTAwMDYyMDE0MjEwNFoX\n"+ + "DTEwMDYyMDEzMjEwNFowWjELMAkGA1UEBhMCV1cxEjAQBgNVBAoTCWJlVFJVU1Rl\n"+ + "ZDEbMBkGA1UEAxMSYmVUUlVTVGVkIFJvb3QgQ0FzMRowGAYDVQQDExFiZVRSVVNU\n"+ + "ZWQgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANS0c3oT\n"+ + "CjhVAb6JVuGUntS+WutKNHUbYSnE4a0IYCF4SP+00PpeQY1hRIfo7clY+vyTmt9P\n"+ + "6j41ffgzeubx181vSUs9Ty1uDoM6GHh3o8/n9E1z2Jo7Gh2+lVPPIJfCzz4kUmwM\n"+ + "jmVZxXH/YgmPqsWPzGCgc0rXOD8Vcr+il7dw6K/ifhYGTPWqZCZyByWtNfwYsSbX\n"+ + "2P8ZDoMbjNx4RWc0PfSvHI3kbWvtILNnmrRhyxdviTX/507AMhLn7uzf/5cwdO2N\n"+ + "R47rtMNE5qdMf1ZD6Li8tr76g5fmu/vEtpO+GRg+jIG5c4gW9JZDnGdzF5DYCW5j\n"+ + "rEq2I8QBoa2k5MUCAwEAAaOCAfgwggH0MA8GA1UdEwEB/wQFMAMBAf8wggFZBgNV\n"+ + "HSAEggFQMIIBTDCCAUgGCisGAQQBsT4BAAAwggE4MIIBAQYIKwYBBQUHAgIwgfQa\n"+ + "gfFSZWxpYW5jZSBvbiB0aGlzIGNlcnRpZmljYXRlIGJ5IGFueSBwYXJ0eSBhc3N1\n"+ + "bWVzIGFjY2VwdGFuY2Ugb2YgdGhlIHRoZW4gYXBwbGljYWJsZSBzdGFuZGFyZCB0\n"+ + "ZXJtcyBhbmQgY29uZGl0aW9ucyBvZiB1c2UsIGFuZCBjZXJ0aWZpY2F0aW9uIHBy\n"+ + "YWN0aWNlIHN0YXRlbWVudCwgd2hpY2ggY2FuIGJlIGZvdW5kIGF0IGJlVFJVU1Rl\n"+ + "ZCdzIHdlYiBzaXRlLCBodHRwczovL3d3dy5iZVRSVVNUZWQuY29tL3ZhdWx0L3Rl\n"+ + "cm1zMDEGCCsGAQUFBwIBFiVodHRwczovL3d3dy5iZVRSVVNUZWQuY29tL3ZhdWx0\n"+ + "L3Rlcm1zMDQGA1UdHwQtMCswKaAnoCWkIzAhMRIwEAYDVQQKEwliZVRSVVNUZWQx\n"+ + "CzAJBgNVBAYTAldXMB0GA1UdDgQWBBQquZtpLjub2M3eKjEENGvKBxirZzAfBgNV\n"+ + "HSMEGDAWgBQquZtpLjub2M3eKjEENGvKBxirZzAOBgNVHQ8BAf8EBAMCAf4wDQYJ\n"+ + "KoZIhvcNAQEFBQADggEBAHlh26Nebhax6nZR+csVm8tpvuaBa58oH2U+3RGFktTo\n"+ + "Qb9+M70j5/Egv6S0phkBxoyNNXxlpE8JpNbYIxUFE6dDea/bow6be3ga8wSGWsb2\n"+ + "jCBHOElQBp1yZzrwmAOtlmdE/D8QDYZN5AA7KXvOOzuZhmElQITcE2K3+spZ1gMe\n"+ + "1lMBzW1MaFVA4e5rxyoAAEiCswoBw2AqDPeCNe5IhpbkdNQ96gFxugR1QKepfzk5\n"+ + "mlWXKWWuGVUlBXJH0+gY3Ljpr0NzARJ0o+FcXxVdJPP55PS2Z2cS52QiivalQaYc\n"+ + "tmBjRYoQtLpGEK5BV2VsPyMQPyEQWbfkQN0mDCP2qq4=\n"+ + "-----END CERTIFICATE-----"); + super.addPEMCertificate("AddTrust Low-Value Services Root", + // X500 Subject, for lookups. + "MGUxCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRUcnVzdCBBQjEdMBsGA1UECxMUQWRkVHJ1c3Qg"+ + "VFRQIE5ldHdvcmsxITAfBgNVBAMTGEFkZFRydXN0IENsYXNzIDEgQ0EgUm9vdA==", + "-----BEGIN CERTIFICATE-----\n"+ + "MIIEGDCCAwCgAwIBAgIBATANBgkqhkiG9w0BAQUFADBlMQswCQYDVQQGEwJTRTEU\n"+ + "MBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3\n"+ + "b3JrMSEwHwYDVQQDExhBZGRUcnVzdCBDbGFzcyAxIENBIFJvb3QwHhcNMDAwNTMw\n"+ + "MTAzODMxWhcNMjAwNTMwMTAzODMxWjBlMQswCQYDVQQGEwJTRTEUMBIGA1UEChML\n"+ + "QWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3b3JrMSEwHwYD\n"+ + "VQQDExhBZGRUcnVzdCBDbGFzcyAxIENBIFJvb3QwggEiMA0GCSqGSIb3DQEBAQUA\n"+ + "A4IBDwAwggEKAoIBAQCWltQhSWDia+hBBwzexODcEyPNwTXH+9ZOEQpnXvUGW2ul\n"+ + "CDtbKRY654eyNAbFvAWlA3yCyykQruGIgb3WntP+LVbBFc7jJp0VLhD7Bo8wBN6n\n"+ + "tGO0/7Gcrjyvd7ZWxbWroulpOj0OM3kyP3CCkplhbY0wCI9xP6ZIVxn4JdxLZlyl\n"+ + "dI+Yrsj5wAYi56xz36Uu+1LcsRVlIPo1Zmne3yzxbrww2ywkEtvrNTVokMsAsJch\n"+ + "PXQhI2U0K7t4WaPW4XY5mqRJjox0r26kmqPZm9I4XJuiGMx1I4S+6+JNM3GOGvDC\n"+ + "+Mcdoq0Dlyz4zyXG9rgkMbFjXZJ/Y/AlyVMuH79NAgMBAAGjgdIwgc8wHQYDVR0O\n"+ + "BBYEFJWxtPCUtr3H2tERCSG+wa9J/RB7MAsGA1UdDwQEAwIBBjAPBgNVHRMBAf8E\n"+ + "BTADAQH/MIGPBgNVHSMEgYcwgYSAFJWxtPCUtr3H2tERCSG+wa9J/RB7oWmkZzBl\n"+ + "MQswCQYDVQQGEwJTRTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFk\n"+ + "ZFRydXN0IFRUUCBOZXR3b3JrMSEwHwYDVQQDExhBZGRUcnVzdCBDbGFzcyAxIENB\n"+ + "IFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBACxtZBsfzQ3duQH6lmM0MkhHma6X\n"+ + "7f1yFqZzR1r0693p9db7RcwpiURdv0Y5PejuvE1Uhh4dbOMXJ0PhiVYrqW9yTkkz\n"+ + "43J8KiOavD7/KCrto/8cI7pDVwlnTUtiBi34/2ydYB7YHEt9tTEv2dB8Xfjea4MY\n"+ + "eDdXL+gzB2ffHsdrKpV2ro9Xo/D0UrSpUwjP4E/TelOL/bscVjby/rK25Xa71SJl\n"+ + "pz/+0WatC7xrmYbvP33zGDLKe8bjq2RGlfgmadlVg3sslgf/WSxEo8bl6ancoWOA\n"+ + "WiFeIc9TVPC6b4nbqKqVz4vjccweGyBECMB6tkD9xOQ14R0WHNC8K47Wcdk=\n"+ + "-----END CERTIFICATE-----"); + super.addPEMCertificate("AddTrust External Root", + // X500 Subject, for lookups. + "MG8xCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRUcnVzdCBBQjEmMCQGA1UECxMdQWRkVHJ1c3Qg"+ + "RXh0ZXJuYWwgVFRQIE5ldHdvcmsxIjAgBgNVBAMTGUFkZFRydXN0IEV4dGVybmFsIENBIFJvb3Q=", + "-----BEGIN CERTIFICATE-----\n"+ + "MIIENjCCAx6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBvMQswCQYDVQQGEwJTRTEU\n"+ + "MBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFkZFRydXN0IEV4dGVybmFs\n"+ + "IFRUUCBOZXR3b3JrMSIwIAYDVQQDExlBZGRUcnVzdCBFeHRlcm5hbCBDQSBSb290\n"+ + "MB4XDTAwMDUzMDEwNDgzOFoXDTIwMDUzMDEwNDgzOFowbzELMAkGA1UEBhMCU0Ux\n"+ + "FDASBgNVBAoTC0FkZFRydXN0IEFCMSYwJAYDVQQLEx1BZGRUcnVzdCBFeHRlcm5h\n"+ + "bCBUVFAgTmV0d29yazEiMCAGA1UEAxMZQWRkVHJ1c3QgRXh0ZXJuYWwgQ0EgUm9v\n"+ + "dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALf3GjPm8gAELTngTlvt\n"+ + "H7xsD821+iO2zt6bETOXpClMfZOfvUq8k+0DGuOPz+VtUFrWlymUWoCwSXrbLpX9\n"+ + "uMq/NzgtHj6RQa1wVsfwTz/oMp50ysiQVOnGXw94nZpAPA6sYapeFI+eh6FqUNzX\n"+ + "mk6vBbOmcZSccbNQYArHE504B4YCqOmoaSYYkKtMsE8jqzpPhNjfzp/haW+710LX\n"+ + "a0Tkx63ubUFfclpxCDezeWWkWaCUN/cALw3CknLa0Dhy2xSoRcRdKn23tNbE7qzN\n"+ + "E0S3ySvdQwAl+mG5aWpYIxG3pzOPVnVZ9c0p10a3CitlttNCbxWyuHv77+ldU9U0\n"+ + "WicCAwEAAaOB3DCB2TAdBgNVHQ4EFgQUrb2YejS0Jvf6xCZU7wO94CTLVBowCwYD\n"+ + "VR0PBAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wgZkGA1UdIwSBkTCBjoAUrb2YejS0\n"+ + "Jvf6xCZU7wO94CTLVBqhc6RxMG8xCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRU\n"+ + "cnVzdCBBQjEmMCQGA1UECxMdQWRkVHJ1c3QgRXh0ZXJuYWwgVFRQIE5ldHdvcmsx\n"+ + "IjAgBgNVBAMTGUFkZFRydXN0IEV4dGVybmFsIENBIFJvb3SCAQEwDQYJKoZIhvcN\n"+ + "AQEFBQADggEBALCb4IUlwtYj4g+WBpKdQZic2YR5gdkeWxQHIzZlj7DYd7usQWxH\n"+ + "YINRsPkyPef89iYTx4AWpb9a/IfPeHmJIZriTAcKhjW88t5RxNKWt9x+Tu5w/Rw5\n"+ + "6wwCURQtjr0W4MHfRnXnJK3s9EK0hZNwEGe6nQY1ShjTK3rMUUKhemPR5ruhxSvC\n"+ + "Nr4TDea9Y355e6cJDUCrat2PisP29owaQgVR1EX1n6diIWgVIEM8med8vSTYqZEX\n"+ + "c4g/VhsxOBi0cQ+azcgOno4uG+GMmIPLHzHxREzGBHNJdmAPx/i9F4BrLunMTA5a\n"+ + "mnkPIAou1Z5jJh5VkpTYghdae9C8x49OhgQ=\n"+ + "-----END CERTIFICATE-----"); + super.addPEMCertificate("AddTrust Public Services Root", + // X500 Subject, for lookups. + "MGQxCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRUcnVzdCBBQjEdMBsGA1UECxMUQWRkVHJ1c3Qg"+ + "VFRQIE5ldHdvcmsxIDAeBgNVBAMTF0FkZFRydXN0IFB1YmxpYyBDQSBSb290", + "-----BEGIN CERTIFICATE-----\n"+ + "MIIEFTCCAv2gAwIBAgIBATANBgkqhkiG9w0BAQUFADBkMQswCQYDVQQGEwJTRTEU\n"+ + "MBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3\n"+ + "b3JrMSAwHgYDVQQDExdBZGRUcnVzdCBQdWJsaWMgQ0EgUm9vdDAeFw0wMDA1MzAx\n"+ + "MDQxNTBaFw0yMDA1MzAxMDQxNTBaMGQxCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtB\n"+ + "ZGRUcnVzdCBBQjEdMBsGA1UECxMUQWRkVHJ1c3QgVFRQIE5ldHdvcmsxIDAeBgNV\n"+ + "BAMTF0FkZFRydXN0IFB1YmxpYyBDQSBSb290MIIBIjANBgkqhkiG9w0BAQEFAAOC\n"+ + "AQ8AMIIBCgKCAQEA6Rowj4OIFMEg2Dybjxt+A3S72mnTRqX4jsIMEZBRpS9mVEBV\n"+ + "6tsfSlbunyNu9DnLoblv8n75XYcmYZ4c+OLspoH4IcUkzBEMP9smcnrHAZcHF/nX\n"+ + "GCwwfQ56HmIexkvA/X1id9NEHif2P0tEs7c42TkfYNVRknMDtABp4/MUTu7R3AnP\n"+ + "dzRGULD4EfL+OHn3Bzn+UZKXC1sIXzSGAa2Il+tmzV7R/9x98oTaunet3IAIx6eH\n"+ + "1lWfl2royBFkuucZKT8Rs3iQhCBSWxHveNCD9tVIkNAwHM+A+WD+eeSI8t0A65RF\n"+ + "62WUaUC6wNW0uLp9BBGo6zEFlpROWCGOn9Bg/QIDAQABo4HRMIHOMB0GA1UdDgQW\n"+ + "BBSBPjfYkrAfd59ctKtzquf2NGAv+jALBgNVHQ8EBAMCAQYwDwYDVR0TAQH/BAUw\n"+ + "AwEB/zCBjgYDVR0jBIGGMIGDgBSBPjfYkrAfd59ctKtzquf2NGAv+qFopGYwZDEL\n"+ + "MAkGA1UEBhMCU0UxFDASBgNVBAoTC0FkZFRydXN0IEFCMR0wGwYDVQQLExRBZGRU\n"+ + "cnVzdCBUVFAgTmV0d29yazEgMB4GA1UEAxMXQWRkVHJ1c3QgUHVibGljIENBIFJv\n"+ + "b3SCAQEwDQYJKoZIhvcNAQEFBQADggEBAAP3FUr4JNojVhaTdt02KLmuG7jD8WS6\n"+ + "IBh4lSknVwW8fCr0uVFV2ocC3g8WFzH4qnkuCRO7r7IgGRLlk/lL+YPoRNWyQSW/\n"+ + "iHVv/xD8SlTQX/D67zZzfRs2RcYhbbQVuE7PnFylPVoAjgbjPGsye/Kf8Lb93/Ao\n"+ + "GEjwxrzQvzSAlsJKsW2Ox5BF3i9nrEUEo3rcVZLJR2bYGozH7ZxOmuASu7VqTITh\n"+ + "4SINhwBk/ox9Yjllpu9CtoAlEmEBqCQTcAARJl/6NVDFSMwGR+gn2HCNX2TmoUQm\n"+ + "XiLsks3/QppEIW1cxeMiHV9HEufOX1362KqxMy3ZdvJOOjMMK7MtkAY=\n"+ + "-----END CERTIFICATE-----"); + super.addPEMCertificate("AddTrust Qualified Certificates Root", + // X500 Subject, for lookups. + "MGcxCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRUcnVzdCBBQjEdMBsGA1UECxMUQWRkVHJ1c3Qg"+ + "VFRQIE5ldHdvcmsxIzAhBgNVBAMTGkFkZFRydXN0IFF1YWxpZmllZCBDQSBSb290", + "-----BEGIN CERTIFICATE-----\n"+ + "MIIEHjCCAwagAwIBAgIBATANBgkqhkiG9w0BAQUFADBnMQswCQYDVQQGEwJTRTEU\n"+ + "MBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3\n"+ + "b3JrMSMwIQYDVQQDExpBZGRUcnVzdCBRdWFsaWZpZWQgQ0EgUm9vdDAeFw0wMDA1\n"+ + "MzAxMDQ0NTBaFw0yMDA1MzAxMDQ0NTBaMGcxCzAJBgNVBAYTAlNFMRQwEgYDVQQK\n"+ + "EwtBZGRUcnVzdCBBQjEdMBsGA1UECxMUQWRkVHJ1c3QgVFRQIE5ldHdvcmsxIzAh\n"+ + "BgNVBAMTGkFkZFRydXN0IFF1YWxpZmllZCBDQSBSb290MIIBIjANBgkqhkiG9w0B\n"+ + "AQEFAAOCAQ8AMIIBCgKCAQEA5B6a/twJWoekn0e+EV+vhDTbYjx5eLfpMLXsDBwq\n"+ + "xBb/4Oxx64r1EW7tTw2R0hIYLUkVAcKkIhPHEWT/IhKauY5cLwjPcWqzZwFZ8V1G\n"+ + "87B4pfYOQnrjfxvM0PC3KP0q6p6zsLkEqv32x7SxuCqg+1jxGaBvcCV+PmlKfw8i\n"+ + "2O+tCBGaKZnhqkRFmhJePp1tUvznoD1oL/BLcHwTOK28FSXx1s6rosAx1i+f4P8U\n"+ + "WfyEk9mHfExUE+uf0S0R+Bg6Ot4l2ffTQO2kBhLEO+GRwVY18BTcZTYJbqukB8c1\n"+ + "0cIDMzZbdSZtQvESa0NvS3GU+jQd7RNuyoB/mC9suWXY6QIDAQABo4HUMIHRMB0G\n"+ + "A1UdDgQWBBQ5lYtii1zJ1IC6WA+XPxUIQ8yYpzALBgNVHQ8EBAMCAQYwDwYDVR0T\n"+ + "AQH/BAUwAwEB/zCBkQYDVR0jBIGJMIGGgBQ5lYtii1zJ1IC6WA+XPxUIQ8yYp6Fr\n"+ + "pGkwZzELMAkGA1UEBhMCU0UxFDASBgNVBAoTC0FkZFRydXN0IEFCMR0wGwYDVQQL\n"+ + "ExRBZGRUcnVzdCBUVFAgTmV0d29yazEjMCEGA1UEAxMaQWRkVHJ1c3QgUXVhbGlm\n"+ + "aWVkIENBIFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBABmrder4i2VhlRO6aQTv\n"+ + "hsoToMeqT2QbPxj2qC0sVY8FtzDqQmodwCVRLae/DLPt7wh/bDxGGuoYQ992zPlm\n"+ + "hpwsaPXpF/gxsxjE1kh9I0xowX67ARRvxdlu3rsEQmr49lx95dr6h+sNNVJn0J6X\n"+ + "dgWTP5XHAeZpVTh/EGGZyeNfpso+gmNIquIISD6q8rKFYqa0p9m9N5xotS1WfbC3\n"+ + "P6CxB9bpT9zeRXEwMn8bLgn5v1Kh7sKAPgZcLlVAwRv1cEWw3F369nJad9Jjzc9Y\n"+ + "iQBCYz95OdBEsIJuQRno3eDBiFrRHnGTHyQwdOUeqN48Jzd/g66ed8/wMLH/S5no\n"+ + "xqE=\n"+ + "-----END CERTIFICATE-----"); + super.addPEMCertificate("Verisign Time Stamping Authority CA", + // X500 Subject, for lookups. + "MIGlMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjEfMB0GA1UECxMWVmVyaVNpZ24gVHJ1c3QgTmV0"+ + "d29yazE7MDkGA1UECxMyVGVybXMgb2YgdXNlIGF0IGh0dHBzOi8vd3d3LnZlcmlzaWduLmNvbS9y"+ + "cGEgKGMpMDAxLDAqBgNVBAMTI1ZlcmlTaWduIFRpbWUgU3RhbXBpbmcgQXV0aG9yaXR5IENB", + "-----BEGIN CERTIFICATE-----\n"+ + "MIIDzTCCAzagAwIBAgIQU2GyYK7bcY6nlLMTM/QHCTANBgkqhkiG9w0BAQUFADCB\n"+ + "wTELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTwwOgYDVQQL\n"+ + "EzNDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5\n"+ + "IC0gRzIxOjA4BgNVBAsTMShjKSAxOTk4IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1\n"+ + "dGhvcml6ZWQgdXNlIG9ubHkxHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdv\n"+ + "cmswHhcNMDAwOTI2MDAwMDAwWhcNMTAwOTI1MjM1OTU5WjCBpTEXMBUGA1UEChMO\n"+ + "VmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsx\n"+ + "OzA5BgNVBAsTMlRlcm1zIG9mIHVzZSBhdCBodHRwczovL3d3dy52ZXJpc2lnbi5j\n"+ + "b20vcnBhIChjKTAwMSwwKgYDVQQDEyNWZXJpU2lnbiBUaW1lIFN0YW1waW5nIEF1\n"+ + "dGhvcml0eSBDQTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA0hmdZ8IAIVli\n"+ + "zrQJIkRpivglWtvtDbc2fk7gu5Q+kCWHwmFHKdm9VLhjzCx9abQzNvQ3B5rB3UBU\n"+ + "/OB4naCTuQk9I1F/RMIUdNsKvsvJMDRAmD7Q1yUQgZS9B0+c1lQn3y6ov8uQjI11\n"+ + "S7zi6ESHzeZBCiVu6PQkAsVSD27smHUCAwEAAaOB3zCB3DAPBgNVHRMECDAGAQH/\n"+ + "AgEAMEUGA1UdIAQ+MDwwOgYMYIZIAYb4RQEHFwEDMCowKAYIKwYBBQUHAgEWHGh0\n"+ + "dHBzOi8vd3d3LnZlcmlzaWduLmNvbS9ycGEwMQYDVR0fBCowKDAmoCSgIoYgaHR0\n"+ + "cDovL2NybC52ZXJpc2lnbi5jb20vcGNhMy5jcmwwCwYDVR0PBAQDAgEGMEIGCCsG\n"+ + "AQUFBwEBBDYwNDAyBggrBgEFBQcwAaYmFiRodHRwOi8vb2NzcC52ZXJpc2lnbi5j\n"+ + "b20vb2NzcC9zdGF0dXMwDQYJKoZIhvcNAQEFBQADgYEAgnBold+2DcIBcBlK0lRW\n"+ + "HqzyRUyHuPU163hLBanInTsZIS5wNEqi9YngFXVF5yg3ADQnKeg3S/LvRJdrF1Ea\n"+ + "w1adPBqK9kpGRjeM+sv1ZFo4aC4cw+9wzrhGBha/937ntag+RaypJXUie28/sJyU\n"+ + "58dzq6wf7iWbwBbtt8pb8BQ=\n"+ + "-----END CERTIFICATE-----"); + super.addPEMCertificate("Thawte Time Stamping CA", + // X500 Subject, for lookups. + "MIGLMQswCQYDVQQGEwJaQTEVMBMGA1UECBMMV2VzdGVybiBDYXBlMRQwEgYDVQQHEwtEdXJiYW52"+ + "aWxsZTEPMA0GA1UEChMGVGhhd3RlMR0wGwYDVQQLExRUaGF3dGUgQ2VydGlmaWNhdGlvbjEfMB0G"+ + "A1UEAxMWVGhhd3RlIFRpbWVzdGFtcGluZyBDQQ==", + "-----BEGIN CERTIFICATE-----\n"+ + "MIICoTCCAgqgAwIBAgIBADANBgkqhkiG9w0BAQQFADCBizELMAkGA1UEBhMCWkEx\n"+ + "FTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTEUMBIGA1UEBxMLRHVyYmFudmlsbGUxDzAN\n"+ + "BgNVBAoTBlRoYXd0ZTEdMBsGA1UECxMUVGhhd3RlIENlcnRpZmljYXRpb24xHzAd\n"+ + "BgNVBAMTFlRoYXd0ZSBUaW1lc3RhbXBpbmcgQ0EwHhcNOTcwMTAxMDAwMDAwWhcN\n"+ + "MjAxMjMxMjM1OTU5WjCBizELMAkGA1UEBhMCWkExFTATBgNVBAgTDFdlc3Rlcm4g\n"+ + "Q2FwZTEUMBIGA1UEBxMLRHVyYmFudmlsbGUxDzANBgNVBAoTBlRoYXd0ZTEdMBsG\n"+ + "A1UECxMUVGhhd3RlIENlcnRpZmljYXRpb24xHzAdBgNVBAMTFlRoYXd0ZSBUaW1l\n"+ + "c3RhbXBpbmcgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANYrWHhhRYZT\n"+ + "6jR7UZztsOYuGA7+4F+oJ9O0yeB8WU4WDnNUYMF/9p8u6TqFJBU820cEY8OexJQa\n"+ + "Wt9MevPZQx08EHp5JduQ/vBR5zDWQQD9nyjfeb6Uu522FOMjhdepQeBMpHmwKxqL\n"+ + "8vg7ij5FrHGSALSQQZj7X+36ty6K+Ig3AgMBAAGjEzARMA8GA1UdEwEB/wQFMAMB\n"+ + "Af8wDQYJKoZIhvcNAQEEBQADgYEAZ9viwuaHPUCDhjc1fR/OmsMMZiCouqoEiYbC\n"+ + "9RAIDb/LogWK0E02PvTX72nGXuSwlG9KuefeW4i2e9vjJ+V2w/A1wcu1J5szedyQ\n"+ + "pgCed/r8zSeUQhac0xxo7L9c3eWpexAKMnRUEzGLhQOEkbdYATAUOK8oyvyxUBkZ\n"+ + "CayJSdM=\n"+ + "-----END CERTIFICATE-----"); + super.addPEMCertificate("Entrust.net Global Secure Server CA", + // X500 Subject, for lookups. + "MIG6MRQwEgYDVQQKEwtFbnRydXN0Lm5ldDE/MD0GA1UECxQ2d3d3LmVudHJ1c3QubmV0L1NTTF9D"+ + "UFMgaW5jb3JwLiBieSByZWYuIChsaW1pdHMgbGlhYi4pMSUwIwYDVQQLExwoYykgMjAwMCBFbnRy"+ + "dXN0Lm5ldCBMaW1pdGVkMTowOAYDVQQDEzFFbnRydXN0Lm5ldCBTZWN1cmUgU2VydmVyIENlcnRp"+ + "ZmljYXRpb24gQXV0aG9yaXR5", + "-----BEGIN CERTIFICATE-----\n"+ + "MIIElTCCA/6gAwIBAgIEOJsRPDANBgkqhkiG9w0BAQQFADCBujEUMBIGA1UEChML\n"+ + "RW50cnVzdC5uZXQxPzA9BgNVBAsUNnd3dy5lbnRydXN0Lm5ldC9TU0xfQ1BTIGlu\n"+ + "Y29ycC4gYnkgcmVmLiAobGltaXRzIGxpYWIuKTElMCMGA1UECxMcKGMpIDIwMDAg\n"+ + "RW50cnVzdC5uZXQgTGltaXRlZDE6MDgGA1UEAxMxRW50cnVzdC5uZXQgU2VjdXJl\n"+ + "IFNlcnZlciBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wMDAyMDQxNzIwMDBa\n"+ + "Fw0yMDAyMDQxNzUwMDBaMIG6MRQwEgYDVQQKEwtFbnRydXN0Lm5ldDE/MD0GA1UE\n"+ + "CxQ2d3d3LmVudHJ1c3QubmV0L1NTTF9DUFMgaW5jb3JwLiBieSByZWYuIChsaW1p\n"+ + "dHMgbGlhYi4pMSUwIwYDVQQLExwoYykgMjAwMCBFbnRydXN0Lm5ldCBMaW1pdGVk\n"+ + "MTowOAYDVQQDEzFFbnRydXN0Lm5ldCBTZWN1cmUgU2VydmVyIENlcnRpZmljYXRp\n"+ + "b24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDHwV9OcfHO\n"+ + "8GCGD9JYf9Mzly0XonUwtZZkJi9ow0SrqHXmAGc0V55lxyKbc+bT3QgON1WqJUaB\n"+ + "bL3+qPZ1V1eMkGxKwz6LS0MKyRFWmponIpnPVZ5h2QLifLZ8OAfc439PmrkDQYC2\n"+ + "dWcTC5/oVzbIXQA23mYU2m52H083jIITiQIDAQABo4IBpDCCAaAwEQYJYIZIAYb4\n"+ + "QgEBBAQDAgAHMIHjBgNVHR8EgdswgdgwgdWggdKggc+kgcwwgckxFDASBgNVBAoT\n"+ + "C0VudHJ1c3QubmV0MT8wPQYDVQQLFDZ3d3cuZW50cnVzdC5uZXQvU1NMX0NQUyBp\n"+ + "bmNvcnAuIGJ5IHJlZi4gKGxpbWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAyMDAw\n"+ + "IEVudHJ1c3QubmV0IExpbWl0ZWQxOjA4BgNVBAMTMUVudHJ1c3QubmV0IFNlY3Vy\n"+ + "ZSBTZXJ2ZXIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxDTALBgNVBAMTBENSTDEw\n"+ + "KwYDVR0QBCQwIoAPMjAwMDAyMDQxNzIwMDBagQ8yMDIwMDIwNDE3NTAwMFowCwYD\n"+ + "VR0PBAQDAgEGMB8GA1UdIwQYMBaAFMtswGvjuz7L/CKc/vuLkpyw8m4iMB0GA1Ud\n"+ + "DgQWBBTLbMBr47s+y/winP77i5KcsPJuIjAMBgNVHRMEBTADAQH/MB0GCSqGSIb2\n"+ + "fQdBAAQQMA4bCFY1LjA6NC4wAwIEkDANBgkqhkiG9w0BAQQFAAOBgQBi24GRzsia\n"+ + "d0Iv7L0no1MPUBvqTpLwqa+poLpIYcvvyQbvH9X07t9WLebKahlzqlO+krNQAraF\n"+ + "JnJj2HVQYnUUt7NQGj/KEQALhUVpbbalrlHhStyCP2yMNLJ3a9kC9n8O6mUE8c1U\n"+ + "yrrJzOCE98g+EZfTYAkYvAX/bIkz8OwVDw==\n"+ + "-----END CERTIFICATE-----"); + super.addPEMCertificate("Entrust.net Global Secure Personal CA", + // X500 Subject, for lookups. + "MIG0MRQwEgYDVQQKEwtFbnRydXN0Lm5ldDFAMD4GA1UECxQ3d3d3LmVudHJ1c3QubmV0L0dDQ0Ff"+ + "Q1BTIGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxpYWIuKTElMCMGA1UECxMcKGMpIDIwMDAgRW50"+ + "cnVzdC5uZXQgTGltaXRlZDEzMDEGA1UEAxMqRW50cnVzdC5uZXQgQ2xpZW50IENlcnRpZmljYXRp"+ + "b24gQXV0aG9yaXR5", + "-----BEGIN CERTIFICATE-----\n"+ + "MIIEgzCCA+ygAwIBAgIEOJ725DANBgkqhkiG9w0BAQQFADCBtDEUMBIGA1UEChML\n"+ + "RW50cnVzdC5uZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9HQ0NBX0NQUyBp\n"+ + "bmNvcnAuIGJ5IHJlZi4gKGxpbWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAyMDAw\n"+ + "IEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNVBAMTKkVudHJ1c3QubmV0IENsaWVu\n"+ + "dCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wMDAyMDcxNjE2NDBaFw0yMDAy\n"+ + "MDcxNjQ2NDBaMIG0MRQwEgYDVQQKEwtFbnRydXN0Lm5ldDFAMD4GA1UECxQ3d3d3\n"+ + "LmVudHJ1c3QubmV0L0dDQ0FfQ1BTIGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxp\n"+ + "YWIuKTElMCMGA1UECxMcKGMpIDIwMDAgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEG\n"+ + "A1UEAxMqRW50cnVzdC5uZXQgQ2xpZW50IENlcnRpZmljYXRpb24gQXV0aG9yaXR5\n"+ + "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCTdLS25MVL1qFof2LV7PdRV7Ny\n"+ + "Spj10InJrWPNTTVRaoTUrcloeW+46xHbh65cJFET8VQlhK8pK5/jgOLZy93GRUk0\n"+ + "iJBeAZfv6lOm3fzB3ksqJeTpNfpVBQbliXrqpBFXO/x8PTbNZzVtpKklWb1m9fkn\n"+ + "5JVn1j+SgF7yNH0rhQIDAQABo4IBnjCCAZowEQYJYIZIAYb4QgEBBAQDAgAHMIHd\n"+ + "BgNVHR8EgdUwgdIwgc+ggcyggcmkgcYwgcMxFDASBgNVBAoTC0VudHJ1c3QubmV0\n"+ + "MUAwPgYDVQQLFDd3d3cuZW50cnVzdC5uZXQvR0NDQV9DUFMgaW5jb3JwLiBieSBy\n"+ + "ZWYuIChsaW1pdHMgbGlhYi4pMSUwIwYDVQQLExwoYykgMjAwMCBFbnRydXN0Lm5l\n"+ + "dCBMaW1pdGVkMTMwMQYDVQQDEypFbnRydXN0Lm5ldCBDbGllbnQgQ2VydGlmaWNh\n"+ + "dGlvbiBBdXRob3JpdHkxDTALBgNVBAMTBENSTDEwKwYDVR0QBCQwIoAPMjAwMDAy\n"+ + "MDcxNjE2NDBagQ8yMDIwMDIwNzE2NDY0MFowCwYDVR0PBAQDAgEGMB8GA1UdIwQY\n"+ + "MBaAFISLdP3FjcD/J20gN0V8/i3OutN9MB0GA1UdDgQWBBSEi3T9xY3A/ydtIDdF\n"+ + "fP4tzrrTfTAMBgNVHRMEBTADAQH/MB0GCSqGSIb2fQdBAAQQMA4bCFY1LjA6NC4w\n"+ + "AwIEkDANBgkqhkiG9w0BAQQFAAOBgQBObzWAO9GK9Q6nIMstZVXQkvTnhLUGJoMS\n"+ + "hAusO7JE7r3PQNsgDrpuFOow4DtifH+La3xKp9U1PL6oXOpLu5OOgGarDyn9TS2/\n"+ + "GpsKkMWr2tGzhtQvJFJcem3G8v7lTRowjJDyutdKPkN+1MhQGof4T4HHdguEOnKd\n"+ + "zmVml64mXg==\n"+ + "-----END CERTIFICATE-----"); + super.addPEMCertificate("AOL Time Warner Root Certification Authority 1", + // X500 Subject, for lookups. + "MIGDMQswCQYDVQQGEwJVUzEdMBsGA1UEChMUQU9MIFRpbWUgV2FybmVyIEluYy4xHDAaBgNVBAsT"+ + "E0FtZXJpY2EgT25saW5lIEluYy4xNzA1BgNVBAMTLkFPTCBUaW1lIFdhcm5lciBSb290IENlcnRp"+ + "ZmljYXRpb24gQXV0aG9yaXR5IDE=", + "-----BEGIN CERTIFICATE-----\n"+ + "MIID5jCCAs6gAwIBAgIBATANBgkqhkiG9w0BAQUFADCBgzELMAkGA1UEBhMCVVMx\n"+ + "HTAbBgNVBAoTFEFPTCBUaW1lIFdhcm5lciBJbmMuMRwwGgYDVQQLExNBbWVyaWNh\n"+ + "IE9ubGluZSBJbmMuMTcwNQYDVQQDEy5BT0wgVGltZSBXYXJuZXIgUm9vdCBDZXJ0\n"+ + "aWZpY2F0aW9uIEF1dGhvcml0eSAxMB4XDTAyMDUyOTA2MDAwMFoXDTM3MTEyMDE1\n"+ + "MDMwMFowgYMxCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRBT0wgVGltZSBXYXJuZXIg\n"+ + "SW5jLjEcMBoGA1UECxMTQW1lcmljYSBPbmxpbmUgSW5jLjE3MDUGA1UEAxMuQU9M\n"+ + "IFRpbWUgV2FybmVyIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgMTCCASIw\n"+ + "DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJnej8Mlo2k06AX3dLm/WpcZuS+U\n"+ + "0pPlLYnKhHw/EEMbjIt8hFj4JHxIzyr9wBXZGH6EGhfT257XyuTZ16pYUYfw8ItI\n"+ + "TuLCxFlpMGK2MKKMCxGZYTVtfu/FsRkGIBKOQuHfD5YQUqjPnF+VFNivO3ULMSAf\n"+ + "RC+iYkGzuxgh28pxPIzstrkNn+9R7017EvILDOGsQI93f7DKeHEMXRZxcKLXwjqF\n"+ + "zQ6axOAAsNUl6twr5JQtOJyJQVdkKGUZHLZEtMgxa44Be3ZZJX8VHIQIfHNlIAqh\n"+ + "BC4aMqiaILGcLCFZ5/vP7nAtCMpjPiybkxlqpMKX/7eGV4iFbJ4VFitNLLMCAwEA\n"+ + "AaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUoTYwFsuGkABFgFOxj8jY\n"+ + "PXy+XxIwHwYDVR0jBBgwFoAUoTYwFsuGkABFgFOxj8jYPXy+XxIwDgYDVR0PAQH/\n"+ + "BAQDAgGGMA0GCSqGSIb3DQEBBQUAA4IBAQCKIBilvrMvtKaEAEAwKfq0FHNMeUWn\n"+ + "9nDg6H5kHgqVfGphwu9OH77/yZkfB2FK4V1Mza3u0FIy2VkyvNp5ctZ7CegCgTXT\n"+ + "Ct8RHcl5oIBN/lrXVtbtDyqvpxh1MwzqwWEFT2qaifKNuZ8u77BfWgDrvq2g+EQF\n"+ + "Z7zLBO+eZMXpyD8Fv8YvBxzDNnGGyjhmSs3WuEvGbKeXO/oTLW4jYYehY0KswsuX\n"+ + "n2Fozy1MBJ3XJU8KDk2QixhWqJNIV9xvrr2eZ1d3iVCzvhGbRWeDhhmH05i9CBoW\n"+ + "H1iCC+GWaQVLjuyDUTEH1dSf/1l7qG6Fz9NLqUmwX7A5KGgOc90lmt4S\n"+ + "-----END CERTIFICATE-----"); + super.addPEMCertificate("AOL Time Warner Root Certification Authority 2", + // X500 Subject, for lookups. + "MIGDMQswCQYDVQQGEwJVUzEdMBsGA1UEChMUQU9MIFRpbWUgV2FybmVyIEluYy4xHDAaBgNVBAsT"+ + "E0FtZXJpY2EgT25saW5lIEluYy4xNzA1BgNVBAMTLkFPTCBUaW1lIFdhcm5lciBSb290IENlcnRp"+ + "ZmljYXRpb24gQXV0aG9yaXR5IDI=", + "-----BEGIN CERTIFICATE-----\n"+ + "MIIF5jCCA86gAwIBAgIBATANBgkqhkiG9w0BAQUFADCBgzELMAkGA1UEBhMCVVMx\n"+ + "HTAbBgNVBAoTFEFPTCBUaW1lIFdhcm5lciBJbmMuMRwwGgYDVQQLExNBbWVyaWNh\n"+ + "IE9ubGluZSBJbmMuMTcwNQYDVQQDEy5BT0wgVGltZSBXYXJuZXIgUm9vdCBDZXJ0\n"+ + "aWZpY2F0aW9uIEF1dGhvcml0eSAyMB4XDTAyMDUyOTA2MDAwMFoXDTM3MDkyODIz\n"+ + "NDMwMFowgYMxCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRBT0wgVGltZSBXYXJuZXIg\n"+ + "SW5jLjEcMBoGA1UECxMTQW1lcmljYSBPbmxpbmUgSW5jLjE3MDUGA1UEAxMuQU9M\n"+ + "IFRpbWUgV2FybmVyIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgMjCCAiIw\n"+ + "DQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALQ3WggWmRToVbEbJGv8x4vmh6mJ\n"+ + "7ouZzU9AhqS2TcnZsdw8TQ2FTBVsRotSeJ/4I/1n9SQ6aF3Q92RhQVSji6UI0ilb\n"+ + "m2BPJoPRYxJWSXakFsKlnUWsi4SVqBax7J/qJBrvuVdcmiQhLE0OcR+mrF1FdAOY\n"+ + "xFSMFkpBd4aVdQxHAWZg/BXxD+r1FHjHDtdugRxev17nOirYlxcwfACtCJ0zr7iZ\n"+ + "YYCLqJV+FNwSbKTQ2O9ASQI2+W6p1h2WVgSysy0WVoaP2SBXgM1nEG2wTPDaRrbq\n"+ + "JS5Gr42whTg0ixQmgiusrpkLjhTXUr2eacOGAgvqdnUxCc4zGSGFQ+aJLZ8lN2fx\n"+ + "I2rSAG2X+Z/nKcrdH9cG6rjJuQkhn8g/BsXS6RJGAE57COtCPStIbp1n3UsC5ETz\n"+ + "kxmlJ85per5n0/xQpCyrw2u544BMzwVhSyvcG7mm0tCq9Stz+86QNZ8MUhy/XCFh\n"+ + "EVsVS6kkUfykXPcXnbDS+gfpj1bkGoxoigTTfFrjnqKhynFbotSg5ymFXQNoKk/S\n"+ + "Btc9+cMDLz9l+WceR0DTYw/j1Y75hauXTLPXJuuWCpTehTacyH+BCQJJKg71ZDIM\n"+ + "gtG6aoIbs0t0EfOMd9afv9w3pKdVBC/UMejTRrkDfNoSTllkt1ExMVCgyhwn2RAu\n"+ + "rda9EGYrw7AiShJbAgMBAAGjYzBhMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYE\n"+ + "FE9pbQN+nZ8HGEO8txBO1b+pxCAoMB8GA1UdIwQYMBaAFE9pbQN+nZ8HGEO8txBO\n"+ + "1b+pxCAoMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQUFAAOCAgEAO/Ouyugu\n"+ + "h4X7ZVnnrREUpVe8WJ8kEle7+z802u6teio0cnAxa8cZmIDJgt43d15Ui47y6mdP\n"+ + "yXSEkVYJ1eV6moG2gcKtNuTxVBFT8zRFASbI5Rq8NEQh3q0l/HYWdyGQgJhXnU7q\n"+ + "7C+qPBR7V8F+GBRn7iTGvboVsNIYvbdVgaxTwOjdaRITQrcCtQVBynlQboIOcXKT\n"+ + "RuidDV29rs4prWPVVRaAMCf/drr3uNZK49m1+VLQTkCpx+XCMseqdiThawVQ68W/\n"+ + "ClTluUI8JPu3B5wwn3la5uBAUhX0/Kr0VvlEl4ftDmVyXr4m+02kLQgH3thcoNyB\n"+ + "M5kYJRF3p+v9WAksmWsbivNSPxpNSGDxoPYzAlOL7SUJuA0t7Zdz7NeWH45gDtoQ\n"+ + "my8YJPamTQr5O8t1wswvziRpyQoijlmn94IM19drNZxDAGrElWe6nEXLuA4399xO\n"+ + "AU++CrYD062KRffaJ00psUjf5BHklka9bAI+1lHIlRcBFanyqqryvy9lG2/QuRqT\n"+ + "9Y41xICHPpQvZuTpqP9BnHAqTyo5GJUefvthATxRCC4oGKQWDzH9OmwjkyB24f0H\n"+ + "hdFbP9IcczLd+rn4jM8Ch3qaluTtT4mNU0OrDhPAARW0eTjb/G49nlG2uBOLZ8/5\n"+ + "fNkiHfZdxRwBL5joeiQYvITX+txyW/fBOmg=\n"+ + "-----END CERTIFICATE-----"); + super.addPEMCertificate("beTRUSTed Root CA-Baltimore Implementation", + // X500 Subject, for lookups. + "MGYxEjAQBgNVBAoTCWJlVFJVU1RlZDEbMBkGA1UECxMSYmVUUlVTVGVkIFJvb3QgQ0FzMTMwMQYD"+ + "VQQDEypiZVRSVVNUZWQgUm9vdCBDQS1CYWx0aW1vcmUgSW1wbGVtZW50YXRpb24=", + "-----BEGIN CERTIFICATE-----\n"+ + "MIIFajCCBFKgAwIBAgIEPLU9RjANBgkqhkiG9w0BAQUFADBmMRIwEAYDVQQKEwli\n"+ + "ZVRSVVNUZWQxGzAZBgNVBAsTEmJlVFJVU1RlZCBSb290IENBczEzMDEGA1UEAxMq\n"+ + "YmVUUlVTVGVkIFJvb3QgQ0EtQmFsdGltb3JlIEltcGxlbWVudGF0aW9uMB4XDTAy\n"+ + "MDQxMTA3Mzg1MVoXDTIyMDQxMTA3Mzg1MVowZjESMBAGA1UEChMJYmVUUlVTVGVk\n"+ + "MRswGQYDVQQLExJiZVRSVVNUZWQgUm9vdCBDQXMxMzAxBgNVBAMTKmJlVFJVU1Rl\n"+ + "ZCBSb290IENBLUJhbHRpbW9yZSBJbXBsZW1lbnRhdGlvbjCCASIwDQYJKoZIhvcN\n"+ + "AQEBBQADggEPADCCAQoCggEBALx+xDmcjOPWHIb/ymKt4H8wRXqOGrO4x/nRNv8i\n"+ + "805qX4QQ+2aBw5R5MdKR4XeOGCrDFN5R9U+jK7wYFuK13XneIviCfsuBH/0nLI/6\n"+ + "l2Qijvj/YaOcGx6Sj8CoCd8JEey3fTGaGuqDIQY8n7pc/5TqarjDa1U0Tz0yH92B\n"+ + "FODEPM2dMPgwqZfT7syj0B9fHBOB1BirlNFjw55/NZKeX0Tq7PQiXLfoPX2k+Ymp\n"+ + "kbIq2eszh+6l/ePazIjmiSZuxyuC0F6dWdsU7JGDBcNeDsYq0ATdcT0gTlgn/FP7\n"+ + "eHgZFLL8kFKJOGJgB7Sg7KxrUNb9uShr71ItOrL/8QFArDcCAwEAAaOCAh4wggIa\n"+ + "MA8GA1UdEwEB/wQFMAMBAf8wggG1BgNVHSAEggGsMIIBqDCCAaQGDysGAQQBsT4A\n"+ + "AAEJKIORMTCCAY8wggFIBggrBgEFBQcCAjCCAToaggE2UmVsaWFuY2Ugb24gb3Ig\n"+ + "dXNlIG9mIHRoaXMgQ2VydGlmaWNhdGUgY3JlYXRlcyBhbiBhY2tub3dsZWRnbWVu\n"+ + "dCBhbmQgYWNjZXB0YW5jZSBvZiB0aGUgdGhlbiBhcHBsaWNhYmxlIHN0YW5kYXJk\n"+ + "IHRlcm1zIGFuZCBjb25kaXRpb25zIG9mIHVzZSwgdGhlIENlcnRpZmljYXRpb24g\n"+ + "UHJhY3RpY2UgU3RhdGVtZW50IGFuZCB0aGUgUmVseWluZyBQYXJ0eSBBZ3JlZW1l\n"+ + "bnQsIHdoaWNoIGNhbiBiZSBmb3VuZCBhdCB0aGUgYmVUUlVTVGVkIHdlYiBzaXRl\n"+ + "LCBodHRwOi8vd3d3LmJldHJ1c3RlZC5jb20vcHJvZHVjdHNfc2VydmljZXMvaW5k\n"+ + "ZXguaHRtbDBBBggrBgEFBQcCARY1aHR0cDovL3d3dy5iZXRydXN0ZWQuY29tL3By\n"+ + "b2R1Y3RzX3NlcnZpY2VzL2luZGV4Lmh0bWwwHQYDVR0OBBYEFEU9w6nR3D8kVpgc\n"+ + "cxiIav+DR+22MB8GA1UdIwQYMBaAFEU9w6nR3D8kVpgccxiIav+DR+22MA4GA1Ud\n"+ + "DwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEASZK8o+6svfoNyYt5hhwjdrCA\n"+ + "WXf82n+0S9/DZEtqTg6t8n1ZdwWtColzsPq8y9yNAIiPpqCy6qxSJ7+hSHyXEHu6\n"+ + "7RMdmgduyzFiEuhjA6p9beP4G3YheBufS0OM00mG9htc9i5gFdPp43t1P9ACg9AY\n"+ + "gkHNZTfqjjJ+vWuZXTARyNtIVBw74acT02pIk/c9jH8F6M7ziCpjBLjqflh8AXtb\n"+ + "4cV97yHgjQ5dUX2xZ/2jvTg2xvI4hocalmhgRvsoFEdV4aeADGvi6t9NfJBIoDa9\n"+ + "CReJf8Py05yc493EG931t3GzUwWJBtDLSoDByFOQtTwxiBdQn8nEDovYqAJjDQ==\n"+ + "-----END CERTIFICATE-----"); + super.addPEMCertificate("beTRUSTed Root CA - Entrust Implementation", + // X500 Subject, for lookups. + "MGYxEjAQBgNVBAoTCWJlVFJVU1RlZDEbMBkGA1UECxMSYmVUUlVTVGVkIFJvb3QgQ0FzMTMwMQYD"+ + "VQQDEypiZVRSVVNUZWQgUm9vdCBDQSAtIEVudHJ1c3QgSW1wbGVtZW50YXRpb24=", + "-----BEGIN CERTIFICATE-----\n"+ + "MIIGUTCCBTmgAwIBAgIEPLVPQDANBgkqhkiG9w0BAQUFADBmMRIwEAYDVQQKEwli\n"+ + "ZVRSVVNUZWQxGzAZBgNVBAsTEmJlVFJVU1RlZCBSb290IENBczEzMDEGA1UEAxMq\n"+ + "YmVUUlVTVGVkIFJvb3QgQ0EgLSBFbnRydXN0IEltcGxlbWVudGF0aW9uMB4XDTAy\n"+ + "MDQxMTA4MjQyN1oXDTIyMDQxMTA4NTQyN1owZjESMBAGA1UEChMJYmVUUlVTVGVk\n"+ + "MRswGQYDVQQLExJiZVRSVVNUZWQgUm9vdCBDQXMxMzAxBgNVBAMTKmJlVFJVU1Rl\n"+ + "ZCBSb290IENBIC0gRW50cnVzdCBJbXBsZW1lbnRhdGlvbjCCASIwDQYJKoZIhvcN\n"+ + "AQEBBQADggEPADCCAQoCggEBALr0RAOqEmq1Q+xVkrYwfTVXDNvzDSduTPdQqJtO\n"+ + "K2/b9a0cS12zqcH+e0TrW6MFDR/FNCswACnxeECypP869AGIF37m1CbTukzqMvtD\n"+ + "d5eHI8XbQ6P1KqNRXuE70mVpflUVm3rnafdE4Fe1FehmYA8NA/uCjqPoEXtsvsdj\n"+ + "DheT389Lrm5zdeDzqrmkwAkbhepxKYhBMvnwKg5sCfJ0a2ZsUhMfGLzUPvfYbiCe\n"+ + "yv78IZTuEyhL11xeDGbu6bsPwTSxfwh28z0mcMmLJR1iJAzqHHVOwBLkuhMdMCkt\n"+ + "VjMFu5dZfsZJT4nXLySotohAtWSSU1Yk5KKghbNekLQSM80CAwEAAaOCAwUwggMB\n"+ + "MIIBtwYDVR0gBIIBrjCCAaowggGmBg8rBgEEAbE+AAACCSiDkTEwggGRMIIBSQYI\n"+ + "KwYBBQUHAgIwggE7GoIBN1JlbGlhbmNlIG9uIG9yIHVzZSBvZiB0aGlzIENlcnRp\n"+ + "ZmljYXRlIGNyZWF0ZXMgYW4gYWNrbm93bGVkZ21lbnQgYW5kIGFjY2VwdGFuY2Ug\n"+ + "b2YgdGhlIHRoZW4gYXBwbGljYWJsZSBzdGFuZGFyZCB0ZXJtcyBhbmQgY29uZGl0\n"+ + "aW9ucyBvZiB1c2UsIHRoZSBDZXJ0aWZpY2F0aW9uIFByYWN0aWNlIFN0YXRlbWVu\n"+ + "dCBhbmQgdGhlIFJlbHlpbmcgUGFydHkgQWdyZWVtZW50LCB3aGljaCBjYW4gYmUg\n"+ + "Zm91bmQgYXQgdGhlIGJlVFJVU1RlZCB3ZWIgc2l0ZSwgaHR0cHM6Ly93d3cuYmV0\n"+ + "cnVzdGVkLmNvbS9wcm9kdWN0c19zZXJ2aWNlcy9pbmRleC5odG1sMEIGCCsGAQUF\n"+ + "BwIBFjZodHRwczovL3d3dy5iZXRydXN0ZWQuY29tL3Byb2R1Y3RzX3NlcnZpY2Vz\n"+ + "L2luZGV4Lmh0bWwwEQYJYIZIAYb4QgEBBAQDAgAHMIGJBgNVHR8EgYEwfzB9oHug\n"+ + "eaR3MHUxEjAQBgNVBAoTCWJlVFJVU1RlZDEbMBkGA1UECxMSYmVUUlVTVGVkIFJv\n"+ + "b3QgQ0FzMTMwMQYDVQQDEypiZVRSVVNUZWQgUm9vdCBDQSAtIEVudHJ1c3QgSW1w\n"+ + "bGVtZW50YXRpb24xDTALBgNVBAMTBENSTDEwKwYDVR0QBCQwIoAPMjAwMjA0MTEw\n"+ + "ODI0MjdagQ8yMDIyMDQxMTA4NTQyN1owCwYDVR0PBAQDAgEGMB8GA1UdIwQYMBaA\n"+ + "FH1w5a44iwY/qhwaj/nPJDCqhIQWMB0GA1UdDgQWBBR9cOWuOIsGP6ocGo/5zyQw\n"+ + "qoSEFjAMBgNVHRMEBTADAQH/MB0GCSqGSIb2fQdBAAQQMA4bCFY2LjA6NC4wAwIE\n"+ + "kDANBgkqhkiG9w0BAQUFAAOCAQEAKrgXzh8QlOu4mre5X+za95IkrNySO8cgjfKZ\n"+ + "5V04ocI07cUTWVwFtStPYZuR+0H8/NU8TZh2BvWBfevdkObRVlTa4y0MnxEylCIB\n"+ + "evZsLHRnBMylj44ss0O1lKLQfelifwa+JwGDnjr9iu6YQ0pr17WXOzq/T220Y/oz\n"+ + "ADQuLW2WyXvKmWO6vvT2MKAtmJbpVkQFqUSjYRDrgqFnXbxdJ3Wqiig2KjiS2d2k\n"+ + "XgClzMx8KSreKJCrt+G2/30lC0DYqjSjLd4H61/OCt3Kfjp9JsFiaDrmLzfzgYYh\n"+ + "xKlkqu9FNtEaZnz46TfW1mG+oq1I59/mdP7TbX3SJdysYlep9w==\n"+ + "-----END CERTIFICATE-----"); + super.addPEMCertificate("beTRUSTed Root CA - RSA Implementation", + // X500 Subject, for lookups. + "MGIxEjAQBgNVBAoTCWJlVFJVU1RlZDEbMBkGA1UECxMSYmVUUlVTVGVkIFJvb3QgQ0FzMS8wLQYD"+ + "VQQDEyZiZVRSVVNUZWQgUm9vdCBDQSAtIFJTQSBJbXBsZW1lbnRhdGlvbg==", + "-----BEGIN CERTIFICATE-----\n"+ + "MIIFaDCCBFCgAwIBAgIQO1nHe81bV569N1KsdrSqGjANBgkqhkiG9w0BAQUFADBi\n"+ + "MRIwEAYDVQQKEwliZVRSVVNUZWQxGzAZBgNVBAsTEmJlVFJVU1RlZCBSb290IENB\n"+ + "czEvMC0GA1UEAxMmYmVUUlVTVGVkIFJvb3QgQ0EgLSBSU0EgSW1wbGVtZW50YXRp\n"+ + "b24wHhcNMDIwNDExMTExODEzWhcNMjIwNDEyMTEwNzI1WjBiMRIwEAYDVQQKEwli\n"+ + "ZVRSVVNUZWQxGzAZBgNVBAsTEmJlVFJVU1RlZCBSb290IENBczEvMC0GA1UEAxMm\n"+ + "YmVUUlVTVGVkIFJvb3QgQ0EgLSBSU0EgSW1wbGVtZW50YXRpb24wggEiMA0GCSqG\n"+ + "SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDkujQwCY5X0LkGLG9uJIAiv11DpvpPrILn\n"+ + "HGhwhRujbrWqeNluB0s/6d/16uhUoWGKDi9pdRi3DOUUjXFumLhV/AyV0Jtu4S2I\n"+ + "1DpAa5LxmZZk3tv/ePTulh1HiXzUvrmIdyM6CeYEnm2qXtLIvZpOGd+J6lsOfsPk\n"+ + "tPDgaTuID0GQ+NRxQyTBjyZLO1bp/4xsN+lFrYWMU8NghpBKlsmzVLC7F/AcRdnU\n"+ + "GxlkVgoZ98zh/4avflherHqQH8koOUV7orbHnB/ahdQhhlkwk75TMzf270HPM8er\n"+ + "cmsl9fNTGwxMLvF1S++gh/f+ihXQbNXL+WhTuXAVE8L1LvtDNXUtAgMBAAGjggIY\n"+ + "MIICFDAMBgNVHRMEBTADAQH/MIIBtQYDVR0gBIIBrDCCAagwggGkBg8rBgEEAbE+\n"+ + "AAADCSiDkTEwggGPMEEGCCsGAQUFBwIBFjVodHRwOi8vd3d3LmJldHJ1c3RlZC5j\n"+ + "b20vcHJvZHVjdHNfc2VydmljZXMvaW5kZXguaHRtbDCCAUgGCCsGAQUFBwICMIIB\n"+ + "OhqCATZSZWxpYW5jZSBvbiBvciB1c2Ugb2YgdGhpcyBDZXJ0aWZpY2F0ZSBjcmVh\n"+ + "dGVzIGFuIGFja25vd2xlZGdtZW50IGFuZCBhY2NlcHRhbmNlIG9mIHRoZSB0aGVu\n"+ + "IGFwcGxpY2FibGUgc3RhbmRhcmQgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YgdXNl\n"+ + "LCB0aGUgQ2VydGlmaWNhdGlvbiBQcmFjdGljZSBTdGF0ZW1lbnQgYW5kIHRoZSBS\n"+ + "ZWx5aW5nIFBhcnR5IEFncmVlbWVudCwgd2hpY2ggY2FuIGJlIGZvdW5kIGF0IHRo\n"+ + "ZSBiZVRSVVNUZWQgd2ViIHNpdGUsIGh0dHA6Ly93d3cuYmV0cnVzdGVkLmNvbS9w\n"+ + "cm9kdWN0c19zZXJ2aWNlcy9pbmRleC5odG1sMAsGA1UdDwQEAwIBBjAfBgNVHSME\n"+ + "GDAWgBSp7BR++dlDzFMrFK3P9/BZiUHNGTAdBgNVHQ4EFgQUqewUfvnZQ8xTKxSt\n"+ + "z/fwWYlBzRkwDQYJKoZIhvcNAQEFBQADggEBANuXsHXqDMTBmMpWBcCorSZIry0g\n"+ + "6IHHtt9DwSwddUvUQo3neqh03GZCWYez9Wlt2ames30cMcH1VOJZJEnl7r05pmuK\n"+ + "mET7m9cqg5c0Lcd9NUwtNLg+DcTsiCevnpL9UGGCqGAHFFPMZRPB9kdEadIxyKbd\n"+ + "LrML3kqNWz2rDcI1UqJWN8wyiyiFQpyRQHpwKzg21eFzGh/l+n5f3NacOzDq28Bb\n"+ + "J1zTcwfBwvNMm2+fG8oeqqg4MwlYsq78B+g23FW6L09A/nq9BqaBwZMifIYRCgZ3\n"+ + "SK41ty8ymmFei74pnykkiFY5LKjSq5YDWtRIn7lAhAuYaPsBQ9Yb4gmxlxw=\n"+ + "-----END CERTIFICATE-----"); + super.addPEMCertificate("RSA Security 2048 v3", + // X500 Subject, for lookups. + "MDoxGTAXBgNVBAoTEFJTQSBTZWN1cml0eSBJbmMxHTAbBgNVBAsTFFJTQSBTZWN1cml0eSAyMDQ4"+ + "IFYz", + "-----BEGIN CERTIFICATE-----\n"+ + "MIIDYTCCAkmgAwIBAgIQCgEBAQAAAnwAAAAKAAAAAjANBgkqhkiG9w0BAQUFADA6\n"+ + "MRkwFwYDVQQKExBSU0EgU2VjdXJpdHkgSW5jMR0wGwYDVQQLExRSU0EgU2VjdXJp\n"+ + "dHkgMjA0OCBWMzAeFw0wMTAyMjIyMDM5MjNaFw0yNjAyMjIyMDM5MjNaMDoxGTAX\n"+ + "BgNVBAoTEFJTQSBTZWN1cml0eSBJbmMxHTAbBgNVBAsTFFJTQSBTZWN1cml0eSAy\n"+ + "MDQ4IFYzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAt49VcdKA3Xtp\n"+ + "eafwGFAyPGJn9gqVB93mG/Oe2dJBVGutn3y+Gc37RqtBaB4Y6lXIL5F4iSj7Jylg\n"+ + "/9+PjDvJSZu1pJTOAeo+tWN7fyb9Gd3AIb2E0S1PRsNO3Ng3OTsor8udGuorryGl\n"+ + "wSMiuLgbWhOHV4PR8CDn6E8jQrAApX2J6elhc5SYcSa8LWrg903w8bYqODGBDSnh\n"+ + "AMFRD0xS+ARaqn1y07iHKrtjEAMqs6FPDVpeRrc9DvV07Jmf+T0kgYim3WBU6JU2\n"+ + "PcYJk5qjEoAAVZkZR73QpXzDuvsf9/UP+Ky5tfQ3mBMY3oVbtwyCO4dvlTlYMNpu\n"+ + "AWgXIszACwIDAQABo2MwYTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB\n"+ + "BjAfBgNVHSMEGDAWgBQHw1EwpKrpRa41JPr/JCwz0LGdjDAdBgNVHQ4EFgQUB8NR\n"+ + "MKSq6UWuNST6/yQsM9CxnYwwDQYJKoZIhvcNAQEFBQADggEBAF8+hnZuuDU8TjYc\n"+ + "HnmYv/3VEhF5Ug7uMYm83X/50cYVIeiKAVQNOvtUudZj1LGqlk2iQk3UUx+LEN5/\n"+ + "Zb5gEydxiKRz44Rj0aRV4VCT5hsOedBnvEbIvz8XDZXmxpBp3ue0L96VfdASPz0+\n"+ + "f00/FGj1EVDVwfSQpQgdMWD/YIwjVAqv/qFuxdF6Kmh4zx6CCiC0H63lhbJqaHVO\n"+ + "rSU3lIW+vaHU6rcMSzyd6BIA8F+sDeGscGNz9395nzIlQnQFgCi/vcEkllgVsRch\n"+ + "6YlL2weIZ/QVrXA+L02FO8K32/6YaCOJ4XQP3vTFhGMpG8zLB8kApKnXwiJPZ9d3\n"+ + "7CAFYd4=\n"+ + "-----END CERTIFICATE-----"); + super.addPEMCertificate("RSA Security 1024 v3", + // X500 Subject, for lookups. + "MDoxGTAXBgNVBAoTEFJTQSBTZWN1cml0eSBJbmMxHTAbBgNVBAsTFFJTQSBTZWN1cml0eSAxMDI0"+ + "IFYz", + "-----BEGIN CERTIFICATE-----\n"+ + "MIICXDCCAcWgAwIBAgIQCgEBAQAAAnwAAAALAAAAAjANBgkqhkiG9w0BAQUFADA6\n"+ + "MRkwFwYDVQQKExBSU0EgU2VjdXJpdHkgSW5jMR0wGwYDVQQLExRSU0EgU2VjdXJp\n"+ + "dHkgMTAyNCBWMzAeFw0wMTAyMjIyMTAxNDlaFw0yNjAyMjIyMDAxNDlaMDoxGTAX\n"+ + "BgNVBAoTEFJTQSBTZWN1cml0eSBJbmMxHTAbBgNVBAsTFFJTQSBTZWN1cml0eSAx\n"+ + "MDI0IFYzMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDV3f5mCc8kPD6ugU5O\n"+ + "isRpgFtZO9+5TUzKtS3DJy08rwBCbbwoppbPf9dYrIMKo1W1exeQFYRMiu4mmdxY\n"+ + "78c4pqqv0I5CyGLXq6yp+0p9v+r+Ek3d/yYtbzZUaMjShFbuklNhCbM/OZuoyZu9\n"+ + "zp9+1BlqFikYvtc6adwlWzMaUQIDAQABo2MwYTAPBgNVHRMBAf8EBTADAQH/MA4G\n"+ + "A1UdDwEB/wQEAwIBBjAfBgNVHSMEGDAWgBTEwBykB5T9zU0B1FTapQxf3q4FWjAd\n"+ + "BgNVHQ4EFgQUxMAcpAeU/c1NAdRU2qUMX96uBVowDQYJKoZIhvcNAQEFBQADgYEA\n"+ + "Py1q4yZDlX2Jl2X7deRyHUZXxGFraZ8SmyzVWujAovBDleMf6XbN3Ou8k6BlCsdN\n"+ + "T1+nr6JGFLkM88y9am63nd4lQtBU/55oc2PcJOsiv6hy8l4A4Q1OOkNumU4/iXgD\n"+ + "mMrzVcydro7BqkWY+o8aoI2II/EVQQ2lRj6RP4vr93E=\n"+ + "-----END CERTIFICATE-----"); + super.addPEMCertificate("GeoTrust Global CA", + // X500 Subject, for lookups. + "MEIxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVz"+ + "dCBHbG9iYWwgQ0E=", + "-----BEGIN CERTIFICATE-----\n"+ + "MIIDVDCCAjygAwIBAgIDAjRWMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVT\n"+ + "MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i\n"+ + "YWwgQ0EwHhcNMDIwNTIxMDQwMDAwWhcNMjIwNTIxMDQwMDAwWjBCMQswCQYDVQQG\n"+ + "EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEbMBkGA1UEAxMSR2VvVHJ1c3Qg\n"+ + "R2xvYmFsIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2swYYzD9\n"+ + "9BcjGlZ+W988bDjkcbd4kdS8odhM+KhDtgPpTSEHCIjaWC9mOSm9BXiLnTjoBbdq\n"+ + "fnGk5sRgprDvgOSJKA+eJdbtg/OtppHHmMlCGDUUna2YRpIuT8rxh0PBFpVXLVDv\n"+ + "iS2Aelet8u5fa9IAjbkU+BQVNdnARqN7csiRv8lVK83Qlz6cJmTM386DGXHKTubU\n"+ + "1XupGc1V3sjs0l44U+VcT4wt/lAjNvxm5suOpDkZALeVAjmRCw7+OC7RHQWa9k0+\n"+ + "bw8HHa8sHo9gOeL6NlMTOdReJivbPagUvTLrGAMoUgRx5aszPeE4uwc2hGKceeoW\n"+ + "MPRfwCvocWvk+QIDAQABo1MwUTAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTA\n"+ + "ephojYn7qwVkDBF9qn1luMrMTjAfBgNVHSMEGDAWgBTAephojYn7qwVkDBF9qn1l\n"+ + "uMrMTjANBgkqhkiG9w0BAQUFAAOCAQEANeMpauUvXVSOKVCUn5kaFOSPeCpilKIn\n"+ + "Z57QzxpeR+nBsqTP3UEaBU6bS+5Kb1VSsyShNwrrZHYqLizz/Tt1kL/6cdjHPTfS\n"+ + "tQWVYrmm3ok9Nns4d0iXrKYgjy6myQzCsplFAMfOEVEiIuCl6rYVSAlk6l5PdPcF\n"+ + "PseKUgzbFbS9bZvlxrFUaKnjaZC2mqUPuLk/IH2uSrW4nOQdtqvmlKXBx4Ot2/Un\n"+ + "hw4EbNX/3aBd7YdStysVAq45pmp06drE57xNNB6pXE0zX5IJL4hmXXeXxx12E6nV\n"+ + "5fEWCRE11azbJHFwLJhWC9kXtNHjUStedejV0NxPNO3CBWaAocvmMw==\n"+ + "-----END CERTIFICATE-----"); + super.addPEMCertificate("GeoTrust Global CA 2", + // X500 Subject, for lookups. + "MEQxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMR0wGwYDVQQDExRHZW9UcnVz"+ + "dCBHbG9iYWwgQ0EgMg==", + "-----BEGIN CERTIFICATE-----\n"+ + "MIIDZjCCAk6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBEMQswCQYDVQQGEwJVUzEW\n"+ + "MBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEdMBsGA1UEAxMUR2VvVHJ1c3QgR2xvYmFs\n"+ + "IENBIDIwHhcNMDQwMzA0MDUwMDAwWhcNMTkwMzA0MDUwMDAwWjBEMQswCQYDVQQG\n"+ + "EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEdMBsGA1UEAxMUR2VvVHJ1c3Qg\n"+ + "R2xvYmFsIENBIDIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDvPE1A\n"+ + "PRDfO1MA4Wf+lGAVPoWI8YkNkMgoI5kF6CsgncbzYEbYwbLVjDHZ3CB5JIG/NTL8\n"+ + "Y2nbsSpr7iFY8gjpeMtvy/wWUsiRxP89c96xPqfCfWbB9X5SJBri1WeR0IIQ13hL\n"+ + "TytCOb1kLUCgsBDTOEhGiKEMuzozKmKY+wCdE1l/bztyqu6mD4b5BWHqZ38MN5aL\n"+ + "5mkWRxHCJ1kDs6ZgwiFAVvqgx306E+PsV8ez1q6diYD3Aecs9pYrEw15LNnA5IZ7\n"+ + "S4wMcoKK+xfNAGw6EzywhIdLFnopsk/bHdQL82Y3vdj2V7teJHq4PIu5+pIaGoSe\n"+ + "2HSPqht/XvT+RSIhAgMBAAGjYzBhMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYE\n"+ + "FHE4NvICMVNHK266ZUapEBVYIAUJMB8GA1UdIwQYMBaAFHE4NvICMVNHK266ZUap\n"+ + "EBVYIAUJMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQUFAAOCAQEAA/e1K6td\n"+ + "EPx7srJerJsOflN4WT5CBP51o62sgU7XAotexC3IUnbHLB/8gTKY0UvGkpMzNTEv\n"+ + "/NgdRN3ggX+d6YvhZJFiCzkIjKx0nVnZellSlxG5FntvRdOW2TF9AjYPnDtuzywN\n"+ + "A0ZF66D0f0hExghAzN4bcLUprbqLOzRldRtxIR0sFAqwlpW41uryZfspuk/qkZN0\n"+ + "abby/+Ea0AzRdoXLiiW9l14sbxWZJue2Kf8i7MkCx1YAzUm5s2x7UwQa4qjJqhIF\n"+ + "I8LO57sEAszAR6LkxCkvW0VXiVHuPOtSCP8HNR6fNWpHSlaY0VqFH4z1Ir+rzoPz\n"+ + "4iIprn2DQKi6bA==\n"+ + "-----END CERTIFICATE-----"); + super.addPEMCertificate("GeoTrust Universal CA", + // X500 Subject, for lookups. + "MEUxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMR4wHAYDVQQDExVHZW9UcnVz"+ + "dCBVbml2ZXJzYWwgQ0E=", + "-----BEGIN CERTIFICATE-----\n"+ + "MIIFaDCCA1CgAwIBAgIBATANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQGEwJVUzEW\n"+ + "MBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEeMBwGA1UEAxMVR2VvVHJ1c3QgVW5pdmVy\n"+ + "c2FsIENBMB4XDTA0MDMwNDA1MDAwMFoXDTI5MDMwNDA1MDAwMFowRTELMAkGA1UE\n"+ + "BhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xHjAcBgNVBAMTFUdlb1RydXN0\n"+ + "IFVuaXZlcnNhbCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAKYV\n"+ + "VaCjxuAfjJ0hUNfBvitbtaSeodlyWL0AG0y/YckUHUWCq8YdgNY96xCcOq9tJPi8\n"+ + "cQGeBvV8Xx7BDlXKg5pZMK4ZyzBIle0iN430SppyZj6tlcDgFgDgEB8rMQ7XlFTT\n"+ + "QjOgNB0eRXbdT8oYN+yFFXoZCPzVx5zw8qkuEKmS5j1YPakWaDwvdSEYfyh3peFh\n"+ + "F7em6fgemdtzbvQKoiFs7tqqhZJmr/Z6a4LauiIINQ/PQvE1+mrufislzDoR5G2v\n"+ + "c7J2Ha3QsnhnGqQ5HFELZ1aD/ThdDc7d8Lsrlh/eezJS/R27tQahsiFepdaVaH/w\n"+ + "mZ7cRQg+59IJDTWU3YBOU5fXtQlEIGQWFwMCTFMNaN7VqnJNk22CDtucvc+081xd\n"+ + "VHppCZbW2xHBjXWotM85yM48vCR85mLK4b19p71XZQvk/iXttmkQ3CgaRr0BHdCX\n"+ + "teGYO8A3ZNY9lO4L4fUorgtWv3GLIylBjobFS1J72HGrH4oVpjuDWtdYAVHGTEHZ\n"+ + "f9hBZ3KiKN9gg6meyHv8U3NyWfWTehd2Ds735VzZC1U0oqpbtWpU5xPKV+yXbfRe\n"+ + "Bi9Fi1jUIxaS5BZuKGNZMN9QAZxjiRqf2xeUgnA3wySemkfWWspOqGmJch+RbNt+\n"+ + "nhutxx9z3SxPGWX9f5NAEC7S8O08ni4oPmkmM8V7AgMBAAGjYzBhMA8GA1UdEwEB\n"+ + "/wQFMAMBAf8wHQYDVR0OBBYEFNq7LqqwDLiIJlF0XG0D08DYj3rWMB8GA1UdIwQY\n"+ + "MBaAFNq7LqqwDLiIJlF0XG0D08DYj3rWMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG\n"+ + "9w0BAQUFAAOCAgEAMXjmx7XfuJRAyXHEqDXsRh3ChfMoWIawC/yOsjmPRFWrZIRc\n"+ + "aanQmjg8+uUfNeVE44B5lGiku8SfPeE0zTBGi1QrlaXv9z+ZhP015s8xxtxqv6fX\n"+ + "IwjhmF7DWgh2qaavdy+3YL1ERmrvl/9zlcGO6JP7/TG37FcREUWbMPEaiDnBTzyn\n"+ + "ANXH/KttgCJwpQzgXQQpAvvLoJHRfNbDflDVnVi+QTjruXU8FdmbyUqDWcDaU/0z\n"+ + "uzYYm4UPFd3uLax2k7nZAY1IEKj79TiG8dsKxr2EoyNB3tZ3b4XUhRxQ4K5RirqN\n"+ + "Pnbiucon8l+f725ZDQbYKxek0nxru18UGkiPGkzns0ccjkxFKyDuSN/n3QmOGKja\n"+ + "QI2SJhFTYXNd673nxE0pN2HrrDktZy4W1vUAg4WhzH92xH3kt0tm7wNFYGm2DFKW\n"+ + "koRepqO1pD4r2czYG0eq8kTaT/kD6PAUyz/zg97QwVTjt+gKN02LIFkDMBmhLMi9\n"+ + "ER/frslKxfMnZmaGrGiR/9nmUxwPi1xpZQomyB40w11Re9epnAahNt3ViZS82eQt\n"+ + "DF4JbAiXfKM9fJP/P6EUp8+1Xevb2xzEdt+Iub1FBZUbrvxGakyvSOPOrg/Sfuvm\n"+ + "bJxPgWp6ZKy7PtXny3YuxadIwVyQD8vIP/rmMuGNG2+k5o7Y+SlIis5z/iw=\n"+ + "-----END CERTIFICATE-----"); + super.addPEMCertificate("GeoTrust Universal CA 2", + // X500 Subject, for lookups. + "MEcxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMSAwHgYDVQQDExdHZW9UcnVz"+ + "dCBVbml2ZXJzYWwgQ0EgMg==", + "-----BEGIN CERTIFICATE-----\n"+ + "MIIFbDCCA1SgAwIBAgIBATANBgkqhkiG9w0BAQUFADBHMQswCQYDVQQGEwJVUzEW\n"+ + "MBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEgMB4GA1UEAxMXR2VvVHJ1c3QgVW5pdmVy\n"+ + "c2FsIENBIDIwHhcNMDQwMzA0MDUwMDAwWhcNMjkwMzA0MDUwMDAwWjBHMQswCQYD\n"+ + "VQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEgMB4GA1UEAxMXR2VvVHJ1\n"+ + "c3QgVW5pdmVyc2FsIENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC\n"+ + "AQCzVFLByT7y2dyxUxpZKeexw0Uo5dfR7cXFS6GqdHtXr0om/Nj1XqduGdt0DE81\n"+ + "WzILAePb63p3NeqqWuDW6KFXlPCQo3RWlEQwAx5cTiuFJnSCegx2oG9NzkEtoBUG\n"+ + "FF+3Qs17j1hhNNwqCPkuwwGmIkQcTAeC5lvO0Ep8BNMZcyfwqph/Lq9O64ceJHdq\n"+ + "XbboW0W63MOhBW9Wjo8QJqVJwy7XQYci4E+GymC16qFjwAGXEHm9ADwSbSsVsaxL\n"+ + "se4YuU6W3Nx2/zu+z18DwPw76L5GG//aQMJS9/7jOvdqdzXQ2o3rXhhqMcceujwb\n"+ + "KNZrVMaqW9eiLBsZzKIC9ptZvTdrhrVtgrrY6slWvKk2WP0+GfPtDCapkzj4T8Fd\n"+ + "IgbQl+rhrcZV4IErKIM6+vR7IVEAvlI4zs1meaj0gVbi0IMJR1FbUGrP20gaXT73\n"+ + "y/Zl92zxlfgCOzJWgjl6W70viRu/obTo/3+NjN8D8WBOWBFM66M/ECuDmgFz2ZRt\n"+ + "hAAnZqzwcEAJQpKtT5MNYQlRJNiS1QuUYbKHsu3/mjX/hVTK7URDrBs8FmtISgoc\n"+ + "QIgfksILAAX/8sgCSqSqqcyZlpwvWOB94b67B9xfBHJcMTTD7F8t4D1kkCLm0ey4\n"+ + "Lt1ZrtmhN79UNdxzMk+MBB4zsslG8dhcyFVQyWi9qLo2CQIDAQABo2MwYTAPBgNV\n"+ + "HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR281Xh+qQ2+/CfXGJx7Tz0RzgQKzAfBgNV\n"+ + "HSMEGDAWgBR281Xh+qQ2+/CfXGJx7Tz0RzgQKzAOBgNVHQ8BAf8EBAMCAYYwDQYJ\n"+ + "KoZIhvcNAQEFBQADggIBAGbBxiPz2eAubl/oz66wsCVNK/g7WJtAJDday6sWSf+z\n"+ + "dXkzoS9tcBc0kf5nfo/sm+VegqlVHy/c1FEHEv6sFj4sNcZj/NwQ6w2jqtB8zNHQ\n"+ + "L1EuxBRa3ugZ4T7GzKQp5y6EqgYweHZUcyiYWTjgAA1i00J9IZ+uPTqM1fp3DRgr\n"+ + "Fg5fNuH8KrUwJM/gYwx7WBr+mbpCErGR9Hxo4sjoryzqyX6uuyo9DRXcNJW2GHSo\n"+ + "ag/HtPQTxORb7QrSpJdMKu0vbBKJPfEncKpqA1Ihn0CoZ1Dy81of398j9tx4TuaY\n"+ + "T1U6U+Pv8vSfx3zYWK8pIpe44L2RLrB27FcRz+8pRPPphXpgY+RdM4kX2TGq2tbz\n"+ + "GDVyz4crL2MjhF2EjD9XoIj8mZEoJmmZ1I+XRL6O1UixpCgp8RW04eWe3fiPpm8m\n"+ + "1wk8OhwRDqZsN/etRIcsKMfYdIKz0G9KV7s1KSegi+ghp4dkNl3M2Basx7InQJJV\n"+ + "OCiNUW7dFGdTbHFcJoRNdVq2fmBWqU2t+5sel/MN2dKXVHfaPRK34B7vCAas+YWH\n"+ + "6aLcr34YEoP9VhdBLtUpgn2Z9DH2canPLAEnpQW5qrJITirvn5NSUZU8UnOOVkwX\n"+ + "QMAJKOSLakhT2+zNVVXxxvjpoixMptEmX36vWkzaH6byHCx+rgIW0lbQL1dTR+iS\n"+ + "-----END CERTIFICATE-----"); + super.addPEMCertificate("UTN-USER First-Network Applications", + // X500 Subject, for lookups. + "MIGjMQswCQYDVQQGEwJVUzELMAkGA1UECBMCVVQxFzAVBgNVBAcTDlNhbHQgTGFrZSBDaXR5MR4w"+ + "HAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxITAfBgNVBAsTGGh0dHA6Ly93d3cudXNlcnRy"+ + "dXN0LmNvbTErMCkGA1UEAxMiVVROLVVTRVJGaXJzdC1OZXR3b3JrIEFwcGxpY2F0aW9ucw==", + "-----BEGIN CERTIFICATE-----\n"+ + "MIIEZDCCA0ygAwIBAgIQRL4Mi1AAJLQR0zYwS8AzdzANBgkqhkiG9w0BAQUFADCB\n"+ + "ozELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2Ug\n"+ + "Q2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExho\n"+ + "dHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xKzApBgNVBAMTIlVUTi1VU0VSRmlyc3Qt\n"+ + "TmV0d29yayBBcHBsaWNhdGlvbnMwHhcNOTkwNzA5MTg0ODM5WhcNMTkwNzA5MTg1\n"+ + "NzQ5WjCBozELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0\n"+ + "IExha2UgQ2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYD\n"+ + "VQQLExhodHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xKzApBgNVBAMTIlVUTi1VU0VS\n"+ + "Rmlyc3QtTmV0d29yayBBcHBsaWNhdGlvbnMwggEiMA0GCSqGSIb3DQEBAQUAA4IB\n"+ + "DwAwggEKAoIBAQCz+5Gh5DZVhawGNFugmliy+LUPBXeDrjKxdpJo7CNKyXY/45y2\n"+ + "N3kDuatpjQclthln5LAbGHNhSuh+zdMvZOOmfAz6F4CjDUeJT1FxL+78P/m4FoCH\n"+ + "iZMlIJpDgmkkdihZNaEdwH+DBmQWICzTSaSFtMBhf1EI+GgVkYDLpdXuOzr0hARe\n"+ + "YFmnjDRy7rh4xdE7EkpvfmUnuaRVxblvQ6TFHSyZwFKkeEwVs0CYCGtDxgGwenv1\n"+ + "axwiP8vv/6jQOkt2FZ7S0cYu49tXGzKiuG/ohqY/cKvlcJKrRB5AUPuco2LkbG6g\n"+ + "yN7igEL66S/ozjIEj3yNtxyjNTwV3Z7DrpelAgMBAAGjgZEwgY4wCwYDVR0PBAQD\n"+ + "AgHGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFPqGydvguul49Uuo1hXf8NPh\n"+ + "ahQ8ME8GA1UdHwRIMEYwRKBCoECGPmh0dHA6Ly9jcmwudXNlcnRydXN0LmNvbS9V\n"+ + "VE4tVVNFUkZpcnN0LU5ldHdvcmtBcHBsaWNhdGlvbnMuY3JsMA0GCSqGSIb3DQEB\n"+ + "BQUAA4IBAQCk8yXM0dSRgyLQzDKrm5ZONJFUICU0YV8qAhXhi6r/fWRRzwr/vH3Y\n"+ + "IWp4yy9Rb/hCHTO967V7lMPDqaAt39EpHx3+jz+7qEUqf9FuVSTiuwL7MT++6Lzs\n"+ + "QCv4AdRWOOTKRIK1YSAhZ2X28AvnNPilwpyjXEAfhZOVBt5P1CeptqX8Fs1zMT+4\n"+ + "ZSfP1FMa8Kxun08FDAOBp4QpxFq9ZFdyrTvPNximmMatBrTcCKME1SmklpoSZ0qM\n"+ + "YEWd8SOasACcaLWYUNPvji6SZbFIPiG+FTAqDbUMo2s/rn9X9R+WfN9v3YIwLGUb\n"+ + "QErNaLly7HF27FSOH4UMAWr6pjisH8SE\n"+ + "-----END CERTIFICATE-----"); + super.addPEMCertificate("America Online Root Certification Authority 1", + // X500 Subject, for lookups. + "MGMxCzAJBgNVBAYTAlVTMRwwGgYDVQQKExNBbWVyaWNhIE9ubGluZSBJbmMuMTYwNAYDVQQDEy1B"+ + "bWVyaWNhIE9ubGluZSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IDE=", + "-----BEGIN CERTIFICATE-----\n"+ + "MIIDpDCCAoygAwIBAgIBATANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEc\n"+ + "MBoGA1UEChMTQW1lcmljYSBPbmxpbmUgSW5jLjE2MDQGA1UEAxMtQW1lcmljYSBP\n"+ + "bmxpbmUgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAxMB4XDTAyMDUyODA2\n"+ + "MDAwMFoXDTM3MTExOTIwNDMwMFowYzELMAkGA1UEBhMCVVMxHDAaBgNVBAoTE0Ft\n"+ + "ZXJpY2EgT25saW5lIEluYy4xNjA0BgNVBAMTLUFtZXJpY2EgT25saW5lIFJvb3Qg\n"+ + "Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkgMTCCASIwDQYJKoZIhvcNAQEBBQADggEP\n"+ + "ADCCAQoCggEBAKgv6KRpBgNHw+kqmP8ZonCaxlCyfqXfaE0bfA+2l2h9LaaLl+lk\n"+ + "hsmj76CGv2BlnEtUiMJIxUo5vxTjWVXlGbR0yLQFOVwWpeKVBeASrlmLojNoWBym\n"+ + "1BW32J/X3HGrfpq/m44zDyL9Hy7nBzbvYjnF3cu6JRQj3gzGPTzOggjmZj7aUTsW\n"+ + "OqMFf6Dch9Wc/HKpoH145LcxVR5lu9RhsCFg7RAycsWSJR74kEoYeEfffjA3PlAb\n"+ + "2xzTa5qGUwew76wGePiEmf4hjUyAtgyC9mZweRrTT6PP8c9GsEsPPt2IYriMqQko\n"+ + "O3rHl+Ee5fSfwMCuJKDIodkP1nsmgmkyPacCAwEAAaNjMGEwDwYDVR0TAQH/BAUw\n"+ + "AwEB/zAdBgNVHQ4EFgQUAK3Zo/Z59m50qX8zPYEX10zPM94wHwYDVR0jBBgwFoAU\n"+ + "AK3Zo/Z59m50qX8zPYEX10zPM94wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEB\n"+ + "BQUAA4IBAQB8itEfGDeC4Liwo+1WlchiYZwFos3CYiZhzRAW18y0ZTTQEYqtqKkF\n"+ + "Zu90821fnZmv9ov761KyBZiibyrFVL0lvV+uyIbqRizBs73B6UlwGBaXCBOMIOAb\n"+ + "LjpHyx7kADCVW/RFo8AasAFOq73AI25jP4BKxQft3OJvx8Fi8eNy1gTIdGcL+oir\n"+ + "oQHIb/AUr9KZzVGTfu0uOMe9zkZQPXLjeSWdm4grECDdpbgyn43gKd8hdIaC2y+C\n"+ + "MMbHNYaz+ZZfRtsMRf3zUMNvxsNIrUam4SdHCh0Om7bCd39j8uB9Gr784N/Xx6ds\n"+ + "sPmuujz9dLQR6FgNgLzTqIA6me11zEZ7\n"+ + "-----END CERTIFICATE-----"); + super.addPEMCertificate("America Online Root Certification Authority 2", + // X500 Subject, for lookups. + "MGMxCzAJBgNVBAYTAlVTMRwwGgYDVQQKExNBbWVyaWNhIE9ubGluZSBJbmMuMTYwNAYDVQQDEy1B"+ + "bWVyaWNhIE9ubGluZSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IDI=", + "-----BEGIN CERTIFICATE-----\n"+ + "MIIFpDCCA4ygAwIBAgIBATANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEc\n"+ + "MBoGA1UEChMTQW1lcmljYSBPbmxpbmUgSW5jLjE2MDQGA1UEAxMtQW1lcmljYSBP\n"+ + "bmxpbmUgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAyMB4XDTAyMDUyODA2\n"+ + "MDAwMFoXDTM3MDkyOTE0MDgwMFowYzELMAkGA1UEBhMCVVMxHDAaBgNVBAoTE0Ft\n"+ + "ZXJpY2EgT25saW5lIEluYy4xNjA0BgNVBAMTLUFtZXJpY2EgT25saW5lIFJvb3Qg\n"+ + "Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkgMjCCAiIwDQYJKoZIhvcNAQEBBQADggIP\n"+ + "ADCCAgoCggIBAMxBRR3pPU0Q9oyxQcngXssNt79Hc9PwVU3dxgz6sWYFas14tNwC\n"+ + "206B89enfHG8dWOgXeMHDEjsJcQDIPT/DjsS/5uN4cbVG7RtIuOx238hZK+GvFci\n"+ + "KtZHgVdEglZTvYYUAQv8f3SkWq7xuhG1m1hagLQ3eAkzfDJHA1zEpYNI9FdWboE2\n"+ + "JxhP7JsowtS013wMPgwr38oE18aO6lhOqKSlGBxsRZijQdEt0sdtjRnxrXm3gT+9\n"+ + "BoInLRBYBbV4Bbkv2wxrkJB+FFk4u5QkE+XRnRTf04JNRvCAOVIyD+OEsnpD8l7e\n"+ + "Xz8d3eOyG6ChKiMDbi4BFYdcpnV1x5dhvt6G3NRI270qv0pV2uh9UPu0gBe4lL8B\n"+ + "PeraunzgWGcXuVjgiIZGZ2ydEEdYMtA1fHkqkKJaEBEjNa0vzORKW6fIJ/KD3l67\n"+ + "Xnfn6KVuY8INXWHQjNJsWiEOyiijzirplcdIz5ZvHZIlyMbGwcEMBawmxNJ10uEq\n"+ + "Z8A9W6Wa6897GqidFEXlD6CaZd4vKL3Ob5Rmg0gp2OpljK+T2WSfVVcmv2/LNzGZ\n"+ + "o2C7HK2JNDJiuEMhBnIMoVxtRsX6Kc8w3onccVvdtjc+31D1uAclJuW8tf48ArO3\n"+ + "+L5DwYcRlJ4jbBeKuIonDFRH8KmzwICMoCfrHRnjB453cMor9H124HhnAgMBAAGj\n"+ + "YzBhMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFE1FwWg4u3OpaaEg5+31IqEj\n"+ + "FNeeMB8GA1UdIwQYMBaAFE1FwWg4u3OpaaEg5+31IqEjFNeeMA4GA1UdDwEB/wQE\n"+ + "AwIBhjANBgkqhkiG9w0BAQUFAAOCAgEAZ2sGuV9FOypLM7PmG2tZTiLMubekJcmn\n"+ + "xPBUlgtk87FYT15R/LKXeydlwuXK5w0MJXti4/qftIe3RUavg6WXSIylvfEWK5t2\n"+ + "LHo1YGwRgJfMqZJS5ivmae2p+DYtLHe/YUjRYwu5W1LtGLBDQiKmsXeu3mnFzccc\n"+ + "obGlHBD7GL4acN3Bkku+KVqdPzW+5X1R+FXgJXUjhx5c3LqdsKyzadsXg8n33gy8\n"+ + "CNyRnqjQ1xU3c6U1uPx+xURABsPr+CKAXEfOAuMRn0T//ZoyzH1kUQ7rVyZ2OuMe\n"+ + "IjzCpjbdGe+n/BLzJsBZMYVMnNjP36TMzCmT/5RtdlwTCJfy7aULTd3oyWgOZtMA\n"+ + "DjMSW7yV5TKQqLPGbIOtd+6Lfn6xqavT4fG2wLHqiMDn05DpKJKUe2h7lyoKZy2F\n"+ + "AjgQ5ANh1NolNscIWC2hp1GvMApJ9aZphwctREZ2jirlmjvXGKL8nDgQzMY70rUX\n"+ + "Om/9riW99XJZZLF0KjhfGEzfz3EEWjbUvy+ZnOjZurGV5gJLIaFb1cFPj65pbVPb\n"+ + "AZO1XB4Y3WRayhgoPmMEEf0cjQAPuDffZ4qdZqkCapH/E8ovXYO8h5Ns3CRRFgQl\n"+ + "Zvqz2cK6Kb6aSDiCmfS/O0oxGfm/jiEzFMpPVF/7zvuPcX/9XhmgD0uRuMRUvAaw\n"+ + "RY8mkaKO/qk=\n"+ + "-----END CERTIFICATE-----"); + super.addPEMCertificate("Visa eCommerce Root", + // X500 Subject, for lookups. + "MGsxCzAJBgNVBAYTAlVTMQ0wCwYDVQQKEwRWSVNBMS8wLQYDVQQLEyZWaXNhIEludGVybmF0aW9u"+ + "YWwgU2VydmljZSBBc3NvY2lhdGlvbjEcMBoGA1UEAxMTVmlzYSBlQ29tbWVyY2UgUm9vdA==", + "-----BEGIN CERTIFICATE-----\n"+ + "MIIDojCCAoqgAwIBAgIQE4Y1TR0/BvLB+WUF1ZAcYjANBgkqhkiG9w0BAQUFADBr\n"+ + "MQswCQYDVQQGEwJVUzENMAsGA1UEChMEVklTQTEvMC0GA1UECxMmVmlzYSBJbnRl\n"+ + "cm5hdGlvbmFsIFNlcnZpY2UgQXNzb2NpYXRpb24xHDAaBgNVBAMTE1Zpc2EgZUNv\n"+ + "bW1lcmNlIFJvb3QwHhcNMDIwNjI2MDIxODM2WhcNMjIwNjI0MDAxNjEyWjBrMQsw\n"+ + "CQYDVQQGEwJVUzENMAsGA1UEChMEVklTQTEvMC0GA1UECxMmVmlzYSBJbnRlcm5h\n"+ + "dGlvbmFsIFNlcnZpY2UgQXNzb2NpYXRpb24xHDAaBgNVBAMTE1Zpc2EgZUNvbW1l\n"+ + "cmNlIFJvb3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvV95WHm6h\n"+ + "2mCxlCfLF9sHP4CFT8icttD0b0/Pmdjh28JIXDqsOTPHH2qLJj0rNfVIsZHBAk4E\n"+ + "lpF7sDPwsRROEW+1QK8bRaVK7362rPKgH1g/EkZgPI2h4H3PVz4zHvtH8aoVlwdV\n"+ + "ZqW1LS7YgFmypw23RuwhY/81q6UCzyr0TP579ZRdhE2o8mCP2w4lPJ9zcc+U30rq\n"+ + "299yOIzzlr3xF7zSujtFWsan9sYXiwGd/BmoKoMWuDpI/k4+oKsGGelT84ATB+0t\n"+ + "vz8KPFUgOSwsAGl0lUq8ILKpeeUYiZGo3BxN77t+Nwtd/jmliFKMAGzsGHxBvfaL\n"+ + "dXe6YJ2E5/4tAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQD\n"+ + "AgEGMB0GA1UdDgQWBBQVOIMPPyw/cDMezUb+B4wg4NfDtzANBgkqhkiG9w0BAQUF\n"+ + "AAOCAQEAX/FBfXxcCLkr4NWSR/pnXKUTwwMhmytMiUbPWU3J/qVAtmPN3XEolWcR\n"+ + "zCSs00Rsca4BIGsDoo8Ytyk6feUWYFN4PMCvFYP3j1IzJL1kk5fui/fbGKhtcbP3\n"+ + "LBfQdCVp9/5rPJS+TUtBjE7ic9DjkCJzQ83z7+pzzkWKsKZJ/0x9nXGIxHYdkFsd\n"+ + "7v3M9+79YKWxehZx0RbQfBI8bGmX265fOZpwLwU8GUYEmSA20GBuYQa7FkKMcPcw\n"+ + "++DbZqMAAb3mLNqRX6BGi01qnD093QVG/na/oAo85ADmJ7f/hC3euiInlhBx6yLt\n"+ + "398znM/jra6O1I7mT1GvFpLgXPYHDw==\n"+ + "-----END CERTIFICATE-----"); + super.addPEMCertificate("TC TrustCenter, Germany, Class 2 CA", + // X500 Subject, for lookups. + "MIG8MQswCQYDVQQGEwJERTEQMA4GA1UECBMHSGFtYnVyZzEQMA4GA1UEBxMHSGFtYnVyZzE6MDgG"+ + "A1UEChMxVEMgVHJ1c3RDZW50ZXIgZm9yIFNlY3VyaXR5IGluIERhdGEgTmV0d29ya3MgR21iSDEi"+ + "MCAGA1UECxMZVEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMiBDQTEpMCcGCSqGSIb3DQEJARYaY2VydGlm"+ + "aWNhdGVAdHJ1c3RjZW50ZXIuZGU=", + "-----BEGIN CERTIFICATE-----\n"+ + "MIIDXDCCAsWgAwIBAgICA+owDQYJKoZIhvcNAQEEBQAwgbwxCzAJBgNVBAYTAkRF\n"+ + "MRAwDgYDVQQIEwdIYW1idXJnMRAwDgYDVQQHEwdIYW1idXJnMTowOAYDVQQKEzFU\n"+ + "QyBUcnVzdENlbnRlciBmb3IgU2VjdXJpdHkgaW4gRGF0YSBOZXR3b3JrcyBHbWJI\n"+ + "MSIwIAYDVQQLExlUQyBUcnVzdENlbnRlciBDbGFzcyAyIENBMSkwJwYJKoZIhvcN\n"+ + "AQkBFhpjZXJ0aWZpY2F0ZUB0cnVzdGNlbnRlci5kZTAeFw05ODAzMDkxMTU5NTla\n"+ + "Fw0xMTAxMDExMTU5NTlaMIG8MQswCQYDVQQGEwJERTEQMA4GA1UECBMHSGFtYnVy\n"+ + "ZzEQMA4GA1UEBxMHSGFtYnVyZzE6MDgGA1UEChMxVEMgVHJ1c3RDZW50ZXIgZm9y\n"+ + "IFNlY3VyaXR5IGluIERhdGEgTmV0d29ya3MgR21iSDEiMCAGA1UECxMZVEMgVHJ1\n"+ + "c3RDZW50ZXIgQ2xhc3MgMiBDQTEpMCcGCSqGSIb3DQEJARYaY2VydGlmaWNhdGVA\n"+ + "dHJ1c3RjZW50ZXIuZGUwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANo46O0y\n"+ + "AClxgwENv4wB3NrGrTmkqYov1YtcaF9QxmL1Zr3KkSLsqh1R1z2zUbKDTl3LSbDw\n"+ + "TFXlay3HhQswHJJOgtTKAu33b77c4OMUuAVT8pr0VotanoWT0bSCVq5Nu6hLVxa8\n"+ + "/vhYnvgpjbB7zXjJT6yLZwzxnPv8V5tXXE8NAgMBAAGjazBpMA8GA1UdEwEB/wQF\n"+ + "MAMBAf8wDgYDVR0PAQH/BAQDAgGGMDMGCWCGSAGG+EIBCAQmFiRodHRwOi8vd3d3\n"+ + "LnRydXN0Y2VudGVyLmRlL2d1aWRlbGluZXMwEQYJYIZIAYb4QgEBBAQDAgAHMA0G\n"+ + "CSqGSIb3DQEBBAUAA4GBAIRS+yjf/x91AbwBvgRWl2p0QiQxg/lGsQaKic+WLDO/\n"+ + "jLVfenKhhQbOhvgFjuj5Jcrag4wGrOs2bYWRNAQ29ELw+HkuCkhcq8xRT3h2oNms\n"+ + "Gb0q0WkEKJHKNhAngFdb0lz1wlurZIFjdFH0l7/NEij3TWZ/p/AcASZ4smZHcFFk\n"+ + "-----END CERTIFICATE-----"); + super.addPEMCertificate("TC TrustCenter, Germany, Class 3 CA", + // X500 Subject, for lookups. + "MIG8MQswCQYDVQQGEwJERTEQMA4GA1UECBMHSGFtYnVyZzEQMA4GA1UEBxMHSGFtYnVyZzE6MDgG"+ + "A1UEChMxVEMgVHJ1c3RDZW50ZXIgZm9yIFNlY3VyaXR5IGluIERhdGEgTmV0d29ya3MgR21iSDEi"+ + "MCAGA1UECxMZVEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMyBDQTEpMCcGCSqGSIb3DQEJARYaY2VydGlm"+ + "aWNhdGVAdHJ1c3RjZW50ZXIuZGU=", + "-----BEGIN CERTIFICATE-----\n"+ + "MIIDXDCCAsWgAwIBAgICA+swDQYJKoZIhvcNAQEEBQAwgbwxCzAJBgNVBAYTAkRF\n"+ + "MRAwDgYDVQQIEwdIYW1idXJnMRAwDgYDVQQHEwdIYW1idXJnMTowOAYDVQQKEzFU\n"+ + "QyBUcnVzdENlbnRlciBmb3IgU2VjdXJpdHkgaW4gRGF0YSBOZXR3b3JrcyBHbWJI\n"+ + "MSIwIAYDVQQLExlUQyBUcnVzdENlbnRlciBDbGFzcyAzIENBMSkwJwYJKoZIhvcN\n"+ + "AQkBFhpjZXJ0aWZpY2F0ZUB0cnVzdGNlbnRlci5kZTAeFw05ODAzMDkxMTU5NTla\n"+ + "Fw0xMTAxMDExMTU5NTlaMIG8MQswCQYDVQQGEwJERTEQMA4GA1UECBMHSGFtYnVy\n"+ + "ZzEQMA4GA1UEBxMHSGFtYnVyZzE6MDgGA1UEChMxVEMgVHJ1c3RDZW50ZXIgZm9y\n"+ + "IFNlY3VyaXR5IGluIERhdGEgTmV0d29ya3MgR21iSDEiMCAGA1UECxMZVEMgVHJ1\n"+ + "c3RDZW50ZXIgQ2xhc3MgMyBDQTEpMCcGCSqGSIb3DQEJARYaY2VydGlmaWNhdGVA\n"+ + "dHJ1c3RjZW50ZXIuZGUwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALa0wTUF\n"+ + "Lg2N7KBAahwOJ6ZQkmtQGwfeLud2zODa/ISoXoxjaitN2U4CdhHBC/KNecoAtvGw\n"+ + "Dtf7pBc9r6tpepYnv68zoZoqWarEtTcI8hKlMbZD9TKWcSgoq40oht+77uMMfTDW\n"+ + "w1Krj10nnGvAo+cFa1dJRLNu6mTP0o56UHd3AgMBAAGjazBpMA8GA1UdEwEB/wQF\n"+ + "MAMBAf8wDgYDVR0PAQH/BAQDAgGGMDMGCWCGSAGG+EIBCAQmFiRodHRwOi8vd3d3\n"+ + "LnRydXN0Y2VudGVyLmRlL2d1aWRlbGluZXMwEQYJYIZIAYb4QgEBBAQDAgAHMA0G\n"+ + "CSqGSIb3DQEBBAUAA4GBABY9xs3Bu4VxhUafPiCPUSiZ7C1FIWMjWwS7TJC4iJIE\n"+ + "Tb19AaM/9uzO8d7+feXhPrvGq14L3T2WxMup1Pkm5gZOngylerpuw3yCGdHHsbHD\n"+ + "2w2Om0B8NwvxXej9H5CIpQ5ON2QhqE6NtJ/x3kit1VYYUimLRzQSCdS7kjXvD9s0\n"+ + "-----END CERTIFICATE-----"); + super.addPEMCertificate("Certum Root CA", + // X500 Subject, for lookups. + "MD4xCzAJBgNVBAYTAlBMMRswGQYDVQQKExJVbml6ZXRvIFNwLiB6IG8uby4xEjAQBgNVBAMTCUNl"+ + "cnR1bSBDQQ==", + "-----BEGIN CERTIFICATE-----\n"+ + "MIIDDDCCAfSgAwIBAgIDAQAgMA0GCSqGSIb3DQEBBQUAMD4xCzAJBgNVBAYTAlBM\n"+ + "MRswGQYDVQQKExJVbml6ZXRvIFNwLiB6IG8uby4xEjAQBgNVBAMTCUNlcnR1bSBD\n"+ + "QTAeFw0wMjA2MTExMDQ2MzlaFw0yNzA2MTExMDQ2MzlaMD4xCzAJBgNVBAYTAlBM\n"+ + "MRswGQYDVQQKExJVbml6ZXRvIFNwLiB6IG8uby4xEjAQBgNVBAMTCUNlcnR1bSBD\n"+ + "QTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM6xwS7TT3zNJc4YPk/E\n"+ + "jG+AanPIW1H4m9LcuwBcsaD8dQPugfCI7iNS6eYVM42sLQnFdvkrOYCJ5JdLkKWo\n"+ + "ePhzQ3ukYbDYWMzhbGZ+nPMJXlVjhNWo7/OxLjBos8Q82KxujZlakE403Daaj4GI\n"+ + "ULdtlkIJ89eVgw1BS7Bqa/j8D35in2fE7SZfECYPCE/wpFcozo+47UX2bu4lXapu\n"+ + "Ob7kky/ZR6By6/qmW6/KUz/iDsaWVhFu9+lmqSbYf5VT7QqFiLpPKaVCjF62/IUg\n"+ + "AKpoC6EahQGcxEZjgoi2IrHu/qpGWX7PNSzVttpd90gzFFS269lvzs2I1qsb2pY7\n"+ + "HVkCAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEA\n"+ + "uI3O7+cUus/usESSbLQ5PqKEbq24IXfS1HeCh+YgQYHu4vgRt2PRFze+GXYkHAQa\n"+ + "TOs9qmdvLdTN/mUxcMUbpgIKumB7bVjCmkn+YzILa+M6wKyrO7Do0wlRjBCDxjTg\n"+ + "xSvgGrZgFCdsMneMvLJymM/NzD+5yCRCFNZX/OYmQ6kd5YCQzgNUKD73P9P4Te1q\n"+ + "CjqTE5s7FCMTY5w/0YcneeVMUeMBrYVdGjux1XMQpNPyvG5k9VpWkKjHDkx0Dy5x\n"+ + "O/fIR/RpbxXyEV6DHpx8Uq79AtoSqFlnGNu8cN2bsWntgM6JQEhqDjXKKWYVIZQs\n"+ + "6GAqm4VKQPNriiTsBhYscw==\n"+ + "-----END CERTIFICATE-----"); + super.addPEMCertificate("Comodo AAA Services root", + // X500 Subject, for lookups. + "MHsxCzAJBgNVBAYTAkdCMRswGQYDVQQIDBJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAOBgNVBAcMB1Nh"+ + "bGZvcmQxGjAYBgNVBAoMEUNvbW9kbyBDQSBMaW1pdGVkMSEwHwYDVQQDDBhBQUEgQ2VydGlmaWNh"+ + "dGUgU2VydmljZXM=", + "-----BEGIN CERTIFICATE-----\n"+ + "MIIEMjCCAxqgAwIBAgIBATANBgkqhkiG9w0BAQUFADB7MQswCQYDVQQGEwJHQjEb\n"+ + "MBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRow\n"+ + "GAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDEhMB8GA1UEAwwYQUFBIENlcnRpZmlj\n"+ + "YXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAwMFoXDTI4MTIzMTIzNTk1OVowezEL\n"+ + "MAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE\n"+ + "BwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxITAfBgNVBAMM\n"+ + "GEFBQSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEBBQADggEP\n"+ + "ADCCAQoCggEBAL5AnfRu4ep2hxxNRUSOvkbIgwadwSr+GB+O5AL686tdUIoWMQua\n"+ + "BtDFcCLNSS1UY8y2bmhGC1Pqy0wkwLxyTurxFa70VJoSCsN6sjNg4tqJVfMiWPPe\n"+ + "3M/vg4aijJRPn2jymJBGhCfHdr/jzDUsi14HZGWCwEiwqJH5YZ92IFCokcdmtet4\n"+ + "YgNW8IoaE+oxox6gmf049vYnMlhvB/VruPsUK6+3qszWY19zjNoFmag4qMsXeDZR\n"+ + "rOme9Hg6jc8P2ULimAyrL58OAd7vn5lJ8S3frHRNG5i1R8XlKdH5kBjHYpy+g8cm\n"+ + "ez6KJcfA3Z3mNWgQIJ2P2N7Sw4ScDV7oL8kCAwEAAaOBwDCBvTAdBgNVHQ4EFgQU\n"+ + "oBEKIz6W8Qfs4q8p74Klf9AwpLQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQF\n"+ + "MAMBAf8wewYDVR0fBHQwcjA4oDagNIYyaHR0cDovL2NybC5jb21vZG9jYS5jb20v\n"+ + "QUFBQ2VydGlmaWNhdGVTZXJ2aWNlcy5jcmwwNqA0oDKGMGh0dHA6Ly9jcmwuY29t\n"+ + "b2RvLm5ldC9BQUFDZXJ0aWZpY2F0ZVNlcnZpY2VzLmNybDANBgkqhkiG9w0BAQUF\n"+ + "AAOCAQEACFb8AvCb6P+k+tZ7xkSAzk/ExfYAWMymtrwUSWgEdujm7l3sAg9g1o1Q\n"+ + "GE8mTgHj5rCl7r+8dFRBv/38ErjHT1r0iWAFf2C3BUrz9vHCv8S5dIa2LX1rzNLz\n"+ + "Rt0vxuBqw8M0Ayx9lt1awg6nCpnBBYurDC/zXDrPbDdVCYfeU0BsWO/8tqtlbgT2\n"+ + "G9w84FoVxp7Z8VlIMCFlA2zs6SFz7JsDoeA3raAVGI/6ugLOpyypEBMs1OUIJqsi\n"+ + "l2D4kF501KKaU73yqWjgom7C12yxow+ev+to51byrvLjKzg6CYG1a4XXvi3tPxq3\n"+ + "smPi9WIsgtRqAEFQ8TmDn5XpNpaYbg==\n"+ + "-----END CERTIFICATE-----"); + super.addPEMCertificate("Comodo Secure Services root", + // X500 Subject, for lookups. + "MH4xCzAJBgNVBAYTAkdCMRswGQYDVQQIDBJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAOBgNVBAcMB1Nh"+ + "bGZvcmQxGjAYBgNVBAoMEUNvbW9kbyBDQSBMaW1pdGVkMSQwIgYDVQQDDBtTZWN1cmUgQ2VydGlm"+ + "aWNhdGUgU2VydmljZXM=", + "-----BEGIN CERTIFICATE-----\n"+ + "MIIEPzCCAyegAwIBAgIBATANBgkqhkiG9w0BAQUFADB+MQswCQYDVQQGEwJHQjEb\n"+ + "MBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRow\n"+ + "GAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDEkMCIGA1UEAwwbU2VjdXJlIENlcnRp\n"+ + "ZmljYXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAwMFoXDTI4MTIzMTIzNTk1OVow\n"+ + "fjELMAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G\n"+ + "A1UEBwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxJDAiBgNV\n"+ + "BAMMG1NlY3VyZSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEB\n"+ + "BQADggEPADCCAQoCggEBAMBxM4KK0HDrc4eCQNUd5MvJDkKQ+d40uaG6EfQlhfPM\n"+ + "cm3ye5drswfxdySRXyWP9nQ95IDC+DwN879A6vfIUtFyb+/Iq0G4bi4XKpVpDM3S\n"+ + "HpR7LZQdqnXXs5jLrLxkU0C8j6ysNstcrbvd4JQX7NFc0L/vpZXJkMWwrPsbQ996\n"+ + "CF23uPJAGysnnlDOXmWCiIxe004MeuoIkbY2qitC++rCoznl2yY4rYsK7hljxxwk\n"+ + "3wN42ubqwUcaCwtGCd0C/N7Lh1/XMGNooa7cMqG6vv5Eq2i2pRcV/b3Vp6ea5EQz\n"+ + "6YiO/O1R65NxTq0B50SOqy3LqP4BSUjwwN3HaNiS/j0CAwEAAaOBxzCBxDAdBgNV\n"+ + "HQ4EFgQUPNiTiMLAggnMAZkGkyDpnnAJY08wDgYDVR0PAQH/BAQDAgEGMA8GA1Ud\n"+ + "EwEB/wQFMAMBAf8wgYEGA1UdHwR6MHgwO6A5oDeGNWh0dHA6Ly9jcmwuY29tb2Rv\n"+ + "Y2EuY29tL1NlY3VyZUNlcnRpZmljYXRlU2VydmljZXMuY3JsMDmgN6A1hjNodHRw\n"+ + "Oi8vY3JsLmNvbW9kby5uZXQvU2VjdXJlQ2VydGlmaWNhdGVTZXJ2aWNlcy5jcmww\n"+ + "DQYJKoZIhvcNAQEFBQADggEBAIcBbSMdflsXfcFhMs+P5/OKlFlm4J4oqF7Tt/Q0\n"+ + "5qo5spcWxYJvMqTpjOev/e/C6LlLqqP05tqNZSH7uoDrJiiFGv45jN5bBAS0VPmj\n"+ + "Z55B+glSzAVIqMk/IQQezkhr/IXownuvf7fM+F86/TXGDe+X3EyrEeFryzHRbPtI\n"+ + "gKvcnDe4IRRLDXE97IMzbtFuMhbsmMcWi1mmNKsFVy2T96oTy9IT4rcuO81rUBcJ\n"+ + "aD61JlfutuC23bkpgHl9j6PwpCikFcSF9CfUa7/lXORlAnZUtOM3ZiTTGWHIUhDl\n"+ + "izeauan5Hb/qmZJhlv8BzaFfDbxxvA6sCx1HRR3B7Hzs/Sk=\n"+ + "-----END CERTIFICATE-----"); + super.addPEMCertificate("Comodo Trusted Services root", + // X500 Subject, for lookups. + "MH8xCzAJBgNVBAYTAkdCMRswGQYDVQQIDBJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAOBgNVBAcMB1Nh"+ + "bGZvcmQxGjAYBgNVBAoMEUNvbW9kbyBDQSBMaW1pdGVkMSUwIwYDVQQDDBxUcnVzdGVkIENlcnRp"+ + "ZmljYXRlIFNlcnZpY2Vz", + "-----BEGIN CERTIFICATE-----\n"+ + "MIIEQzCCAyugAwIBAgIBATANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJHQjEb\n"+ + "MBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRow\n"+ + "GAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDElMCMGA1UEAwwcVHJ1c3RlZCBDZXJ0\n"+ + "aWZpY2F0ZSBTZXJ2aWNlczAeFw0wNDAxMDEwMDAwMDBaFw0yODEyMzEyMzU5NTla\n"+ + "MH8xCzAJBgNVBAYTAkdCMRswGQYDVQQIDBJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAO\n"+ + "BgNVBAcMB1NhbGZvcmQxGjAYBgNVBAoMEUNvbW9kbyBDQSBMaW1pdGVkMSUwIwYD\n"+ + "VQQDDBxUcnVzdGVkIENlcnRpZmljYXRlIFNlcnZpY2VzMIIBIjANBgkqhkiG9w0B\n"+ + "AQEFAAOCAQ8AMIIBCgKCAQEA33FvNlhTWvI2VFeAxHQIIO0Yfyod5jWaHiWsnOWW\n"+ + "fnJSoBVC21ndZHoa0Lh73TkVvFVIxO06AOoxEbrycXQaZ7jPM8yoMa+j49d/vzMt\n"+ + "TGo87IvDktJTdyR0nAducPy9C1t2ul/y/9c3S0pgePfw+spwtOpZqqPOSC+pw7IL\n"+ + "fhdyFgymBwwbOM/JYrc/oJOlh0Hyt3BAd9i+FHzjqMB6juljatEPmsbS9Is6FARW\n"+ + "1O24zG71++IsWL1/T2sr92AkWCTOJu80kTrV44HQsvAEAtdbtz6SrGsSivnkBbA7\n"+ + "kUlcsutT6vifR4buv5XAwAaf0lteERv0xwQ1KdJVXOTt6wIDAQABo4HJMIHGMB0G\n"+ + "A1UdDgQWBBTFe1i97doladL3WRaoszLAeydb9DAOBgNVHQ8BAf8EBAMCAQYwDwYD\n"+ + "VR0TAQH/BAUwAwEB/zCBgwYDVR0fBHwwejA8oDqgOIY2aHR0cDovL2NybC5jb21v\n"+ + "ZG9jYS5jb20vVHJ1c3RlZENlcnRpZmljYXRlU2VydmljZXMuY3JsMDqgOKA2hjRo\n"+ + "dHRwOi8vY3JsLmNvbW9kby5uZXQvVHJ1c3RlZENlcnRpZmljYXRlU2VydmljZXMu\n"+ + "Y3JsMA0GCSqGSIb3DQEBBQUAA4IBAQDIk4E7ibSvuIQSTI3S8NtwuleGFTQQuS9/\n"+ + "HrCoiWChisJ3DFBKmwCL2Iv0QeLQg4pKHBQGsKNoBXAxMKdTmw7pSqBYaWcOrp32\n"+ + "pSxBvzwGa+RZzG0Q8ZZvH9/0BAKkn0U+yNj6NkZEUD+Cl5EfKNsYEYwq5GWDVxIS\n"+ + "jBc/lDb+XbDABHcTuPQV1T84zJQ6VdCsmPW6AF/ghhmBeC8owH7TzEIK9a5QoNE+\n"+ + "xqFx7D+gIIxmOom0jtTYsU0lR+4viMi14QVFwL4Ucd56/Y57fU0IlqUSc/Atyjcn\n"+ + "dBInTMu2l+nZrghtWjlA3QVHdWpaIbOjGM9O9y5Xt5hwXsjEeLBi\n"+ + "-----END CERTIFICATE-----"); + super.addPEMCertificate("IPS Chained CAs root", + // X500 Subject, for lookups. + "MIIBHDELMAkGA1UEBhMCRVMxEjAQBgNVBAgTCUJhcmNlbG9uYTESMBAGA1UEBxMJQmFyY2Vsb25h"+ + "MS4wLAYDVQQKEyVJUFMgSW50ZXJuZXQgcHVibGlzaGluZyBTZXJ2aWNlcyBzLmwuMSswKQYDVQQK"+ + "FCJpcHNAbWFpbC5pcHMuZXMgQy5JLkYuICBCLTYwOTI5NDUyMTMwMQYDVQQLEypJUFMgQ0EgQ2hh"+ + "aW5lZCBDQXMgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxMzAxBgNVBAMTKklQUyBDQSBDaGFpbmVk"+ + "IENBcyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEeMBwGCSqGSIb3DQEJARYPaXBzQG1haWwuaXBz"+ + "LmVz", + "-----BEGIN CERTIFICATE-----\n"+ + "MIIH9zCCB2CgAwIBAgIBADANBgkqhkiG9w0BAQUFADCCARwxCzAJBgNVBAYTAkVT\n"+ + "MRIwEAYDVQQIEwlCYXJjZWxvbmExEjAQBgNVBAcTCUJhcmNlbG9uYTEuMCwGA1UE\n"+ + "ChMlSVBTIEludGVybmV0IHB1Ymxpc2hpbmcgU2VydmljZXMgcy5sLjErMCkGA1UE\n"+ + "ChQiaXBzQG1haWwuaXBzLmVzIEMuSS5GLiAgQi02MDkyOTQ1MjEzMDEGA1UECxMq\n"+ + "SVBTIENBIENoYWluZWQgQ0FzIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MTMwMQYD\n"+ + "VQQDEypJUFMgQ0EgQ2hhaW5lZCBDQXMgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkx\n"+ + "HjAcBgkqhkiG9w0BCQEWD2lwc0BtYWlsLmlwcy5lczAeFw0wMTEyMjkwMDUzNTha\n"+ + "Fw0yNTEyMjcwMDUzNThaMIIBHDELMAkGA1UEBhMCRVMxEjAQBgNVBAgTCUJhcmNl\n"+ + "bG9uYTESMBAGA1UEBxMJQmFyY2Vsb25hMS4wLAYDVQQKEyVJUFMgSW50ZXJuZXQg\n"+ + "cHVibGlzaGluZyBTZXJ2aWNlcyBzLmwuMSswKQYDVQQKFCJpcHNAbWFpbC5pcHMu\n"+ + "ZXMgQy5JLkYuICBCLTYwOTI5NDUyMTMwMQYDVQQLEypJUFMgQ0EgQ2hhaW5lZCBD\n"+ + "QXMgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxMzAxBgNVBAMTKklQUyBDQSBDaGFp\n"+ + "bmVkIENBcyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEeMBwGCSqGSIb3DQEJARYP\n"+ + "aXBzQG1haWwuaXBzLmVzMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDcVpJJ\n"+ + "spQgvJhPUOtopKdJC7/SMejHT8KGC/po/UNaivNgkjWZOLtNA1IhW/A3mTXhQSCB\n"+ + "hYEFcYGdtJUZqV92NC5jNzVXjrQfQj8VXOF6wV8TGDIxya2+o8eDZh65nAQTy2nB\n"+ + "Bt4wBrszo7Uf8I9vzv+W6FS+ZoCua9tBhDaiPQIDAQABo4IEQzCCBD8wHQYDVR0O\n"+ + "BBYEFKGtMbH5PuEXpsirNPxShwkeYlJBMIIBTgYDVR0jBIIBRTCCAUGAFKGtMbH5\n"+ + "PuEXpsirNPxShwkeYlJBoYIBJKSCASAwggEcMQswCQYDVQQGEwJFUzESMBAGA1UE\n"+ + "CBMJQmFyY2Vsb25hMRIwEAYDVQQHEwlCYXJjZWxvbmExLjAsBgNVBAoTJUlQUyBJ\n"+ + "bnRlcm5ldCBwdWJsaXNoaW5nIFNlcnZpY2VzIHMubC4xKzApBgNVBAoUImlwc0Bt\n"+ + "YWlsLmlwcy5lcyBDLkkuRi4gIEItNjA5Mjk0NTIxMzAxBgNVBAsTKklQUyBDQSBD\n"+ + "aGFpbmVkIENBcyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEzMDEGA1UEAxMqSVBT\n"+ + "IENBIENoYWluZWQgQ0FzIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MR4wHAYJKoZI\n"+ + "hvcNAQkBFg9pcHNAbWFpbC5pcHMuZXOCAQAwDAYDVR0TBAUwAwEB/zAMBgNVHQ8E\n"+ + "BQMDB/+AMGsGA1UdJQRkMGIGCCsGAQUFBwMBBggrBgEFBQcDAgYIKwYBBQUHAwMG\n"+ + "CCsGAQUFBwMEBggrBgEFBQcDCAYKKwYBBAGCNwIBFQYKKwYBBAGCNwIBFgYKKwYB\n"+ + "BAGCNwoDAQYKKwYBBAGCNwoDBDARBglghkgBhvhCAQEEBAMCAAcwGgYDVR0RBBMw\n"+ + "EYEPaXBzQG1haWwuaXBzLmVzMBoGA1UdEgQTMBGBD2lwc0BtYWlsLmlwcy5lczBC\n"+ + "BglghkgBhvhCAQ0ENRYzQ2hhaW5lZCBDQSBDZXJ0aWZpY2F0ZSBpc3N1ZWQgYnkg\n"+ + "aHR0cDovL3d3dy5pcHMuZXMvMCkGCWCGSAGG+EIBAgQcFhpodHRwOi8vd3d3Lmlw\n"+ + "cy5lcy9pcHMyMDAyLzA3BglghkgBhvhCAQQEKhYoaHR0cDovL3d3dy5pcHMuZXMv\n"+ + "aXBzMjAwMi9pcHMyMDAyQ0FDLmNybDA8BglghkgBhvhCAQMELxYtaHR0cDovL3d3\n"+ + "dy5pcHMuZXMvaXBzMjAwMi9yZXZvY2F0aW9uQ0FDLmh0bWw/MDkGCWCGSAGG+EIB\n"+ + "BwQsFipodHRwOi8vd3d3Lmlwcy5lcy9pcHMyMDAyL3JlbmV3YWxDQUMuaHRtbD8w\n"+ + "NwYJYIZIAYb4QgEIBCoWKGh0dHA6Ly93d3cuaXBzLmVzL2lwczIwMDIvcG9saWN5\n"+ + "Q0FDLmh0bWwwbQYDVR0fBGYwZDAuoCygKoYoaHR0cDovL3d3dy5pcHMuZXMvaXBz\n"+ + "MjAwMi9pcHMyMDAyQ0FDLmNybDAyoDCgLoYsaHR0cDovL3d3d2JhY2suaXBzLmVz\n"+ + "L2lwczIwMDIvaXBzMjAwMkNBQy5jcmwwLwYIKwYBBQUHAQEEIzAhMB8GCCsGAQUF\n"+ + "BzABhhNodHRwOi8vb2NzcC5pcHMuZXMvMA0GCSqGSIb3DQEBBQUAA4GBAERyMJ1W\n"+ + "WKJBGyi3leGmGpVfp3hAK+/blkr8THFj2XOVvQLiogbHvpcqk4A0hgP63Ng9HgfN\n"+ + "HnNDJGD1HWHc3JagvPsd4+cSACczAsDAK1M92GsDgaPb1pOVIO/Tln4mkImcJpvN\n"+ + "b2ar7QMiRDjMWb2f2/YHogF/JsRj9SVCXmK9\n"+ + "-----END CERTIFICATE-----"); + super.addPEMCertificate("IPS CLASE1 root", + // X500 Subject, for lookups. + "MIIBEjELMAkGA1UEBhMCRVMxEjAQBgNVBAgTCUJhcmNlbG9uYTESMBAGA1UEBxMJQmFyY2Vsb25h"+ + "MS4wLAYDVQQKEyVJUFMgSW50ZXJuZXQgcHVibGlzaGluZyBTZXJ2aWNlcyBzLmwuMSswKQYDVQQK"+ + "FCJpcHNAbWFpbC5pcHMuZXMgQy5JLkYuICBCLTYwOTI5NDUyMS4wLAYDVQQLEyVJUFMgQ0EgQ0xB"+ + "U0UxIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MS4wLAYDVQQDEyVJUFMgQ0EgQ0xBU0UxIENlcnRp"+ + "ZmljYXRpb24gQXV0aG9yaXR5MR4wHAYJKoZIhvcNAQkBFg9pcHNAbWFpbC5pcHMuZXM=", + "-----BEGIN CERTIFICATE-----\n"+ + "MIIH6jCCB1OgAwIBAgIBADANBgkqhkiG9w0BAQUFADCCARIxCzAJBgNVBAYTAkVT\n"+ + "MRIwEAYDVQQIEwlCYXJjZWxvbmExEjAQBgNVBAcTCUJhcmNlbG9uYTEuMCwGA1UE\n"+ + "ChMlSVBTIEludGVybmV0IHB1Ymxpc2hpbmcgU2VydmljZXMgcy5sLjErMCkGA1UE\n"+ + "ChQiaXBzQG1haWwuaXBzLmVzIEMuSS5GLiAgQi02MDkyOTQ1MjEuMCwGA1UECxMl\n"+ + "SVBTIENBIENMQVNFMSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEuMCwGA1UEAxMl\n"+ + "SVBTIENBIENMQVNFMSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEeMBwGCSqGSIb3\n"+ + "DQEJARYPaXBzQG1haWwuaXBzLmVzMB4XDTAxMTIyOTAwNTkzOFoXDTI1MTIyNzAw\n"+ + "NTkzOFowggESMQswCQYDVQQGEwJFUzESMBAGA1UECBMJQmFyY2Vsb25hMRIwEAYD\n"+ + "VQQHEwlCYXJjZWxvbmExLjAsBgNVBAoTJUlQUyBJbnRlcm5ldCBwdWJsaXNoaW5n\n"+ + "IFNlcnZpY2VzIHMubC4xKzApBgNVBAoUImlwc0BtYWlsLmlwcy5lcyBDLkkuRi4g\n"+ + "IEItNjA5Mjk0NTIxLjAsBgNVBAsTJUlQUyBDQSBDTEFTRTEgQ2VydGlmaWNhdGlv\n"+ + "biBBdXRob3JpdHkxLjAsBgNVBAMTJUlQUyBDQSBDTEFTRTEgQ2VydGlmaWNhdGlv\n"+ + "biBBdXRob3JpdHkxHjAcBgkqhkiG9w0BCQEWD2lwc0BtYWlsLmlwcy5lczCBnzAN\n"+ + "BgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA4FEnpwvdr9G5Q1uCN0VWcu+atsIS7ywS\n"+ + "zHb5BlmvXSHU0lq4oNTzav3KaY1mSPd05u42veiWkXWmcSjK5yISMmmwPh5r9FBS\n"+ + "YmL9Yzt9fuzuOOpi9GyocY3h6YvJP8a1zZRCb92CRTzo3wno7wpVqVZHYUxJZHMQ\n"+ + "KD/Kvwn/xi8CAwEAAaOCBEowggRGMB0GA1UdDgQWBBTrsxl588GlHKzcuh9morKb\n"+ + "adB4CDCCAUQGA1UdIwSCATswggE3gBTrsxl588GlHKzcuh9morKbadB4CKGCARqk\n"+ + "ggEWMIIBEjELMAkGA1UEBhMCRVMxEjAQBgNVBAgTCUJhcmNlbG9uYTESMBAGA1UE\n"+ + "BxMJQmFyY2Vsb25hMS4wLAYDVQQKEyVJUFMgSW50ZXJuZXQgcHVibGlzaGluZyBT\n"+ + "ZXJ2aWNlcyBzLmwuMSswKQYDVQQKFCJpcHNAbWFpbC5pcHMuZXMgQy5JLkYuICBC\n"+ + "LTYwOTI5NDUyMS4wLAYDVQQLEyVJUFMgQ0EgQ0xBU0UxIENlcnRpZmljYXRpb24g\n"+ + "QXV0aG9yaXR5MS4wLAYDVQQDEyVJUFMgQ0EgQ0xBU0UxIENlcnRpZmljYXRpb24g\n"+ + "QXV0aG9yaXR5MR4wHAYJKoZIhvcNAQkBFg9pcHNAbWFpbC5pcHMuZXOCAQAwDAYD\n"+ + "VR0TBAUwAwEB/zAMBgNVHQ8EBQMDB/+AMGsGA1UdJQRkMGIGCCsGAQUFBwMBBggr\n"+ + "BgEFBQcDAgYIKwYBBQUHAwMGCCsGAQUFBwMEBggrBgEFBQcDCAYKKwYBBAGCNwIB\n"+ + "FQYKKwYBBAGCNwIBFgYKKwYBBAGCNwoDAQYKKwYBBAGCNwoDBDARBglghkgBhvhC\n"+ + "AQEEBAMCAAcwGgYDVR0RBBMwEYEPaXBzQG1haWwuaXBzLmVzMBoGA1UdEgQTMBGB\n"+ + "D2lwc0BtYWlsLmlwcy5lczBBBglghkgBhvhCAQ0ENBYyQ0xBU0UxIENBIENlcnRp\n"+ + "ZmljYXRlIGlzc3VlZCBieSBodHRwOi8vd3d3Lmlwcy5lcy8wKQYJYIZIAYb4QgEC\n"+ + "BBwWGmh0dHA6Ly93d3cuaXBzLmVzL2lwczIwMDIvMDoGCWCGSAGG+EIBBAQtFito\n"+ + "dHRwOi8vd3d3Lmlwcy5lcy9pcHMyMDAyL2lwczIwMDJDTEFTRTEuY3JsMD8GCWCG\n"+ + "SAGG+EIBAwQyFjBodHRwOi8vd3d3Lmlwcy5lcy9pcHMyMDAyL3Jldm9jYXRpb25D\n"+ + "TEFTRTEuaHRtbD8wPAYJYIZIAYb4QgEHBC8WLWh0dHA6Ly93d3cuaXBzLmVzL2lw\n"+ + "czIwMDIvcmVuZXdhbENMQVNFMS5odG1sPzA6BglghkgBhvhCAQgELRYraHR0cDov\n"+ + "L3d3dy5pcHMuZXMvaXBzMjAwMi9wb2xpY3lDTEFTRTEuaHRtbDBzBgNVHR8EbDBq\n"+ + "MDGgL6AthitodHRwOi8vd3d3Lmlwcy5lcy9pcHMyMDAyL2lwczIwMDJDTEFTRTEu\n"+ + "Y3JsMDWgM6Axhi9odHRwOi8vd3d3YmFjay5pcHMuZXMvaXBzMjAwMi9pcHMyMDAy\n"+ + "Q0xBU0UxLmNybDAvBggrBgEFBQcBAQQjMCEwHwYIKwYBBQUHMAGGE2h0dHA6Ly9v\n"+ + "Y3NwLmlwcy5lcy8wDQYJKoZIhvcNAQEFBQADgYEAK9Dr/drIyllq2tPMMi7JVBuK\n"+ + "Yn4VLenZMdMu9Ccj/1urxUq2ckCuU3T0vAW0xtnIyXf7t/k0f3gA+Nak5FI/LEpj\n"+ + "V4F1Wo7ojPsCwJTGKbqz3Bzosq/SLmJbGqmODszFV0VRFOlOHIilkfSj945RyKm+\n"+ + "hjM+5i9Ibq9UkE6tsSU=\n"+ + "-----END CERTIFICATE-----"); + super.addPEMCertificate("IPS CLASE3 root", + // X500 Subject, for lookups. + "MIIBEjELMAkGA1UEBhMCRVMxEjAQBgNVBAgTCUJhcmNlbG9uYTESMBAGA1UEBxMJQmFyY2Vsb25h"+ + "MS4wLAYDVQQKEyVJUFMgSW50ZXJuZXQgcHVibGlzaGluZyBTZXJ2aWNlcyBzLmwuMSswKQYDVQQK"+ + "FCJpcHNAbWFpbC5pcHMuZXMgQy5JLkYuICBCLTYwOTI5NDUyMS4wLAYDVQQLEyVJUFMgQ0EgQ0xB"+ + "U0UzIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MS4wLAYDVQQDEyVJUFMgQ0EgQ0xBU0UzIENlcnRp"+ + "ZmljYXRpb24gQXV0aG9yaXR5MR4wHAYJKoZIhvcNAQkBFg9pcHNAbWFpbC5pcHMuZXM=", + "-----BEGIN CERTIFICATE-----\n"+ + "MIIH6jCCB1OgAwIBAgIBADANBgkqhkiG9w0BAQUFADCCARIxCzAJBgNVBAYTAkVT\n"+ + "MRIwEAYDVQQIEwlCYXJjZWxvbmExEjAQBgNVBAcTCUJhcmNlbG9uYTEuMCwGA1UE\n"+ + "ChMlSVBTIEludGVybmV0IHB1Ymxpc2hpbmcgU2VydmljZXMgcy5sLjErMCkGA1UE\n"+ + "ChQiaXBzQG1haWwuaXBzLmVzIEMuSS5GLiAgQi02MDkyOTQ1MjEuMCwGA1UECxMl\n"+ + "SVBTIENBIENMQVNFMyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEuMCwGA1UEAxMl\n"+ + "SVBTIENBIENMQVNFMyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEeMBwGCSqGSIb3\n"+ + "DQEJARYPaXBzQG1haWwuaXBzLmVzMB4XDTAxMTIyOTAxMDE0NFoXDTI1MTIyNzAx\n"+ + "MDE0NFowggESMQswCQYDVQQGEwJFUzESMBAGA1UECBMJQmFyY2Vsb25hMRIwEAYD\n"+ + "VQQHEwlCYXJjZWxvbmExLjAsBgNVBAoTJUlQUyBJbnRlcm5ldCBwdWJsaXNoaW5n\n"+ + "IFNlcnZpY2VzIHMubC4xKzApBgNVBAoUImlwc0BtYWlsLmlwcy5lcyBDLkkuRi4g\n"+ + "IEItNjA5Mjk0NTIxLjAsBgNVBAsTJUlQUyBDQSBDTEFTRTMgQ2VydGlmaWNhdGlv\n"+ + "biBBdXRob3JpdHkxLjAsBgNVBAMTJUlQUyBDQSBDTEFTRTMgQ2VydGlmaWNhdGlv\n"+ + "biBBdXRob3JpdHkxHjAcBgkqhkiG9w0BCQEWD2lwc0BtYWlsLmlwcy5lczCBnzAN\n"+ + "BgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAqxf+DrDGaBtT8FK+n/ra+osTBLsBjzLZ\n"+ + "H49NzjaY2uQARIwo2BNEKqRrThckQpzTiKRBgtYj+4vJhuW5qYIF3PHeH+AMmVWY\n"+ + "8jjsbJ0gA8DvqqPGZARRLXgNo9KoOtYkTOmWehisEyMiG3zoMRGzXwmqMHBxRiVr\n"+ + "SXGAK5UBsh8CAwEAAaOCBEowggRGMB0GA1UdDgQWBBS4k/8uy9wsjqLnev42USGj\n"+ + "mFsMNDCCAUQGA1UdIwSCATswggE3gBS4k/8uy9wsjqLnev42USGjmFsMNKGCARqk\n"+ + "ggEWMIIBEjELMAkGA1UEBhMCRVMxEjAQBgNVBAgTCUJhcmNlbG9uYTESMBAGA1UE\n"+ + "BxMJQmFyY2Vsb25hMS4wLAYDVQQKEyVJUFMgSW50ZXJuZXQgcHVibGlzaGluZyBT\n"+ + "ZXJ2aWNlcyBzLmwuMSswKQYDVQQKFCJpcHNAbWFpbC5pcHMuZXMgQy5JLkYuICBC\n"+ + "LTYwOTI5NDUyMS4wLAYDVQQLEyVJUFMgQ0EgQ0xBU0UzIENlcnRpZmljYXRpb24g\n"+ + "QXV0aG9yaXR5MS4wLAYDVQQDEyVJUFMgQ0EgQ0xBU0UzIENlcnRpZmljYXRpb24g\n"+ + "QXV0aG9yaXR5MR4wHAYJKoZIhvcNAQkBFg9pcHNAbWFpbC5pcHMuZXOCAQAwDAYD\n"+ + "VR0TBAUwAwEB/zAMBgNVHQ8EBQMDB/+AMGsGA1UdJQRkMGIGCCsGAQUFBwMBBggr\n"+ + "BgEFBQcDAgYIKwYBBQUHAwMGCCsGAQUFBwMEBggrBgEFBQcDCAYKKwYBBAGCNwIB\n"+ + "FQYKKwYBBAGCNwIBFgYKKwYBBAGCNwoDAQYKKwYBBAGCNwoDBDARBglghkgBhvhC\n"+ + "AQEEBAMCAAcwGgYDVR0RBBMwEYEPaXBzQG1haWwuaXBzLmVzMBoGA1UdEgQTMBGB\n"+ + "D2lwc0BtYWlsLmlwcy5lczBBBglghkgBhvhCAQ0ENBYyQ0xBU0UzIENBIENlcnRp\n"+ + "ZmljYXRlIGlzc3VlZCBieSBodHRwOi8vd3d3Lmlwcy5lcy8wKQYJYIZIAYb4QgEC\n"+ + "BBwWGmh0dHA6Ly93d3cuaXBzLmVzL2lwczIwMDIvMDoGCWCGSAGG+EIBBAQtFito\n"+ + "dHRwOi8vd3d3Lmlwcy5lcy9pcHMyMDAyL2lwczIwMDJDTEFTRTMuY3JsMD8GCWCG\n"+ + "SAGG+EIBAwQyFjBodHRwOi8vd3d3Lmlwcy5lcy9pcHMyMDAyL3Jldm9jYXRpb25D\n"+ + "TEFTRTMuaHRtbD8wPAYJYIZIAYb4QgEHBC8WLWh0dHA6Ly93d3cuaXBzLmVzL2lw\n"+ + "czIwMDIvcmVuZXdhbENMQVNFMy5odG1sPzA6BglghkgBhvhCAQgELRYraHR0cDov\n"+ + "L3d3dy5pcHMuZXMvaXBzMjAwMi9wb2xpY3lDTEFTRTMuaHRtbDBzBgNVHR8EbDBq\n"+ + "MDGgL6AthitodHRwOi8vd3d3Lmlwcy5lcy9pcHMyMDAyL2lwczIwMDJDTEFTRTMu\n"+ + "Y3JsMDWgM6Axhi9odHRwOi8vd3d3YmFjay5pcHMuZXMvaXBzMjAwMi9pcHMyMDAy\n"+ + "Q0xBU0UzLmNybDAvBggrBgEFBQcBAQQjMCEwHwYIKwYBBQUHMAGGE2h0dHA6Ly9v\n"+ + "Y3NwLmlwcy5lcy8wDQYJKoZIhvcNAQEFBQADgYEAF2VcmZVDAyevJuXr0LMXI/dD\n"+ + "qsfwfewPxqmurpYPdikc4gYtfibFPPqhwYHOU7BC0ZdXGhd+pFFhxu7pXu8Fuuu9\n"+ + "D6eSb9ijBmgpjnn1/7/5p6/ksc7C0YBCJwUENPjDfxZ4IwwHJPJGR607VNCv1TGy\n"+ + "r33I6unUVtkOE7LFRVA=\n"+ + "-----END CERTIFICATE-----"); + super.addPEMCertificate("IPS CLASEA1 root", + // X500 Subject, for lookups. + "MIIBFDELMAkGA1UEBhMCRVMxEjAQBgNVBAgTCUJhcmNlbG9uYTESMBAGA1UEBxMJQmFyY2Vsb25h"+ + "MS4wLAYDVQQKEyVJUFMgSW50ZXJuZXQgcHVibGlzaGluZyBTZXJ2aWNlcyBzLmwuMSswKQYDVQQK"+ + "FCJpcHNAbWFpbC5pcHMuZXMgQy5JLkYuICBCLTYwOTI5NDUyMS8wLQYDVQQLEyZJUFMgQ0EgQ0xB"+ + "U0VBMSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEvMC0GA1UEAxMmSVBTIENBIENMQVNFQTEgQ2Vy"+ + "dGlmaWNhdGlvbiBBdXRob3JpdHkxHjAcBgkqhkiG9w0BCQEWD2lwc0BtYWlsLmlwcy5lcw==", + "-----BEGIN CERTIFICATE-----\n"+ + "MIIH9zCCB2CgAwIBAgIBADANBgkqhkiG9w0BAQUFADCCARQxCzAJBgNVBAYTAkVT\n"+ + "MRIwEAYDVQQIEwlCYXJjZWxvbmExEjAQBgNVBAcTCUJhcmNlbG9uYTEuMCwGA1UE\n"+ + "ChMlSVBTIEludGVybmV0IHB1Ymxpc2hpbmcgU2VydmljZXMgcy5sLjErMCkGA1UE\n"+ + "ChQiaXBzQG1haWwuaXBzLmVzIEMuSS5GLiAgQi02MDkyOTQ1MjEvMC0GA1UECxMm\n"+ + "SVBTIENBIENMQVNFQTEgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxLzAtBgNVBAMT\n"+ + "JklQUyBDQSBDTEFTRUExIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MR4wHAYJKoZI\n"+ + "hvcNAQkBFg9pcHNAbWFpbC5pcHMuZXMwHhcNMDExMjI5MDEwNTMyWhcNMjUxMjI3\n"+ + "MDEwNTMyWjCCARQxCzAJBgNVBAYTAkVTMRIwEAYDVQQIEwlCYXJjZWxvbmExEjAQ\n"+ + "BgNVBAcTCUJhcmNlbG9uYTEuMCwGA1UEChMlSVBTIEludGVybmV0IHB1Ymxpc2hp\n"+ + "bmcgU2VydmljZXMgcy5sLjErMCkGA1UEChQiaXBzQG1haWwuaXBzLmVzIEMuSS5G\n"+ + "LiAgQi02MDkyOTQ1MjEvMC0GA1UECxMmSVBTIENBIENMQVNFQTEgQ2VydGlmaWNh\n"+ + "dGlvbiBBdXRob3JpdHkxLzAtBgNVBAMTJklQUyBDQSBDTEFTRUExIENlcnRpZmlj\n"+ + "YXRpb24gQXV0aG9yaXR5MR4wHAYJKoZIhvcNAQkBFg9pcHNAbWFpbC5pcHMuZXMw\n"+ + "gZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALsw19zQVL01Tp/FTILq0VA8R5j8\n"+ + "m2mdd81u4D/u6zJfX5/S0HnllXNEITLgCtud186Nq1KLK3jgm1t99P1tCeWu4Wwd\n"+ + "ByOgF9H5fahGRpEiqLJpxq339fWUoTCUvQDMRH/uxJ7JweaPCjbB/SQ9AaD1e+J8\n"+ + "eGZDi09Z8pvZ+kmzAgMBAAGjggRTMIIETzAdBgNVHQ4EFgQUZyaW56G/2LUDnf47\n"+ + "3P7yiuYV3TAwggFGBgNVHSMEggE9MIIBOYAUZyaW56G/2LUDnf473P7yiuYV3TCh\n"+ + "ggEcpIIBGDCCARQxCzAJBgNVBAYTAkVTMRIwEAYDVQQIEwlCYXJjZWxvbmExEjAQ\n"+ + "BgNVBAcTCUJhcmNlbG9uYTEuMCwGA1UEChMlSVBTIEludGVybmV0IHB1Ymxpc2hp\n"+ + "bmcgU2VydmljZXMgcy5sLjErMCkGA1UEChQiaXBzQG1haWwuaXBzLmVzIEMuSS5G\n"+ + "LiAgQi02MDkyOTQ1MjEvMC0GA1UECxMmSVBTIENBIENMQVNFQTEgQ2VydGlmaWNh\n"+ + "dGlvbiBBdXRob3JpdHkxLzAtBgNVBAMTJklQUyBDQSBDTEFTRUExIENlcnRpZmlj\n"+ + "YXRpb24gQXV0aG9yaXR5MR4wHAYJKoZIhvcNAQkBFg9pcHNAbWFpbC5pcHMuZXOC\n"+ + "AQAwDAYDVR0TBAUwAwEB/zAMBgNVHQ8EBQMDB/+AMGsGA1UdJQRkMGIGCCsGAQUF\n"+ + "BwMBBggrBgEFBQcDAgYIKwYBBQUHAwMGCCsGAQUFBwMEBggrBgEFBQcDCAYKKwYB\n"+ + "BAGCNwIBFQYKKwYBBAGCNwIBFgYKKwYBBAGCNwoDAQYKKwYBBAGCNwoDBDARBglg\n"+ + "hkgBhvhCAQEEBAMCAAcwGgYDVR0RBBMwEYEPaXBzQG1haWwuaXBzLmVzMBoGA1Ud\n"+ + "EgQTMBGBD2lwc0BtYWlsLmlwcy5lczBCBglghkgBhvhCAQ0ENRYzQ0xBU0VBMSBD\n"+ + "QSBDZXJ0aWZpY2F0ZSBpc3N1ZWQgYnkgaHR0cDovL3d3dy5pcHMuZXMvMCkGCWCG\n"+ + "SAGG+EIBAgQcFhpodHRwOi8vd3d3Lmlwcy5lcy9pcHMyMDAyLzA7BglghkgBhvhC\n"+ + "AQQELhYsaHR0cDovL3d3dy5pcHMuZXMvaXBzMjAwMi9pcHMyMDAyQ0xBU0VBMS5j\n"+ + "cmwwQAYJYIZIAYb4QgEDBDMWMWh0dHA6Ly93d3cuaXBzLmVzL2lwczIwMDIvcmV2\n"+ + "b2NhdGlvbkNMQVNFQTEuaHRtbD8wPQYJYIZIAYb4QgEHBDAWLmh0dHA6Ly93d3cu\n"+ + "aXBzLmVzL2lwczIwMDIvcmVuZXdhbENMQVNFQTEuaHRtbD8wOwYJYIZIAYb4QgEI\n"+ + "BC4WLGh0dHA6Ly93d3cuaXBzLmVzL2lwczIwMDIvcG9saWN5Q0xBU0VBMS5odG1s\n"+ + "MHUGA1UdHwRuMGwwMqAwoC6GLGh0dHA6Ly93d3cuaXBzLmVzL2lwczIwMDIvaXBz\n"+ + "MjAwMkNMQVNFQTEuY3JsMDagNKAyhjBodHRwOi8vd3d3YmFjay5pcHMuZXMvaXBz\n"+ + "MjAwMi9pcHMyMDAyQ0xBU0VBMS5jcmwwLwYIKwYBBQUHAQEEIzAhMB8GCCsGAQUF\n"+ + "BzABhhNodHRwOi8vb2NzcC5pcHMuZXMvMA0GCSqGSIb3DQEBBQUAA4GBAH66iqyA\n"+ + "AIQVCtWYUQxkxZwCWINmyq0eB81+atqAB98DNEock8RLWCA1NnHtogo1EqWmZaeF\n"+ + "aQoO42Hu6r4okzPV7Oi+xNtff6j5YzHIa5biKcJboOeXNp13XjFr/tOn2yrb25aL\n"+ + "H2betgPAK7N41lUH5Y85UN4HI3LmvSAUS7SG\n"+ + "-----END CERTIFICATE-----"); + super.addPEMCertificate("IPS CLASEA3 root", + // X500 Subject, for lookups. + "MIIBFDELMAkGA1UEBhMCRVMxEjAQBgNVBAgTCUJhcmNlbG9uYTESMBAGA1UEBxMJQmFyY2Vsb25h"+ + "MS4wLAYDVQQKEyVJUFMgSW50ZXJuZXQgcHVibGlzaGluZyBTZXJ2aWNlcyBzLmwuMSswKQYDVQQK"+ + "FCJpcHNAbWFpbC5pcHMuZXMgQy5JLkYuICBCLTYwOTI5NDUyMS8wLQYDVQQLEyZJUFMgQ0EgQ0xB"+ + "U0VBMyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEvMC0GA1UEAxMmSVBTIENBIENMQVNFQTMgQ2Vy"+ + "dGlmaWNhdGlvbiBBdXRob3JpdHkxHjAcBgkqhkiG9w0BCQEWD2lwc0BtYWlsLmlwcy5lcw==", + "-----BEGIN CERTIFICATE-----\n"+ + "MIIH9zCCB2CgAwIBAgIBADANBgkqhkiG9w0BAQUFADCCARQxCzAJBgNVBAYTAkVT\n"+ + "MRIwEAYDVQQIEwlCYXJjZWxvbmExEjAQBgNVBAcTCUJhcmNlbG9uYTEuMCwGA1UE\n"+ + "ChMlSVBTIEludGVybmV0IHB1Ymxpc2hpbmcgU2VydmljZXMgcy5sLjErMCkGA1UE\n"+ + "ChQiaXBzQG1haWwuaXBzLmVzIEMuSS5GLiAgQi02MDkyOTQ1MjEvMC0GA1UECxMm\n"+ + "SVBTIENBIENMQVNFQTMgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxLzAtBgNVBAMT\n"+ + "JklQUyBDQSBDTEFTRUEzIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MR4wHAYJKoZI\n"+ + "hvcNAQkBFg9pcHNAbWFpbC5pcHMuZXMwHhcNMDExMjI5MDEwNzUwWhcNMjUxMjI3\n"+ + "MDEwNzUwWjCCARQxCzAJBgNVBAYTAkVTMRIwEAYDVQQIEwlCYXJjZWxvbmExEjAQ\n"+ + "BgNVBAcTCUJhcmNlbG9uYTEuMCwGA1UEChMlSVBTIEludGVybmV0IHB1Ymxpc2hp\n"+ + "bmcgU2VydmljZXMgcy5sLjErMCkGA1UEChQiaXBzQG1haWwuaXBzLmVzIEMuSS5G\n"+ + "LiAgQi02MDkyOTQ1MjEvMC0GA1UECxMmSVBTIENBIENMQVNFQTMgQ2VydGlmaWNh\n"+ + "dGlvbiBBdXRob3JpdHkxLzAtBgNVBAMTJklQUyBDQSBDTEFTRUEzIENlcnRpZmlj\n"+ + "YXRpb24gQXV0aG9yaXR5MR4wHAYJKoZIhvcNAQkBFg9pcHNAbWFpbC5pcHMuZXMw\n"+ + "gZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAO6AAPYaZC6tasiDsYun7o/ZttvN\n"+ + "G7uGBiJ2MwwSbUhWYdLcgiViL5/SaTBlA0IjWLxH3GvWdV0XPOH/8lhneaDBgbHU\n"+ + "VqLyjRGZ/fZ98cfEXgIqmuJKtROKAP2Md4bm15T1IHUuDky/dMQ/gT6DtKM4Ninn\n"+ + "6Cr1jIhBqoCm42zvAgMBAAGjggRTMIIETzAdBgNVHQ4EFgQUHp9XUEe2YZM50yz8\n"+ + "2l09BXW3mQIwggFGBgNVHSMEggE9MIIBOYAUHp9XUEe2YZM50yz82l09BXW3mQKh\n"+ + "ggEcpIIBGDCCARQxCzAJBgNVBAYTAkVTMRIwEAYDVQQIEwlCYXJjZWxvbmExEjAQ\n"+ + "BgNVBAcTCUJhcmNlbG9uYTEuMCwGA1UEChMlSVBTIEludGVybmV0IHB1Ymxpc2hp\n"+ + "bmcgU2VydmljZXMgcy5sLjErMCkGA1UEChQiaXBzQG1haWwuaXBzLmVzIEMuSS5G\n"+ + "LiAgQi02MDkyOTQ1MjEvMC0GA1UECxMmSVBTIENBIENMQVNFQTMgQ2VydGlmaWNh\n"+ + "dGlvbiBBdXRob3JpdHkxLzAtBgNVBAMTJklQUyBDQSBDTEFTRUEzIENlcnRpZmlj\n"+ + "YXRpb24gQXV0aG9yaXR5MR4wHAYJKoZIhvcNAQkBFg9pcHNAbWFpbC5pcHMuZXOC\n"+ + "AQAwDAYDVR0TBAUwAwEB/zAMBgNVHQ8EBQMDB/+AMGsGA1UdJQRkMGIGCCsGAQUF\n"+ + "BwMBBggrBgEFBQcDAgYIKwYBBQUHAwMGCCsGAQUFBwMEBggrBgEFBQcDCAYKKwYB\n"+ + "BAGCNwIBFQYKKwYBBAGCNwIBFgYKKwYBBAGCNwoDAQYKKwYBBAGCNwoDBDARBglg\n"+ + "hkgBhvhCAQEEBAMCAAcwGgYDVR0RBBMwEYEPaXBzQG1haWwuaXBzLmVzMBoGA1Ud\n"+ + "EgQTMBGBD2lwc0BtYWlsLmlwcy5lczBCBglghkgBhvhCAQ0ENRYzQ0xBU0VBMyBD\n"+ + "QSBDZXJ0aWZpY2F0ZSBpc3N1ZWQgYnkgaHR0cDovL3d3dy5pcHMuZXMvMCkGCWCG\n"+ + "SAGG+EIBAgQcFhpodHRwOi8vd3d3Lmlwcy5lcy9pcHMyMDAyLzA7BglghkgBhvhC\n"+ + "AQQELhYsaHR0cDovL3d3dy5pcHMuZXMvaXBzMjAwMi9pcHMyMDAyQ0xBU0VBMy5j\n"+ + "cmwwQAYJYIZIAYb4QgEDBDMWMWh0dHA6Ly93d3cuaXBzLmVzL2lwczIwMDIvcmV2\n"+ + "b2NhdGlvbkNMQVNFQTMuaHRtbD8wPQYJYIZIAYb4QgEHBDAWLmh0dHA6Ly93d3cu\n"+ + "aXBzLmVzL2lwczIwMDIvcmVuZXdhbENMQVNFQTMuaHRtbD8wOwYJYIZIAYb4QgEI\n"+ + "BC4WLGh0dHA6Ly93d3cuaXBzLmVzL2lwczIwMDIvcG9saWN5Q0xBU0VBMy5odG1s\n"+ + "MHUGA1UdHwRuMGwwMqAwoC6GLGh0dHA6Ly93d3cuaXBzLmVzL2lwczIwMDIvaXBz\n"+ + "MjAwMkNMQVNFQTMuY3JsMDagNKAyhjBodHRwOi8vd3d3YmFjay5pcHMuZXMvaXBz\n"+ + "MjAwMi9pcHMyMDAyQ0xBU0VBMy5jcmwwLwYIKwYBBQUHAQEEIzAhMB8GCCsGAQUF\n"+ + "BzABhhNodHRwOi8vb2NzcC5pcHMuZXMvMA0GCSqGSIb3DQEBBQUAA4GBAEo9IEca\n"+ + "2on0eisxeewBwMwB9dbB/MjD81ACUZBYKp/nNQlbMAqBACVHr9QPDp5gJqiVp4MI\n"+ + "3y2s6Q73nMify5NF8bpqxmdRSmlPa/59Cy9SKcJQrSRE7SOzSMtEQMEDlQwKeAYS\n"+ + "AfWRMS1Jjbs/RU4s4OjNtckUFQzjB4ObJnXv\n"+ + "-----END CERTIFICATE-----"); + super.addPEMCertificate("IPS Servidores root", + // X500 Subject, for lookups. + "MIGjMQswCQYDVQQGEwJFUzESMBAGA1UECBMJQkFSQ0VMT05BMRIwEAYDVQQHEwlCQVJDRUxPTkEx"+ + "GTAXBgNVBAoTEElQUyBTZWd1cmlkYWQgQ0ExGDAWBgNVBAsTD0NlcnRpZmljYWNpb25lczEXMBUG"+ + "A1UEAxMOSVBTIFNFUlZJRE9SRVMxHjAcBgkqhkiG9w0BCQEWD2lwc0BtYWlsLmlwcy5lcw==", + "-----BEGIN CERTIFICATE-----\n"+ + "MIICtzCCAiACAQAwDQYJKoZIhvcNAQEEBQAwgaMxCzAJBgNVBAYTAkVTMRIwEAYD\n"+ + "VQQIEwlCQVJDRUxPTkExEjAQBgNVBAcTCUJBUkNFTE9OQTEZMBcGA1UEChMQSVBT\n"+ + "IFNlZ3VyaWRhZCBDQTEYMBYGA1UECxMPQ2VydGlmaWNhY2lvbmVzMRcwFQYDVQQD\n"+ + "Ew5JUFMgU0VSVklET1JFUzEeMBwGCSqGSIb3DQEJARYPaXBzQG1haWwuaXBzLmVz\n"+ + "MB4XDTk4MDEwMTIzMjEwN1oXDTA5MTIyOTIzMjEwN1owgaMxCzAJBgNVBAYTAkVT\n"+ + "MRIwEAYDVQQIEwlCQVJDRUxPTkExEjAQBgNVBAcTCUJBUkNFTE9OQTEZMBcGA1UE\n"+ + "ChMQSVBTIFNlZ3VyaWRhZCBDQTEYMBYGA1UECxMPQ2VydGlmaWNhY2lvbmVzMRcw\n"+ + "FQYDVQQDEw5JUFMgU0VSVklET1JFUzEeMBwGCSqGSIb3DQEJARYPaXBzQG1haWwu\n"+ + "aXBzLmVzMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCsT1J0nznqjtwlxLyY\n"+ + "XZhkJAk8IbPMGbWOlI6H0fg3PqHILVikgDVboXVsHUUMH2Fjal5vmwpMwci4YSM1\n"+ + "gf/+rHhwLWjhOgeYlQJU3c0jt4BT18g3RXIGJBK6E2Ehim51KODFDzT9NthFf+G4\n"+ + "Nu+z4cYgjui0OLzhPvYR3oydAQIDAQABMA0GCSqGSIb3DQEBBAUAA4GBACzzw3lY\n"+ + "JN7GO9HgQmm47mSzPWIBubOE3yN93ZjPEKn+ANgilgUTB1RXxafey9m4iEL2mdsU\n"+ + "dx+2/iU94aI+A6mB0i1sR/WWRowiq8jMDQ6XXotBtDvECgZAHd1G9AHduoIuPD14\n"+ + "cJ58GNCr+Lh3B0Zx8coLY1xq+XKU1QFPoNtC\n"+ + "-----END CERTIFICATE-----"); + super.addPEMCertificate("IPS Timestamping root", + // X500 Subject, for lookups. + "MIIBHjELMAkGA1UEBhMCRVMxEjAQBgNVBAgTCUJhcmNlbG9uYTESMBAGA1UEBxMJQmFyY2Vsb25h"+ + "MS4wLAYDVQQKEyVJUFMgSW50ZXJuZXQgcHVibGlzaGluZyBTZXJ2aWNlcyBzLmwuMSswKQYDVQQK"+ + "FCJpcHNAbWFpbC5pcHMuZXMgQy5JLkYuICBCLTYwOTI5NDUyMTQwMgYDVQQLEytJUFMgQ0EgVGlt"+ + "ZXN0YW1waW5nIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MTQwMgYDVQQDEytJUFMgQ0EgVGltZXN0"+ + "YW1waW5nIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MR4wHAYJKoZIhvcNAQkBFg9pcHNAbWFpbC5p"+ + "cHMuZXM=", + "-----BEGIN CERTIFICATE-----\n"+ + "MIIIODCCB6GgAwIBAgIBADANBgkqhkiG9w0BAQUFADCCAR4xCzAJBgNVBAYTAkVT\n"+ + "MRIwEAYDVQQIEwlCYXJjZWxvbmExEjAQBgNVBAcTCUJhcmNlbG9uYTEuMCwGA1UE\n"+ + "ChMlSVBTIEludGVybmV0IHB1Ymxpc2hpbmcgU2VydmljZXMgcy5sLjErMCkGA1UE\n"+ + "ChQiaXBzQG1haWwuaXBzLmVzIEMuSS5GLiAgQi02MDkyOTQ1MjE0MDIGA1UECxMr\n"+ + "SVBTIENBIFRpbWVzdGFtcGluZyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTE0MDIG\n"+ + "A1UEAxMrSVBTIENBIFRpbWVzdGFtcGluZyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0\n"+ + "eTEeMBwGCSqGSIb3DQEJARYPaXBzQG1haWwuaXBzLmVzMB4XDTAxMTIyOTAxMTAx\n"+ + "OFoXDTI1MTIyNzAxMTAxOFowggEeMQswCQYDVQQGEwJFUzESMBAGA1UECBMJQmFy\n"+ + "Y2Vsb25hMRIwEAYDVQQHEwlCYXJjZWxvbmExLjAsBgNVBAoTJUlQUyBJbnRlcm5l\n"+ + "dCBwdWJsaXNoaW5nIFNlcnZpY2VzIHMubC4xKzApBgNVBAoUImlwc0BtYWlsLmlw\n"+ + "cy5lcyBDLkkuRi4gIEItNjA5Mjk0NTIxNDAyBgNVBAsTK0lQUyBDQSBUaW1lc3Rh\n"+ + "bXBpbmcgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxNDAyBgNVBAMTK0lQUyBDQSBU\n"+ + "aW1lc3RhbXBpbmcgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxHjAcBgkqhkiG9w0B\n"+ + "CQEWD2lwc0BtYWlsLmlwcy5lczCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA\n"+ + "vLjuVqWajOY2ycJioGaBjRrVetJznw6EZLqVtJCneK/K/lRhW86yIFcBrkSSQxA4\n"+ + "Efdo/BdApWgnMjvEp+ZCccWZ73b/K5Uk9UmSGGjKALWkWi9uy9YbLA1UZ2t6KaFY\n"+ + "q6JaANZbuxjC3/YeE1Z2m6Vo4pjOxgOKNNtMg0GmqaMCAwEAAaOCBIAwggR8MB0G\n"+ + "A1UdDgQWBBSL0BBQCYHynQnVDmB4AyKiP8jKZjCCAVAGA1UdIwSCAUcwggFDgBSL\n"+ + "0BBQCYHynQnVDmB4AyKiP8jKZqGCASakggEiMIIBHjELMAkGA1UEBhMCRVMxEjAQ\n"+ + "BgNVBAgTCUJhcmNlbG9uYTESMBAGA1UEBxMJQmFyY2Vsb25hMS4wLAYDVQQKEyVJ\n"+ + "UFMgSW50ZXJuZXQgcHVibGlzaGluZyBTZXJ2aWNlcyBzLmwuMSswKQYDVQQKFCJp\n"+ + "cHNAbWFpbC5pcHMuZXMgQy5JLkYuICBCLTYwOTI5NDUyMTQwMgYDVQQLEytJUFMg\n"+ + "Q0EgVGltZXN0YW1waW5nIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MTQwMgYDVQQD\n"+ + "EytJUFMgQ0EgVGltZXN0YW1waW5nIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MR4w\n"+ + "HAYJKoZIhvcNAQkBFg9pcHNAbWFpbC5pcHMuZXOCAQAwDAYDVR0TBAUwAwEB/zAM\n"+ + "BgNVHQ8EBQMDB/+AMGsGA1UdJQRkMGIGCCsGAQUFBwMBBggrBgEFBQcDAgYIKwYB\n"+ + "BQUHAwMGCCsGAQUFBwMEBggrBgEFBQcDCAYKKwYBBAGCNwIBFQYKKwYBBAGCNwIB\n"+ + "FgYKKwYBBAGCNwoDAQYKKwYBBAGCNwoDBDARBglghkgBhvhCAQEEBAMCAAcwGgYD\n"+ + "VR0RBBMwEYEPaXBzQG1haWwuaXBzLmVzMBoGA1UdEgQTMBGBD2lwc0BtYWlsLmlw\n"+ + "cy5lczBHBglghkgBhvhCAQ0EOhY4VGltZXN0YW1waW5nIENBIENlcnRpZmljYXRl\n"+ + "IGlzc3VlZCBieSBodHRwOi8vd3d3Lmlwcy5lcy8wKQYJYIZIAYb4QgECBBwWGmh0\n"+ + "dHA6Ly93d3cuaXBzLmVzL2lwczIwMDIvMEAGCWCGSAGG+EIBBAQzFjFodHRwOi8v\n"+ + "d3d3Lmlwcy5lcy9pcHMyMDAyL2lwczIwMDJUaW1lc3RhbXBpbmcuY3JsMEUGCWCG\n"+ + "SAGG+EIBAwQ4FjZodHRwOi8vd3d3Lmlwcy5lcy9pcHMyMDAyL3Jldm9jYXRpb25U\n"+ + "aW1lc3RhbXBpbmcuaHRtbD8wQgYJYIZIAYb4QgEHBDUWM2h0dHA6Ly93d3cuaXBz\n"+ + "LmVzL2lwczIwMDIvcmVuZXdhbFRpbWVzdGFtcGluZy5odG1sPzBABglghkgBhvhC\n"+ + "AQgEMxYxaHR0cDovL3d3dy5pcHMuZXMvaXBzMjAwMi9wb2xpY3lUaW1lc3RhbXBp\n"+ + "bmcuaHRtbDB/BgNVHR8EeDB2MDegNaAzhjFodHRwOi8vd3d3Lmlwcy5lcy9pcHMy\n"+ + "MDAyL2lwczIwMDJUaW1lc3RhbXBpbmcuY3JsMDugOaA3hjVodHRwOi8vd3d3YmFj\n"+ + "ay5pcHMuZXMvaXBzMjAwMi9pcHMyMDAyVGltZXN0YW1waW5nLmNybDAvBggrBgEF\n"+ + "BQcBAQQjMCEwHwYIKwYBBQUHMAGGE2h0dHA6Ly9vY3NwLmlwcy5lcy8wDQYJKoZI\n"+ + "hvcNAQEFBQADgYEAZbrBzAAalZHK6Ww6vzoeFAh8+4Pua2JR0zORtWB5fgTYXXk3\n"+ + "6MNbsMRnLWhasl8OCvrNPzpFoeo2zyYepxEoxZSPhExTCMWTs/zif/WN87GphV+I\n"+ + "3pGW7hdbrqXqcGV4LCFkAZXOzkw+UPS2Wctjjba9GNSHSl/c7+lW8AoM6HU=\n"+ + "-----END CERTIFICATE-----"); + super.addPEMCertificate("QuoVadis Root CA", + // X500 Subject, for lookups. + "MH8xCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMSUwIwYDVQQLExxSb290"+ + "IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MS4wLAYDVQQDEyVRdW9WYWRpcyBSb290IENlcnRpZmlj"+ + "YXRpb24gQXV0aG9yaXR5", + "-----BEGIN CERTIFICATE-----\n"+ + "MIIF0DCCBLigAwIBAgIEOrZQizANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJC\n"+ + "TTEZMBcGA1UEChMQUXVvVmFkaXMgTGltaXRlZDElMCMGA1UECxMcUm9vdCBDZXJ0\n"+ + "aWZpY2F0aW9uIEF1dGhvcml0eTEuMCwGA1UEAxMlUXVvVmFkaXMgUm9vdCBDZXJ0\n"+ + "aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wMTAzMTkxODMzMzNaFw0yMTAzMTcxODMz\n"+ + "MzNaMH8xCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMSUw\n"+ + "IwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MS4wLAYDVQQDEyVR\n"+ + "dW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG\n"+ + "9w0BAQEFAAOCAQ8AMIIBCgKCAQEAv2G1lVO6V/z68mcLOhrfEYBklbTRvM16z/Yp\n"+ + "li4kVEAkOPcahdxYTMukJ0KX0J+DisPkBgNbAKVRHnAEdOLB1Dqr1607BxgFjv2D\n"+ + "rOpm2RgbaIr1VxqYuvXtdj182d6UajtLF8HVj71lODqV0D1VNk7feVcxKh7YWWVJ\n"+ + "WCCYfqtffp/p1k3sg3Spx2zY7ilKhSoGFPlU5tPaZQeLYzcS19Dsw3sgQUSj7cug\n"+ + "F+FxZc4dZjH3dgEZyH0DWLaVSR2mEiboxgx24ONmy+pdpibu5cxfvWenAScOospU\n"+ + "xbF6lR1xHkopigPcakXBpBlebzbNw6Kwt/5cOOJSvPhEQ+aQuwIDAQABo4ICUjCC\n"+ + "Ak4wPQYIKwYBBQUHAQEEMTAvMC0GCCsGAQUFBzABhiFodHRwczovL29jc3AucXVv\n"+ + "dmFkaXNvZmZzaG9yZS5jb20wDwYDVR0TAQH/BAUwAwEB/zCCARoGA1UdIASCAREw\n"+ + "ggENMIIBCQYJKwYBBAG+WAABMIH7MIHUBggrBgEFBQcCAjCBxxqBxFJlbGlhbmNl\n"+ + "IG9uIHRoZSBRdW9WYWRpcyBSb290IENlcnRpZmljYXRlIGJ5IGFueSBwYXJ0eSBh\n"+ + "c3N1bWVzIGFjY2VwdGFuY2Ugb2YgdGhlIHRoZW4gYXBwbGljYWJsZSBzdGFuZGFy\n"+ + "ZCB0ZXJtcyBhbmQgY29uZGl0aW9ucyBvZiB1c2UsIGNlcnRpZmljYXRpb24gcHJh\n"+ + "Y3RpY2VzLCBhbmQgdGhlIFF1b1ZhZGlzIENlcnRpZmljYXRlIFBvbGljeS4wIgYI\n"+ + "KwYBBQUHAgEWFmh0dHA6Ly93d3cucXVvdmFkaXMuYm0wHQYDVR0OBBYEFItLbe3T\n"+ + "KbkGGew5Oanwl4Rqy+/fMIGuBgNVHSMEgaYwgaOAFItLbe3TKbkGGew5Oanwl4Rq\n"+ + "y+/foYGEpIGBMH8xCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1p\n"+ + "dGVkMSUwIwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MS4wLAYD\n"+ + "VQQDEyVRdW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggQ6tlCL\n"+ + "MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEAitQUtf70mpKnGdSk\n"+ + "fnIYj9lofFIk3WdvOXrEql494liwTXCYhGHoG+NpGA7O+0dQoE7/8CQfvbLO9Sf8\n"+ + "7C9TqnN7Az10buYWnuulLsS/VidQK2K6vkscPFVcQR0kvoIgR13VRH56FmjffU1R\n"+ + "cHhXHTMe/QKZnAzNCgVPx7uOpHX6Sm2xgI4JVrmcGmD+XcHXetwReNDWXcG31a0y\n"+ + "mQM6isxUJTkxgXsTIlG6Rmyhu576BGxJJnSP0nPrzDCi5upZIof4l/UO/erMkqQW\n"+ + "xFIY6iHOsfHmhIHluqmGKPJDWl0Snawe2ajlCmqnf6CHKc/yiU3U7MXi5nrQNiOK\n"+ + "SnQ2+Q==\n"+ + "-----END CERTIFICATE-----"); + super.addPEMCertificate("QuoVadis Root CA 2", + // X500 Subject, for lookups. + "MEUxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMRswGQYDVQQDExJRdW9W"+ + "YWRpcyBSb290IENBIDI=", + "-----BEGIN CERTIFICATE-----\n"+ + "MIIFtzCCA5+gAwIBAgICBQkwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0x\n"+ + "GTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJv\n"+ + "b3QgQ0EgMjAeFw0wNjExMjQxODI3MDBaFw0zMTExMjQxODIzMzNaMEUxCzAJBgNV\n"+ + "BAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMRswGQYDVQQDExJRdW9W\n"+ + "YWRpcyBSb290IENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCa\n"+ + "GMpLlA0ALa8DKYrwD4HIrkwZhR0In6spRIXzL4GtMh6QRr+jhiYaHv5+HBg6XJxg\n"+ + "Fyo6dIMzMH1hVBHL7avg5tKifvVrbxi3Cgst/ek+7wrGsxDp3MJGF/hd/aTa/55J\n"+ + "WpzmM+Yklvc/ulsrHHo1wtZn/qtmUIttKGAr79dgw8eTvI02kfN/+NsRE8Scd3bB\n"+ + "rrcCaoF6qUWD4gXmuVbBlDePSHFjIuwXZQeVikvfj8ZaCuWw419eaxGrDPmF60Tp\n"+ + "+ARz8un+XJiM9XOva7R+zdRcAitMOeGylZUtQofX1bOQQ7dsE/He3fbE+Ik/0XX1\n"+ + "ksOR1YqI0JDs3G3eicJlcZaLDQP9nL9bFqyS2+r+eXyt66/3FsvbzSUr5R/7mp/i\n"+ + "Ucw6UwxI5g69ybR2BlLmEROFcmMDBOAENisgGQLodKcftslWZvB1JdxnwQ5hYIiz\n"+ + "PtGo/KPaHbDRsSNU30R2be1B2MGyIrZTHN81Hdyhdyox5C315eXbyOD/5YDXC2Og\n"+ + "/zOhD7osFRXql7PSorW+8oyWHhqPHWykYTe5hnMz15eWniN9gqRMgeKh0bpnX5UH\n"+ + "oycR7hYQe7xFSkyyBNKr79X9DFHOUGoIMfmR2gyPZFwDwzqLID9ujWc9Otb+fVuI\n"+ + "yV77zGHcizN300QyNQliBJIWENieJ0f7OyHj+OsdWwIDAQABo4GwMIGtMA8GA1Ud\n"+ + "EwEB/wQFMAMBAf8wCwYDVR0PBAQDAgEGMB0GA1UdDgQWBBQahGK8SEwzJQTU7tD2\n"+ + "A8QZRtGUazBuBgNVHSMEZzBlgBQahGK8SEwzJQTU7tD2A8QZRtGUa6FJpEcwRTEL\n"+ + "MAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMT\n"+ + "ElF1b1ZhZGlzIFJvb3QgQ0EgMoICBQkwDQYJKoZIhvcNAQEFBQADggIBAD4KFk2f\n"+ + "BluornFdLwUvZ+YTRYPENvbzwCYMDbVHZF34tHLJRqUDGCdViXh9duqWNIAXINzn\n"+ + "g/iN/Ae42l9NLmeyhP3ZRPx3UIHmfLTJDQtyU/h2BwdBR5YM++CCJpNVjP4iH2Bl\n"+ + "fF/nJrP3MpCYUNQ3cVX2kiF495V5+vgtJodmVjB3pjd4M1IQWK4/YY7yarHvGH5K\n"+ + "WWPKjaJW1acvvFYfzznB4vsKqBUsfU16Y8Zsl0Q80m/DShcK+JDSV6IZUaUtl0Ha\n"+ + "B0+pUNqQjZRG4T7wlP0QADj1O+hA4bRuVhogzG9Yje0uRY/W6ZM/57Es3zrWIozc\n"+ + "hLsib9D45MY56QSIPMO661V6bYCZJPVsAfv4l7CUW+v90m/xd2gNNWQjrLhVoQPR\n"+ + "TUIZ3Ph1WVaj+ahJefivDrkRoHy3au000LYmYjgahwz46P0u05B/B5EqHdZ+XIWD\n"+ + "mbA4CD/pXvk1B+TJYm5Xf6dQlfe6yJvmjqIBxdZmv3lh8zwc4bmCXF2gw+nYSL0Z\n"+ + "ohEUGW6yhhtoPkg3Goi3XZZenMfvJ2II4pEZXNLxId26F0KCl3GBUzGpn/Z9Yr9y\n"+ + "4aOTHcyKJloJONDO1w2AFrR4pTqHTI2KpdVGl/IsELm8VCLAAVBpQ570su9t+Oza\n"+ + "8eOx79+Rj1QqCyXBJhnEUhAFZdWCEOrCMc0u\n"+ + "-----END CERTIFICATE-----"); + super.addPEMCertificate("QuoVadis Root CA 3", + // X500 Subject, for lookups. + "MEUxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMRswGQYDVQQDExJRdW9W"+ + "YWRpcyBSb290IENBIDM=", + "-----BEGIN CERTIFICATE-----\n"+ + "MIIGnTCCBIWgAwIBAgICBcYwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0x\n"+ + "GTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJv\n"+ + "b3QgQ0EgMzAeFw0wNjExMjQxOTExMjNaFw0zMTExMjQxOTA2NDRaMEUxCzAJBgNV\n"+ + "BAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMRswGQYDVQQDExJRdW9W\n"+ + "YWRpcyBSb290IENBIDMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDM\n"+ + "V0IWVJzmmNPTTe7+7cefQzlKZbPoFog02w1ZkXTPkrgEQK0CSzGrvI2RaNggDhoB\n"+ + "4hp7Thdd4oq3P5kazethq8Jlph+3t723j/z9cI8LoGe+AaJZz3HmDyl2/7FWeUUr\n"+ + "H556VOijKTVopAFPD6QuN+8bv+OPEKhyq1hX51SGyMnzW9os2l2ObjyjPtr7guXd\n"+ + "8lyyBTNvijbO0BNO/79KDDRMpsMhvVAEVeuxu537RR5kFd5VAYwCdrXLoT9Cabwv\n"+ + "vWhDFlaJKjdhkf2mrk7AyxRllDdLkgbvBNDInIjbC3uBr7E9KsRlOni27tyAsdLT\n"+ + "mZw67mtaa7ONt9XOnMK+pUsvFrGeaDsGb659n/je7Mwpp5ijJUMv7/FfJuGITfhe\n"+ + "btfZFG4ZM2mnO4SJk8RTVROhUXhA+LjJou57ulJCg54U7QVSWllWp5f8nT8KKdjc\n"+ + "T5EOE7zelaTfi5m+rJsziO+1ga8bxiJTyPbH7pcUsMV8eFLI8M5ud2CEpukqdiDt\n"+ + "WAEXMJPpGovgc2PZapKUSU60rUqFxKMiMPwJ7Wgic6aIDFUhWMXhOp8q3crhkODZ\n"+ + "c6tsgLjoC2SToJyMGf+z0gzskSaHirOi4XCPLArlzW1oUevaPwV/izLmE1xr/l9A\n"+ + "4iLItLRkT9a6fUg+qGkM17uGcclzuD87nSVL2v9A6wIDAQABo4IBlTCCAZEwDwYD\n"+ + "VR0TAQH/BAUwAwEB/zCB4QYDVR0gBIHZMIHWMIHTBgkrBgEEAb5YAAMwgcUwgZMG\n"+ + "CCsGAQUFBwICMIGGGoGDQW55IHVzZSBvZiB0aGlzIENlcnRpZmljYXRlIGNvbnN0\n"+ + "aXR1dGVzIGFjY2VwdGFuY2Ugb2YgdGhlIFF1b1ZhZGlzIFJvb3QgQ0EgMyBDZXJ0\n"+ + "aWZpY2F0ZSBQb2xpY3kgLyBDZXJ0aWZpY2F0aW9uIFByYWN0aWNlIFN0YXRlbWVu\n"+ + "dC4wLQYIKwYBBQUHAgEWIWh0dHA6Ly93d3cucXVvdmFkaXNnbG9iYWwuY29tL2Nw\n"+ + "czALBgNVHQ8EBAMCAQYwHQYDVR0OBBYEFPLAE+CCQz777i9nMpY1XNu4ywLQMG4G\n"+ + "A1UdIwRnMGWAFPLAE+CCQz777i9nMpY1XNu4ywLQoUmkRzBFMQswCQYDVQQGEwJC\n"+ + "TTEZMBcGA1UEChMQUXVvVmFkaXMgTGltaXRlZDEbMBkGA1UEAxMSUXVvVmFkaXMg\n"+ + "Um9vdCBDQSAzggIFxjANBgkqhkiG9w0BAQUFAAOCAgEAT62gLEz6wPJv92ZVqyM0\n"+ + "7ucp2sNbtrCD2dDQ4iH782CnO11gUyeim/YIIirnv6By5ZwkajGxkHon24QRiSem\n"+ + "d1o417+shvzuXYO8BsbRd2sPbSQvS3pspweWyuOEn62Iix2rFo1bZhfZFvSLgNLd\n"+ + "+LJ2w/w4E6oM3kJpK27zPOuAJ9v1pkQNn1pVWQvVDVJIxa6f8i+AxeoyUDUSly7B\n"+ + "4f/xI4hROJ/yZlZ25w9Rl6VSDE1JUZU2Pb+iSwwQHYaZTKrzchGT5Or2m9qoXadN\n"+ + "t54CrnMAyNojA+j56hl0YgCUyyIgvpSnWbWCar6ZeXqp8kokUvd0/bpO5qgdAm6x\n"+ + "DYBEwa7TIzdfu4V8K5Iu6H6li92Z4b8nby1dqnuH/grdS/yO9SbkbnBCbjPsMZ57\n"+ + "k8HkyWkaPcBrTiJt7qtYTcbQQcEr6k8Sh17rRdhs9ZgC06DYVYoGmRmioHfRMJ6s\n"+ + "zHXug/WwYjnPbFfiTNKRCw51KBuav/0aQ/HKd/s7j2G4aSgWQgRecCocIdiP4b0j\n"+ + "Wy10QJLZYxkNc91pvGJHvOB0K7Lrfb5BG7XARsWhIstfTsEokt4YutUqKLsRixeT\n"+ + "mJlglFwjz1onl14LBQaTNx47aTbrqZ5hHY8y2o4M1nQ+ewkk2gF3R8Q7zTSMmfXK\n"+ + "4SVhM7JZG+Ju1zdXtg2pEto=\n"+ + "-----END CERTIFICATE-----"); + super.addPEMCertificate("Security Communication Root CA", + // X500 Subject, for lookups. + "MFAxCzAJBgNVBAYTAkpQMRgwFgYDVQQKEw9TRUNPTSBUcnVzdC5uZXQxJzAlBgNVBAsTHlNlY3Vy"+ + "aXR5IENvbW11bmljYXRpb24gUm9vdENBMQ==", + "-----BEGIN CERTIFICATE-----\n"+ + "MIIDWjCCAkKgAwIBAgIBADANBgkqhkiG9w0BAQUFADBQMQswCQYDVQQGEwJKUDEY\n"+ + "MBYGA1UEChMPU0VDT00gVHJ1c3QubmV0MScwJQYDVQQLEx5TZWN1cml0eSBDb21t\n"+ + "dW5pY2F0aW9uIFJvb3RDQTEwHhcNMDMwOTMwMDQyMDQ5WhcNMjMwOTMwMDQyMDQ5\n"+ + "WjBQMQswCQYDVQQGEwJKUDEYMBYGA1UEChMPU0VDT00gVHJ1c3QubmV0MScwJQYD\n"+ + "VQQLEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTEwggEiMA0GCSqGSIb3\n"+ + "DQEBAQUAA4IBDwAwggEKAoIBAQCzs/5/022x7xZ8V6UMbXaKL0u/ZPtM7orw8yl8\n"+ + "9f/uKuDp6bpbZCKamm8sOiZpUQWZJtzVHGpxxpp9Hp3dfGzGjGdnSj74cbAZJ6kJ\n"+ + "DKaVv0uMDPpVmDvY6CKhS3E4eayXkmmziX7qIWgGmBSWh9JhNrxtJ1aeV+7AwFb9\n"+ + "Ms+k2Y7CI9eNqPPYJayX5HA49LY6tJ07lyZDo6G8SVlyTCMwhwFY9k6+HGhWZq/N\n"+ + "QV3Is00qVUarH9oe4kA92819uZKAnDfdDJZkndwi92SL32HeFZRSFaB9UslLqCHJ\n"+ + "xrHty8OVYNEP8Ktw+N/LTX7s1vqr2b1/VPKl6Xn62dZ2JChzAgMBAAGjPzA9MB0G\n"+ + "A1UdDgQWBBSgc0mZaNyFW2XjmygvV5+9M7wHSDALBgNVHQ8EBAMCAQYwDwYDVR0T\n"+ + "AQH/BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAaECpqLvkT115swW1F7NgE+vG\n"+ + "kl3g0dNq/vu+m22/xwVtWSDEHPC32oRYAmP6SBbvT6UL90qY8j+eG61Ha2POCEfr\n"+ + "Uj94nK9NrvjVT8+amCoQQTlSxN3Zmw7vkwGusi7KaEIkQmywszo+zenaSMQVy+n5\n"+ + "Bw+SUEmK3TGXX8npN6o7WWWXlDLJs58+OmJYxUmtYg5xpTKqL8aJdkNAExNnPaJU\n"+ + "JRDL8Try2frbSVa7pv6nQTXD4IhhyYjH3zYQIphZ6rBK+1YWc26sTfcioU+tHXot\n"+ + "RSflMMFe8toTyyVCUZVHA4xsIcx0Qu1T/zOLjw9XARYvz6buyXAiFL39vmwLAw==\n"+ + "-----END CERTIFICATE-----"); + super.addPEMCertificate("Sonera Class 1 Root CA", + // X500 Subject, for lookups. + "MDkxCzAJBgNVBAYTAkZJMQ8wDQYDVQQKEwZTb25lcmExGTAXBgNVBAMTEFNvbmVyYSBDbGFzczEg"+ + "Q0E=", + "-----BEGIN CERTIFICATE-----\n"+ + "MIIDIDCCAgigAwIBAgIBJDANBgkqhkiG9w0BAQUFADA5MQswCQYDVQQGEwJGSTEP\n"+ + "MA0GA1UEChMGU29uZXJhMRkwFwYDVQQDExBTb25lcmEgQ2xhc3MxIENBMB4XDTAx\n"+ + "MDQwNjEwNDkxM1oXDTIxMDQwNjEwNDkxM1owOTELMAkGA1UEBhMCRkkxDzANBgNV\n"+ + "BAoTBlNvbmVyYTEZMBcGA1UEAxMQU29uZXJhIENsYXNzMSBDQTCCASIwDQYJKoZI\n"+ + "hvcNAQEBBQADggEPADCCAQoCggEBALWJHytPZwp5/8Ue+H887dF+2rDNbS82rDTG\n"+ + "29lkFwhjMDMiikzujrsPDUJVyZ0upe/3p4zDq7mXy47vPxVnqIJyY1MPQYx9EJUk\n"+ + "oVqlBvqSV536pQHydekfvFYmUk54GWVYVQNYwBSujHxVX3BbdyMGNpfzJLWaRpXk\n"+ + "3w0LBUXl0fIdgrvGE+D+qnr9aTCU89JFhfzyMlsy3uhsXR/LpCJ0sICOXZT3BgBL\n"+ + "qdReLjVQCfOAl/QMF6452F/NM8EcyonCIvdFEu1eEpOdY6uCLrnrQkFEy0oaAIIN\n"+ + "nvmLVz5MxxftLItyM19yejhW1ebZrgUaHXVFsculJRwSVzb9IjcCAwEAAaMzMDEw\n"+ + "DwYDVR0TAQH/BAUwAwEB/zARBgNVHQ4ECgQIR+IMi/ZTiFIwCwYDVR0PBAQDAgEG\n"+ + "MA0GCSqGSIb3DQEBBQUAA4IBAQCLGrLJXWG04bkruVPRsoWdd44W7hE928Jj2VuX\n"+ + "ZfsSZ9gqXLar5V7DtxYvyOirHYr9qxp81V9jz9yw3Xe5qObSIjiHBxTZ/75Wtf0H\n"+ + "DjxVyhbMp6Z3N/vbXB9OWQaHowND9Rart4S9Tu+fMTfwRvFAttEMpWT4Y14h21VO\n"+ + "TzF2nBBhjrZTOqMRvq9tfB69ri3iDGnHhVNoomG6xT60eVR4ngrHAr5i0RGCS2Uv\n"+ + "kVrCqIexVmiUefkl98HVrhq4uz2PqYo4Ffdz0Fpg0YCw8NzVUM1O7pJIae2yIx4w\n"+ + "zMiUyLb1O4Z/P6Yun/Y+LLWSlj7fLJOK/4GMDw9ZIRlXvVWa\n"+ + "-----END CERTIFICATE-----"); + super.addPEMCertificate("Sonera Class 2 Root CA", + // X500 Subject, for lookups. + "MDkxCzAJBgNVBAYTAkZJMQ8wDQYDVQQKEwZTb25lcmExGTAXBgNVBAMTEFNvbmVyYSBDbGFzczIg"+ + "Q0E=", + "-----BEGIN CERTIFICATE-----\n"+ + "MIIDIDCCAgigAwIBAgIBHTANBgkqhkiG9w0BAQUFADA5MQswCQYDVQQGEwJGSTEP\n"+ + "MA0GA1UEChMGU29uZXJhMRkwFwYDVQQDExBTb25lcmEgQ2xhc3MyIENBMB4XDTAx\n"+ + "MDQwNjA3Mjk0MFoXDTIxMDQwNjA3Mjk0MFowOTELMAkGA1UEBhMCRkkxDzANBgNV\n"+ + "BAoTBlNvbmVyYTEZMBcGA1UEAxMQU29uZXJhIENsYXNzMiBDQTCCASIwDQYJKoZI\n"+ + "hvcNAQEBBQADggEPADCCAQoCggEBAJAXSjWdyvANlsdE+hY3/Ei9vX+ALTU74W+o\n"+ + "Z6m/AxxNjG8yR9VBaKQTBME1DJqEQ/xcHf+Js+gXGM2RX/uJ4+q/Tl18GybTdXnt\n"+ + "5oTjV+WtKcT0OijnpXuENmmz/V52vaMtmdOQTiMofRhj8VQ7Jp12W5dCsv+u8E7s\n"+ + "3TmVToMGf+dJQMjFAbJUWmYdPfz56TwKnoG4cPABi+QjVHzIrviQHgCWctRUz2Ej\n"+ + "vOr7nQKV0ba5cTppCD8PtOFCx4j1P5iop7oc4HFx71hXgVB6XGt0Rg6DA5jDjqhu\n"+ + "8nYybieDwnPz3BjotJPqdURrBGAgcVeHnfO+oJAjPYok4doh28MCAwEAAaMzMDEw\n"+ + "DwYDVR0TAQH/BAUwAwEB/zARBgNVHQ4ECgQISqCqWITTXjwwCwYDVR0PBAQDAgEG\n"+ + "MA0GCSqGSIb3DQEBBQUAA4IBAQBazof5FnIVV0sd2ZvnoiYw7JNn39Yt0jSv9zil\n"+ + "zqsWuasvfDXLrNAPtEwr/IDva4yRXzZ299uzGxnq9LIR/WFxRL8oszodv7ND6J+/\n"+ + "3DEIcbCdjdY0RzKQxmUk96BKfARzjzlvF4xytb1LyHr4e4PDKE6cCepnP7JnBBvD\n"+ + "FNr450kkkdAdavphOe9r5yF1BgfYErQhIHBCcYHaPJo2vqZbDWpsmh+Re/n570K6\n"+ + "Tk6ezAyNlNzZRZxe7EJQY670XcSxEtzKO6gunRRaBXW37Ndj4ro1tgQIkejanZz2\n"+ + "ZrUYrAqmVCY0M9IbwdR/GjqOC6oybtv8TyWf2TLHllpwrN9M\n"+ + "-----END CERTIFICATE-----"); + super.addPEMCertificate("Staat der Nederlanden Root CA", + // X500 Subject, for lookups. + "MFUxCzAJBgNVBAYTAk5MMR4wHAYDVQQKExVTdGFhdCBkZXIgTmVkZXJsYW5kZW4xJjAkBgNVBAMT"+ + "HVN0YWF0IGRlciBOZWRlcmxhbmRlbiBSb290IENB", + "-----BEGIN CERTIFICATE-----\n"+ + "MIIDujCCAqKgAwIBAgIEAJiWijANBgkqhkiG9w0BAQUFADBVMQswCQYDVQQGEwJO\n"+ + "TDEeMBwGA1UEChMVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSYwJAYDVQQDEx1TdGFh\n"+ + "dCBkZXIgTmVkZXJsYW5kZW4gUm9vdCBDQTAeFw0wMjEyMTcwOTIzNDlaFw0xNTEy\n"+ + "MTYwOTE1MzhaMFUxCzAJBgNVBAYTAk5MMR4wHAYDVQQKExVTdGFhdCBkZXIgTmVk\n"+ + "ZXJsYW5kZW4xJjAkBgNVBAMTHVN0YWF0IGRlciBOZWRlcmxhbmRlbiBSb290IENB\n"+ + "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmNK1URF6gaYUmHFtvszn\n"+ + "ExvWJw56s2oYHLZhWtVhCb/ekBPHZ+7d89rFDBKeNVU+LCeIQGv33N0iYfXCxw71\n"+ + "9tV2U02PjLwYdjeFnejKScfST5gTCaI+Ioicf9byEGW07l8Y1Rfj+MX94p2i71MO\n"+ + "hXeiD+EwR+4A5zN9RGcaC1Hoi6CeUJhoNFIfLm0B8mBF8jHrqTFoKbt6QZ7GGX+U\n"+ + "tFE5A3+y3qcym7RHjm+0Sq7lr7HcsBthvJly3uSJt3omXdozSVtSnA71iq3DuD3o\n"+ + "BmrC1SoLbHuEvVYFy4ZlkuxEK7COudxwC0barbxjiDn622r+I/q85Ej0ZytqERAh\n"+ + "SQIDAQABo4GRMIGOMAwGA1UdEwQFMAMBAf8wTwYDVR0gBEgwRjBEBgRVHSAAMDww\n"+ + "OgYIKwYBBQUHAgEWLmh0dHA6Ly93d3cucGtpb3ZlcmhlaWQubmwvcG9saWNpZXMv\n"+ + "cm9vdC1wb2xpY3kwDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBSofeu8Y6R0E3QA\n"+ + "7Jbg0zTBLL9s+DANBgkqhkiG9w0BAQUFAAOCAQEABYSHVXQ2YcG70dTGFagTtJ+k\n"+ + "/rvuFbQvBgwp8qiSpGEN/KtcCFtREytNwiphyPgJWPwtArI5fZlmgb9uXJVFIGzm\n"+ + "eafR2Bwp/MIgJ1HI8XxdNGdphREwxgDS1/PTfLbwMVcoEoJz6TMvplW0C5GUR5z6\n"+ + "u3pCMuiufi3IvKwUv9kP2Vv8wfl6leF9fpb8cbDCTMjfRTTJzg3ynGQI0DvDKcWy\n"+ + "7ZAEwbEpkcUwb8GpcjPM/l0WFywRaed+/sWDCN+83CI6LiBpIzlWYGeQiy52OfsR\n"+ + "iJf2fL1LuCAWZwWN4jvBcj+UlTfHXbme2JOhF4//DGYVwSR8MnwDHTuhWEUykw==\n"+ + "-----END CERTIFICATE-----"); + super.addPEMCertificate("TDC Internet Root CA", + // X500 Subject, for lookups. + "MEMxCzAJBgNVBAYTAkRLMRUwEwYDVQQKEwxUREMgSW50ZXJuZXQxHTAbBgNVBAsTFFREQyBJbnRl"+ + "cm5ldCBSb290IENB", + "-----BEGIN CERTIFICATE-----\n"+ + "MIIEKzCCAxOgAwIBAgIEOsylTDANBgkqhkiG9w0BAQUFADBDMQswCQYDVQQGEwJE\n"+ + "SzEVMBMGA1UEChMMVERDIEludGVybmV0MR0wGwYDVQQLExRUREMgSW50ZXJuZXQg\n"+ + "Um9vdCBDQTAeFw0wMTA0MDUxNjMzMTdaFw0yMTA0MDUxNzAzMTdaMEMxCzAJBgNV\n"+ + "BAYTAkRLMRUwEwYDVQQKEwxUREMgSW50ZXJuZXQxHTAbBgNVBAsTFFREQyBJbnRl\n"+ + "cm5ldCBSb290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxLhA\n"+ + "vJHVYx/XmaCLDEAedLdInUaMArLgJF/wGROnN4NrXceO+YQwzho7+vvOi20jxsNu\n"+ + "Zp+Jpd/gQlBn+h9sHvTQBda/ytZO5GhgbEaqHF1j4QeGDmUApy6mcca8uYGoOn0a\n"+ + "0vnRrEvLznWv3Hv6gXPU/Lq9QYjUdLP5Xjg6PEOo0pVOd20TDJ2PeAG3WiAfAzc1\n"+ + "4izbSysseLlJ28TQx5yc5IogCSEWVmb/Bexb4/DPqyQkXsN/cHoSxNK1EKC2IeGN\n"+ + "eGlVRGn1ypYcNIUXJXfi9i8nmHj9eQY6otZaQ8H/7AQ77hPv01ha/5Lr7K7a8jcD\n"+ + "R0G2l8ktCkEiu7vmpwIDAQABo4IBJTCCASEwEQYJYIZIAYb4QgEBBAQDAgAHMGUG\n"+ + "A1UdHwReMFwwWqBYoFakVDBSMQswCQYDVQQGEwJESzEVMBMGA1UEChMMVERDIElu\n"+ + "dGVybmV0MR0wGwYDVQQLExRUREMgSW50ZXJuZXQgUm9vdCBDQTENMAsGA1UEAxME\n"+ + "Q1JMMTArBgNVHRAEJDAigA8yMDAxMDQwNTE2MzMxN1qBDzIwMjEwNDA1MTcwMzE3\n"+ + "WjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUbGQBx/2FbazI2p5QCIUItTxWqFAw\n"+ + "HQYDVR0OBBYEFGxkAcf9hW2syNqeUAiFCLU8VqhQMAwGA1UdEwQFMAMBAf8wHQYJ\n"+ + "KoZIhvZ9B0EABBAwDhsIVjUuMDo0LjADAgSQMA0GCSqGSIb3DQEBBQUAA4IBAQBO\n"+ + "Q8zR3R0QGwZ/t6T609lN+yOfI1Rb5osvBCiLtSdtiaHsmGnc540mgwV5dOy0uaOX\n"+ + "wTUA/RXaOYE6lTGQ3pfphqiZdwzlWqCE/xIWrG64jcN7ksKsLtB9KOy282A4aW8+\n"+ + "2ARVPp7MVdK6/rtHBNcK2RYKNCn1WBPVT8+PVkuzHu7TmHnaCB4Mb7j4Fifvwm89\n"+ + "9qNLPg7kbWzbO0ESm70NRyN/PErQr8Cv9u8btRXE64PECV90i9kR+8JWsTz4cMo0\n"+ + "jUNAE4z9mQNUecYu6oah9jrUCbz0vGbMPVjQV0kK7iXiQe4T+Zs4NNEA9X7nlB38\n"+ + "aQNiuJkFBT1reBK9sG9l\n"+ + "-----END CERTIFICATE-----"); + super.addPEMCertificate("TDC OCES Root CA", + // X500 Subject, for lookups. + "MDExCzAJBgNVBAYTAkRLMQwwCgYDVQQKEwNUREMxFDASBgNVBAMTC1REQyBPQ0VTIENB", + "-----BEGIN CERTIFICATE-----\n"+ + "MIIFGTCCBAGgAwIBAgIEPki9xDANBgkqhkiG9w0BAQUFADAxMQswCQYDVQQGEwJE\n"+ + "SzEMMAoGA1UEChMDVERDMRQwEgYDVQQDEwtUREMgT0NFUyBDQTAeFw0wMzAyMTEw\n"+ + "ODM5MzBaFw0zNzAyMTEwOTA5MzBaMDExCzAJBgNVBAYTAkRLMQwwCgYDVQQKEwNU\n"+ + "REMxFDASBgNVBAMTC1REQyBPQ0VTIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A\n"+ + "MIIBCgKCAQEArGL2YSCyz8DGhdfjeebM7fI5kqSXLmSjhFuHnEz9pPPEXyG9VhDr\n"+ + "2y5h7JNp46PMvZnDBfwGuMo2HP6QjklMxFaaL1a8z3sM8W9Hpg1DTeLpHTk0zY0s\n"+ + "2RKY+ePhwUp8hjjEqcRhiNJerxomTdXkoCJHhNlktxmW/OwZ5LKXJk5KTMuPJItU\n"+ + "GBxIYXvViGjaXbXqzRowwYCDdlCqT9HU3Tjw7xb04QxQBr/q+3pJoSgrHPb8FTKj\n"+ + "dGqPqcNiKXEx5TukYBdedObaE+3pHx8b0bJoc8YQNHVGEBDjkAB2QMuLt0MJIf+r\n"+ + "TpPGWOmlgtt3xDqZsXKVSQTwtyv6e1mO3QIDAQABo4ICNzCCAjMwDwYDVR0TAQH/\n"+ + "BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwgewGA1UdIASB5DCB4TCB3gYIKoFQgSkB\n"+ + "AQEwgdEwLwYIKwYBBQUHAgEWI2h0dHA6Ly93d3cuY2VydGlmaWthdC5kay9yZXBv\n"+ + "c2l0b3J5MIGdBggrBgEFBQcCAjCBkDAKFgNUREMwAwIBARqBgUNlcnRpZmlrYXRl\n"+ + "ciBmcmEgZGVubmUgQ0EgdWRzdGVkZXMgdW5kZXIgT0lEIDEuMi4yMDguMTY5LjEu\n"+ + "MS4xLiBDZXJ0aWZpY2F0ZXMgZnJvbSB0aGlzIENBIGFyZSBpc3N1ZWQgdW5kZXIg\n"+ + "T0lEIDEuMi4yMDguMTY5LjEuMS4xLjARBglghkgBhvhCAQEEBAMCAAcwgYEGA1Ud\n"+ + "HwR6MHgwSKBGoESkQjBAMQswCQYDVQQGEwJESzEMMAoGA1UEChMDVERDMRQwEgYD\n"+ + "VQQDEwtUREMgT0NFUyBDQTENMAsGA1UEAxMEQ1JMMTAsoCqgKIYmaHR0cDovL2Ny\n"+ + "bC5vY2VzLmNlcnRpZmlrYXQuZGsvb2Nlcy5jcmwwKwYDVR0QBCQwIoAPMjAwMzAy\n"+ + "MTEwODM5MzBagQ8yMDM3MDIxMTA5MDkzMFowHwYDVR0jBBgwFoAUYLWF7FZkfhIZ\n"+ + "J2cdUBVLc647+RIwHQYDVR0OBBYEFGC1hexWZH4SGSdnHVAVS3OuO/kSMB0GCSqG\n"+ + "SIb2fQdBAAQQMA4bCFY2LjA6NC4wAwIEkDANBgkqhkiG9w0BAQUFAAOCAQEACrom\n"+ + "JkbTc6gJ82sLMJn9iuFXehHTuJTXCRBuo7E4A9G28kNBKWKnctj7fAXmMXAnVBhO\n"+ + "inxO5dHKjHiIzxvTkIvmI/gLDjNDfZziChmPyQE+dF10yYscA+UYyAFMP8uXBV2Y\n"+ + "caaYb7Z8vTd/vuGTJW1v8AqtFxjhA7wHKcitJuj4YfD9IQl+mo6paH1IYnK9AOoB\n"+ + "mbgGglGBTvH1tJFUuSN6AJqfXY3gPGS5GhKSKseCRHI53OI8xthV9RVOyAUO28bQ\n"+ + "YqbsFbS1AoLbrIyigfCbmTH1ICCoiGEKB5+U/NDXG8wuF/MEJ3Zn61SD/aSQfgY9\n"+ + "BKNDLdr8C2LqL19iUw==\n"+ + "-----END CERTIFICATE-----"); + super.addPEMCertificate("UTN DATACorp SGC Root CA", + // X500 Subject, for lookups. + "MIGTMQswCQYDVQQGEwJVUzELMAkGA1UECBMCVVQxFzAVBgNVBAcTDlNhbHQgTGFrZSBDaXR5MR4w"+ + "HAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxITAfBgNVBAsTGGh0dHA6Ly93d3cudXNlcnRy"+ + "dXN0LmNvbTEbMBkGA1UEAxMSVVROIC0gREFUQUNvcnAgU0dD", + "-----BEGIN CERTIFICATE-----\n"+ + "MIIEXjCCA0agAwIBAgIQRL4Mi1AAIbQR0ypoBqmtaTANBgkqhkiG9w0BAQUFADCB\n"+ + "kzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2Ug\n"+ + "Q2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExho\n"+ + "dHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xGzAZBgNVBAMTElVUTiAtIERBVEFDb3Jw\n"+ + "IFNHQzAeFw05OTA2MjQxODU3MjFaFw0xOTA2MjQxOTA2MzBaMIGTMQswCQYDVQQG\n"+ + "EwJVUzELMAkGA1UECBMCVVQxFzAVBgNVBAcTDlNhbHQgTGFrZSBDaXR5MR4wHAYD\n"+ + "VQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxITAfBgNVBAsTGGh0dHA6Ly93d3cu\n"+ + "dXNlcnRydXN0LmNvbTEbMBkGA1UEAxMSVVROIC0gREFUQUNvcnAgU0dDMIIBIjAN\n"+ + "BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3+5YEKIrblXEjr8uRgnn4AgPLit6\n"+ + "E5Qbvfa2gI5lBZMAHryv4g+OGQ0SR+ysraP6LnD43m77VkIVni5c7yPeIbkFdicZ\n"+ + "D0/Ww5y0vpQZY/KmEQrrU0icvvIpOxboGqBMpsn0GFlowHDyUwDAXlCCpVZvNvlK\n"+ + "4ESGoE1O1kduSUrLZ9emxAW5jh70/P/N5zbgnAVssjMiFdC04MwXwLLA9P4yPykq\n"+ + "lXvY8qdOD1R8oQ2AswkDwf9c3V6aPryuvEeKaq5xyh+xKrhfQgUL7EYw0XILyulW\n"+ + "bfXv33i+Ybqypa4ETLyorGkVl73v67SMvzX41MPRKA5cOp9wGDMgd8SirwIDAQAB\n"+ + "o4GrMIGoMAsGA1UdDwQEAwIBxjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRT\n"+ + "MtGzz3/64PGgXYVOktKeRR20TzA9BgNVHR8ENjA0MDKgMKAuhixodHRwOi8vY3Js\n"+ + "LnVzZXJ0cnVzdC5jb20vVVROLURBVEFDb3JwU0dDLmNybDAqBgNVHSUEIzAhBggr\n"+ + "BgEFBQcDAQYKKwYBBAGCNwoDAwYJYIZIAYb4QgQBMA0GCSqGSIb3DQEBBQUAA4IB\n"+ + "AQAnNZcAiosovcYzMB4p/OL31ZjUQLtgyr+rFywJNn9Q+kHcrpY6CiM+iVnJowft\n"+ + "Gzet/Hy+UUla3joKVAgWRcKZsYfNjGjgaQPpxE6YsjuMFrMOoAyYUJuTqXAJyCyj\n"+ + "j98C5OBxOvG0I3KgqgHf35g+FFCgMSa9KOlaMCZ1+XtgHI3zzVAmbQQnmt/VDUVH\n"+ + "KWss5nbZqSl9Mt3JNjy9rjXxEZ4du5A/EkdOjtd+D2JzHVImOBwYSf0wdJrE5SIv\n"+ + "2MCN7ZF6TACPcn9d2t0bi0Vr591pl6jFVkwPDPafepE39peC4N1xaf92P2BNPM/3\n"+ + "mfnGV/TJVTl4uix5yaaIK/QI\n"+ + "-----END CERTIFICATE-----"); + super.addPEMCertificate("UTN USERFirst Email Root CA", + // X500 Subject, for lookups. + "MIGuMQswCQYDVQQGEwJVUzELMAkGA1UECBMCVVQxFzAVBgNVBAcTDlNhbHQgTGFrZSBDaXR5MR4w"+ + "HAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxITAfBgNVBAsTGGh0dHA6Ly93d3cudXNlcnRy"+ + "dXN0LmNvbTE2MDQGA1UEAxMtVVROLVVTRVJGaXJzdC1DbGllbnQgQXV0aGVudGljYXRpb24gYW5k"+ + "IEVtYWls", + "-----BEGIN CERTIFICATE-----\n"+ + "MIIEojCCA4qgAwIBAgIQRL4Mi1AAJLQR0zYlJWfJiTANBgkqhkiG9w0BAQUFADCB\n"+ + "rjELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2Ug\n"+ + "Q2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExho\n"+ + "dHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xNjA0BgNVBAMTLVVUTi1VU0VSRmlyc3Qt\n"+ + "Q2xpZW50IEF1dGhlbnRpY2F0aW9uIGFuZCBFbWFpbDAeFw05OTA3MDkxNzI4NTBa\n"+ + "Fw0xOTA3MDkxNzM2NThaMIGuMQswCQYDVQQGEwJVUzELMAkGA1UECBMCVVQxFzAV\n"+ + "BgNVBAcTDlNhbHQgTGFrZSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5l\n"+ + "dHdvcmsxITAfBgNVBAsTGGh0dHA6Ly93d3cudXNlcnRydXN0LmNvbTE2MDQGA1UE\n"+ + "AxMtVVROLVVTRVJGaXJzdC1DbGllbnQgQXV0aGVudGljYXRpb24gYW5kIEVtYWls\n"+ + "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsjmFpPJ9q0E7YkY3rs3B\n"+ + "YHW8OWX5ShpHornMSMxqmNVNNRm5pELlzkniii8efNIxB8dOtINknS4p1aJkxIW9\n"+ + "hVE1eaROaJB7HHqkkqgX8pgV8pPMyaQylbsMTzC9mKALi+VuG6JG+ni8om+rWV6l\n"+ + "L8/K2m2qL+usobNqqrcuZzWLeeEeaYji5kbNoKXqvgvOdjp6Dpvq/NonWz1zHyLm\n"+ + "SGHGTPNpsaguG7bUMSAsvIKKjqQOpdeJQ/wWWq8dcdcRWdq6hw2v+vPhwvCkxWeM\n"+ + "1tZUOt4KpLoDd7NlyP0e03RiqhjKaJMeoYV+9Udly/hNVyh00jT/MLbu9mIwFIws\n"+ + "6wIDAQABo4G5MIG2MAsGA1UdDwQEAwIBxjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud\n"+ + "DgQWBBSJgmd9xJ0mcABLtFBIfN49rgRufTBYBgNVHR8EUTBPME2gS6BJhkdodHRw\n"+ + "Oi8vY3JsLnVzZXJ0cnVzdC5jb20vVVROLVVTRVJGaXJzdC1DbGllbnRBdXRoZW50\n"+ + "aWNhdGlvbmFuZEVtYWlsLmNybDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUH\n"+ + "AwQwDQYJKoZIhvcNAQEFBQADggEBALFtYV2mGn98q0rkMPxTbyUkxsrt4jFcKw7u\n"+ + "7mFVbwQ+zznexRtJlOTrIEy05p5QLnLZjfWqo7NK2lYcYJeA3IKirUq9iiv/Cwm0\n"+ + "xtcgBEXkzYABurorbs6q15L+5K/r9CYdFip/bDCVNy8zEqx/3cfREYxRmLLQo5HQ\n"+ + "rfafnoOTHh1CuEava2bwm3/q4wMC5QJRwarVNZ1yQAOJujEdxRBoUp7fooXFXAim\n"+ + "eOZTT7Hot9MUnpOmw2TjrH5xzbyf6QMbzPvprDHBr3wVdAKZw7JHpsIyYdfHb0gk\n"+ + "USeh1YdV8nuPmD0Wnu51tvjQjvLzxq4oW6fw8zYX/MMF08oDSlQ=\n"+ + "-----END CERTIFICATE-----"); + super.addPEMCertificate("UTN USERFirst Hardware Root CA", + // X500 Subject, for lookups. + "MIGXMQswCQYDVQQGEwJVUzELMAkGA1UECBMCVVQxFzAVBgNVBAcTDlNhbHQgTGFrZSBDaXR5MR4w"+ + "HAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxITAfBgNVBAsTGGh0dHA6Ly93d3cudXNlcnRy"+ + "dXN0LmNvbTEfMB0GA1UEAxMWVVROLVVTRVJGaXJzdC1IYXJkd2FyZQ==", + "-----BEGIN CERTIFICATE-----\n"+ + "MIIEdDCCA1ygAwIBAgIQRL4Mi1AAJLQR0zYq/mUK/TANBgkqhkiG9w0BAQUFADCB\n"+ + "lzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2Ug\n"+ + "Q2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExho\n"+ + "dHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xHzAdBgNVBAMTFlVUTi1VU0VSRmlyc3Qt\n"+ + "SGFyZHdhcmUwHhcNOTkwNzA5MTgxMDQyWhcNMTkwNzA5MTgxOTIyWjCBlzELMAkG\n"+ + "A1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0eTEe\n"+ + "MBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRwOi8v\n"+ + "d3d3LnVzZXJ0cnVzdC5jb20xHzAdBgNVBAMTFlVUTi1VU0VSRmlyc3QtSGFyZHdh\n"+ + "cmUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCx98M4P7Sof885glFn\n"+ + "0G2f0v9Y8+efK+wNiVSZuTiZFvfgIXlIwrthdBKWHTxqctU8EGc6Oe0rE81m65UJ\n"+ + "M6Rsl7HoxuzBdXmcRl6Nq9Bq/bkqVRcQVLMZ8Jr28bFdtqdt++BxF2uiiPsA3/4a\n"+ + "MXcMmgF6sTLjKwEHOG7DpV4jvEWbe1DByTCP2+UretNb+zNAHqDVmBe8i4fDidNd\n"+ + "oI6yqqr2jmmIBsX6iSHzCJ1pLgkzmykNRg+MzEk0sGlRvfkGzWitZky8PqxhvQqI\n"+ + "DsjfPe58BEydCl5rkdbux+0ojatNh4lz0G6k0B4WixThdkQDf2Os5M1JnMWS9Ksy\n"+ + "oUhbAgMBAAGjgbkwgbYwCwYDVR0PBAQDAgHGMA8GA1UdEwEB/wQFMAMBAf8wHQYD\n"+ + "VR0OBBYEFKFyXyYbKJhDlV0HN9WFlp1L0sNFMEQGA1UdHwQ9MDswOaA3oDWGM2h0\n"+ + "dHA6Ly9jcmwudXNlcnRydXN0LmNvbS9VVE4tVVNFUkZpcnN0LUhhcmR3YXJlLmNy\n"+ + "bDAxBgNVHSUEKjAoBggrBgEFBQcDAQYIKwYBBQUHAwUGCCsGAQUFBwMGBggrBgEF\n"+ + "BQcDBzANBgkqhkiG9w0BAQUFAAOCAQEARxkP3nTGmZev/K0oXnWO6y1n7k57K9cM\n"+ + "//bey1WiCuFMVGWTYGufEpytXoMs61quwOQt9ABjHbjAbPLPSbtNk28Gpgoiskli\n"+ + "CE7/yMgUsogWXecB5BKV5UU0s4tpvc+0hY91UZ59Ojg6FEgSxvunOxqNDYJAB+gE\n"+ + "CJChicsZUN/KHAG8HQQZexB2lzvukJDKxA4fFm517zP4029bHpbj4HR3dHuKom4t\n"+ + "3XbWOTCC8KucUvIqx69JXn7HaOWCgchqJ/kniCrVWFCVH/A7HFe7fRQ5YiuayZSS\n"+ + "KqMiDP+JJn1fIytH1xUdqWqeUQ0qUZ6B+dQ7XnASfxAynB67nfhmqA==\n"+ + "-----END CERTIFICATE-----"); + super.addPEMCertificate("UTN USERFirst Object Root CA", + // X500 Subject, for lookups. + "MIGVMQswCQYDVQQGEwJVUzELMAkGA1UECBMCVVQxFzAVBgNVBAcTDlNhbHQgTGFrZSBDaXR5MR4w"+ + "HAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxITAfBgNVBAsTGGh0dHA6Ly93d3cudXNlcnRy"+ + "dXN0LmNvbTEdMBsGA1UEAxMUVVROLVVTRVJGaXJzdC1PYmplY3Q=", + "-----BEGIN CERTIFICATE-----\n"+ + "MIIEZjCCA06gAwIBAgIQRL4Mi1AAJLQR0zYt4LNfGzANBgkqhkiG9w0BAQUFADCB\n"+ + "lTELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2Ug\n"+ + "Q2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExho\n"+ + "dHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xHTAbBgNVBAMTFFVUTi1VU0VSRmlyc3Qt\n"+ + "T2JqZWN0MB4XDTk5MDcwOTE4MzEyMFoXDTE5MDcwOTE4NDAzNlowgZUxCzAJBgNV\n"+ + "BAYTAlVTMQswCQYDVQQIEwJVVDEXMBUGA1UEBxMOU2FsdCBMYWtlIENpdHkxHjAc\n"+ + "BgNVBAoTFVRoZSBVU0VSVFJVU1QgTmV0d29yazEhMB8GA1UECxMYaHR0cDovL3d3\n"+ + "dy51c2VydHJ1c3QuY29tMR0wGwYDVQQDExRVVE4tVVNFUkZpcnN0LU9iamVjdDCC\n"+ + "ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM6qgT+jo2F4qjEAVZURnicP\n"+ + "HxzfOpuCaDDASmEd8S8O+r5596Uj71VRloTN2+O5bj4x2AogZ8f02b+U60cEPgLO\n"+ + "KqJdhwQJ9jCdGIqXsqoc/EHSoTbL+z2RuufZcDX65OeQw5ujm9M89RKZd7G3CeBo\n"+ + "5hy485RjiGpq/gt2yb70IuRnuasaXnfBhQfdDWy/7gbHd2pBnqcP1/vulBe3/IW+\n"+ + "pKvEHDHd17bR5PDv3xaPslKT16HUiaEHLr/hARJCHhrh2JU022R5KP+6LhHC5ehb\n"+ + "kkj7RwvCbNqtMoNB86XlQXD9ZZBt+vpRxPm9lisZBCzTbafc8H9vg2XiaquHhnUC\n"+ + "AwEAAaOBrzCBrDALBgNVHQ8EBAMCAcYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E\n"+ + "FgQU2u1kdBScFDyr3ZmpvVsoTYs8ydgwQgYDVR0fBDswOTA3oDWgM4YxaHR0cDov\n"+ + "L2NybC51c2VydHJ1c3QuY29tL1VUTi1VU0VSRmlyc3QtT2JqZWN0LmNybDApBgNV\n"+ + "HSUEIjAgBggrBgEFBQcDAwYIKwYBBQUHAwgGCisGAQQBgjcKAwQwDQYJKoZIhvcN\n"+ + "AQEFBQADggEBAAgfUrE3RHjb/c652pWWmKpVZIC1WkDdIaXFwfNfLEzIR1pp6ujw\n"+ + "NTX00CXzyKakh0q9G7FzCL3Uw8q2NbtZhncxzaeAFK4T7/yxSPlrJSUtUbYsbUXB\n"+ + "mMiKVl0+7kNOPmsnjtA6S4ULX9Ptaqd1y9Fahy85dRNacrACgZ++8A+EVCBibGnU\n"+ + "4U3GDZlDAQ0Slox4nb9QorFEqmrPF3rPbw/U+CRVX/A0FklmPlBGyWNxODFiuGK5\n"+ + "81OtbLUrohKqGU8J2l7nk8aOFAj+8DCAGKCGhU3IfdeLA/5u1fedFqySLKAj5ZyR\n"+ + "Uh+U3xeUc8OzwcFxBSAAeL0TUh2oPs0AH8g=\n"+ + "-----END CERTIFICATE-----"); + super.addPEMCertificate("Camerfirma Chambers of Commerce Root", + // X500 Subject, for lookups. + "MH8xCzAJBgNVBAYTAkVVMScwJQYDVQQKEx5BQyBDYW1lcmZpcm1hIFNBIENJRiBBODI3NDMyODcx"+ + "IzAhBgNVBAsTGmh0dHA6Ly93d3cuY2hhbWJlcnNpZ24ub3JnMSIwIAYDVQQDExlDaGFtYmVycyBv"+ + "ZiBDb21tZXJjZSBSb290", + "-----BEGIN CERTIFICATE-----\n"+ + "MIIEvTCCA6WgAwIBAgIBADANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJFVTEn\n"+ + "MCUGA1UEChMeQUMgQ2FtZXJmaXJtYSBTQSBDSUYgQTgyNzQzMjg3MSMwIQYDVQQL\n"+ + "ExpodHRwOi8vd3d3LmNoYW1iZXJzaWduLm9yZzEiMCAGA1UEAxMZQ2hhbWJlcnMg\n"+ + "b2YgQ29tbWVyY2UgUm9vdDAeFw0wMzA5MzAxNjEzNDNaFw0zNzA5MzAxNjEzNDRa\n"+ + "MH8xCzAJBgNVBAYTAkVVMScwJQYDVQQKEx5BQyBDYW1lcmZpcm1hIFNBIENJRiBB\n"+ + "ODI3NDMyODcxIzAhBgNVBAsTGmh0dHA6Ly93d3cuY2hhbWJlcnNpZ24ub3JnMSIw\n"+ + "IAYDVQQDExlDaGFtYmVycyBvZiBDb21tZXJjZSBSb290MIIBIDANBgkqhkiG9w0B\n"+ + "AQEFAAOCAQ0AMIIBCAKCAQEAtzZV5aVdGDDg2olUkfzIx1L4L1DZ77F1c2VHfRtb\n"+ + "unXF/KGIJPov7coISjlUxFF6tdpg6jg8gbLL8bvZkSM/SAFwdakFKq0fcfPJVD0d\n"+ + "BmpAPrMMhe5cG3nCYsS4No41XQEMIwRHNaqbYE6gZj3LJgqcQKH0XZi/caulAGgq\n"+ + "7YN6D6IUtdQis4CwPAxaUWktWBiP7Zme8a7ileb2R6jWDA+wWFjbw2Y3npuRVDM3\n"+ + "0pQcakjJyfKl2qUMI/cjDpwyVV5xnIQFUZot/eZOKjRa3spAN2cMVCFVd9oKDMyX\n"+ + "roDclDZK9D7ONhMeU+SsTjoF7Nuucpw4i9A5O4kKPnf+dQIBA6OCAUQwggFAMBIG\n"+ + "A1UdEwEB/wQIMAYBAf8CAQwwPAYDVR0fBDUwMzAxoC+gLYYraHR0cDovL2NybC5j\n"+ + "aGFtYmVyc2lnbi5vcmcvY2hhbWJlcnNyb290LmNybDAdBgNVHQ4EFgQU45T1sU3p\n"+ + "26EpW1eLTXYGduHRooowDgYDVR0PAQH/BAQDAgEGMBEGCWCGSAGG+EIBAQQEAwIA\n"+ + "BzAnBgNVHREEIDAegRxjaGFtYmVyc3Jvb3RAY2hhbWJlcnNpZ24ub3JnMCcGA1Ud\n"+ + "EgQgMB6BHGNoYW1iZXJzcm9vdEBjaGFtYmVyc2lnbi5vcmcwWAYDVR0gBFEwTzBN\n"+ + "BgsrBgEEAYGHLgoDATA+MDwGCCsGAQUFBwIBFjBodHRwOi8vY3BzLmNoYW1iZXJz\n"+ + "aWduLm9yZy9jcHMvY2hhbWJlcnNyb290Lmh0bWwwDQYJKoZIhvcNAQEFBQADggEB\n"+ + "AAxBl8IahsAifJ/7kPMa0QOx7xP5IV8EnNrJpY0nbJaHkb5BkAFyk+cefV/2icZd\n"+ + "p0AJPaxJRUXcLo0waLIJuvvDL8y6C98/d3tGfToSJI6WjzwFCm/SlCgdbQzALogi\n"+ + "1djPHRPH8EjX1wWnz8dHnjs8NMiAT9QUu/wNUPf6s+xCX6ndbcj0dc97wXImsQEc\n"+ + "XCz9ek60AcUFV7nnPKoF2YjpB0ZBzu9Bga5Y34OirsrXdx/nADydb47kMgkdTXg0\n"+ + "eDQ8lJsm7U9xxhl6vSAiSFr+S30Dt+dYvsYyTnQeaN2oaFuzPu5ifdmA6Ap1erfu\n"+ + "tGWaIZDgqtCYvDi1czyL+Nw=\n"+ + "-----END CERTIFICATE-----"); + super.addPEMCertificate("Camerfirma Global Chambersign Root", + // X500 Subject, for lookups. + "MH0xCzAJBgNVBAYTAkVVMScwJQYDVQQKEx5BQyBDYW1lcmZpcm1hIFNBIENJRiBBODI3NDMyODcx"+ + "IzAhBgNVBAsTGmh0dHA6Ly93d3cuY2hhbWJlcnNpZ24ub3JnMSAwHgYDVQQDExdHbG9iYWwgQ2hh"+ + "bWJlcnNpZ24gUm9vdA==", + "-----BEGIN CERTIFICATE-----\n"+ + "MIIExTCCA62gAwIBAgIBADANBgkqhkiG9w0BAQUFADB9MQswCQYDVQQGEwJFVTEn\n"+ + "MCUGA1UEChMeQUMgQ2FtZXJmaXJtYSBTQSBDSUYgQTgyNzQzMjg3MSMwIQYDVQQL\n"+ + "ExpodHRwOi8vd3d3LmNoYW1iZXJzaWduLm9yZzEgMB4GA1UEAxMXR2xvYmFsIENo\n"+ + "YW1iZXJzaWduIFJvb3QwHhcNMDMwOTMwMTYxNDE4WhcNMzcwOTMwMTYxNDE4WjB9\n"+ + "MQswCQYDVQQGEwJFVTEnMCUGA1UEChMeQUMgQ2FtZXJmaXJtYSBTQSBDSUYgQTgy\n"+ + "NzQzMjg3MSMwIQYDVQQLExpodHRwOi8vd3d3LmNoYW1iZXJzaWduLm9yZzEgMB4G\n"+ + "A1UEAxMXR2xvYmFsIENoYW1iZXJzaWduIFJvb3QwggEgMA0GCSqGSIb3DQEBAQUA\n"+ + "A4IBDQAwggEIAoIBAQCicKLQn0KuWxfH2H3PFIP8T8mhtxOviteePgQKkotgVvq0\n"+ + "Mi+ITaFgCPS3CU6gSS9J1tPfnZdan5QEcOw/Wdm3zGaLmFIoCQLfxS+EjXqXd7/s\n"+ + "QJ0lcqu1PzKY+7e3/HKE5TWH+VX6ox8Oby4o3Wmg2UIQxvi1RMLQQ3/bvOSiPGpV\n"+ + "eAp3qdjqGTK3L/5cPxvusZjsyq16aUXjlg9V9ubtdepl6DJWk0aJqCWKZQbua795\n"+ + "B9Dxt6/tLE2Su8CoX6dnfQTyFQhwrJLWfQTSM/tMtgsL+xrJxI0DqX5c8lCrEqWh\n"+ + "z0hQpe/SyBoT+rB/sYIcd2oPX9wLlY/vQ37mRQklAgEDo4IBUDCCAUwwEgYDVR0T\n"+ + "AQH/BAgwBgEB/wIBDDA/BgNVHR8EODA2MDSgMqAwhi5odHRwOi8vY3JsLmNoYW1i\n"+ + "ZXJzaWduLm9yZy9jaGFtYmVyc2lnbnJvb3QuY3JsMB0GA1UdDgQWBBRDnDafsJ4w\n"+ + "TcbOX60Qq+UDpfqpFDAOBgNVHQ8BAf8EBAMCAQYwEQYJYIZIAYb4QgEBBAQDAgAH\n"+ + "MCoGA1UdEQQjMCGBH2NoYW1iZXJzaWducm9vdEBjaGFtYmVyc2lnbi5vcmcwKgYD\n"+ + "VR0SBCMwIYEfY2hhbWJlcnNpZ25yb290QGNoYW1iZXJzaWduLm9yZzBbBgNVHSAE\n"+ + "VDBSMFAGCysGAQQBgYcuCgEBMEEwPwYIKwYBBQUHAgEWM2h0dHA6Ly9jcHMuY2hh\n"+ + "bWJlcnNpZ24ub3JnL2Nwcy9jaGFtYmVyc2lnbnJvb3QuaHRtbDANBgkqhkiG9w0B\n"+ + "AQUFAAOCAQEAPDtwkfkEVCeR4e3t/mh/YV3lQWVPMvEYBZRqHN4fcNs+ezICNLUM\n"+ + "bKGKfKX0j//U2K0X1S0E0T9YgOKBWYi+wONGkyT+kL0mojAt6JcmVzWJdJYY9hXi\n"+ + "ryQZVgICsroPFOrGimbBhkVVi76SvpykBMdJPJ7oKXqJ1/6v/2j1pReQvayZzKWG\n"+ + "VwlnRtvWFsJG8eSpUPWP0ZIV018+xgBJOm5YstHRJw0lyDL4IBHNfTIzSJRUTN3c\n"+ + "ecQwn+uOuFW114hcxWokPbLTBQNRxgfvzBRydD1ucs4YKIxKoHflCStFREest2d/\n"+ + "AYoFWpO+ocH/+OcOZ6RHSXZddZAa9SaP8A==\n"+ + "-----END CERTIFICATE-----"); + super.addPEMCertificate("NetLock Qualified (Class QA) Root", + // X500 Subject, for lookups. + "MIHJMQswCQYDVQQGEwJIVTERMA8GA1UEBxMIQnVkYXBlc3QxJzAlBgNVBAoTHk5ldExvY2sgSGFs"+ + "b3phdGJpenRvbnNhZ2kgS2Z0LjEaMBgGA1UECxMRVGFudXNpdHZhbnlraWFkb2sxQjBABgNVBAMT"+ + "OU5ldExvY2sgTWlub3NpdGV0dCBLb3pqZWd5em9pIChDbGFzcyBRQSkgVGFudXNpdHZhbnlraWFk"+ + "bzEeMBwGCSqGSIb3DQEJARYPaW5mb0BuZXRsb2NrLmh1", + "-----BEGIN CERTIFICATE-----\n"+ + "MIIG0TCCBbmgAwIBAgIBezANBgkqhkiG9w0BAQUFADCByTELMAkGA1UEBhMCSFUx\n"+ + "ETAPBgNVBAcTCEJ1ZGFwZXN0MScwJQYDVQQKEx5OZXRMb2NrIEhhbG96YXRiaXp0\n"+ + "b25zYWdpIEtmdC4xGjAYBgNVBAsTEVRhbnVzaXR2YW55a2lhZG9rMUIwQAYDVQQD\n"+ + "EzlOZXRMb2NrIE1pbm9zaXRldHQgS296amVneXpvaSAoQ2xhc3MgUUEpIFRhbnVz\n"+ + "aXR2YW55a2lhZG8xHjAcBgkqhkiG9w0BCQEWD2luZm9AbmV0bG9jay5odTAeFw0w\n"+ + "MzAzMzAwMTQ3MTFaFw0yMjEyMTUwMTQ3MTFaMIHJMQswCQYDVQQGEwJIVTERMA8G\n"+ + "A1UEBxMIQnVkYXBlc3QxJzAlBgNVBAoTHk5ldExvY2sgSGFsb3phdGJpenRvbnNh\n"+ + "Z2kgS2Z0LjEaMBgGA1UECxMRVGFudXNpdHZhbnlraWFkb2sxQjBABgNVBAMTOU5l\n"+ + "dExvY2sgTWlub3NpdGV0dCBLb3pqZWd5em9pIChDbGFzcyBRQSkgVGFudXNpdHZh\n"+ + "bnlraWFkbzEeMBwGCSqGSIb3DQEJARYPaW5mb0BuZXRsb2NrLmh1MIIBIjANBgkq\n"+ + "hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx1Ilstg91IRVCacbvWy5FPSKAtt2/Goq\n"+ + "eKvld/Bu4IwjZ9ulZJm53QE+b+8tmjwi8F3JV6BVQX/yQ15YglMxZc4e8ia6AFQe\n"+ + "r7C8HORSjKAyr7c3sVNnaHRnUPYtLmTeriZ539+Zhqurf4XsoPuAzPS4DB6TRWO5\n"+ + "3Lhbm+1bOdRfYrCnjnxmOCyqsQhjF2d9zL2z8cM/z1A57dEZgxXbhxInlrfa6uWd\n"+ + "vLrqOU+L73Sa58XQ0uqGURzk/mQIKAR5BevKxXEOC++r6uwSEaEYBTJp0QwsGj0l\n"+ + "mT+1fMptsK6ZmfoIYOcZwvK9UdPM0wKswREMgM6r3JSda6M5UzrWhQIDAMV9o4IC\n"+ + "wDCCArwwEgYDVR0TAQH/BAgwBgEB/wIBBDAOBgNVHQ8BAf8EBAMCAQYwggJ1Bglg\n"+ + "hkgBhvhCAQ0EggJmFoICYkZJR1lFTEVNISBFemVuIHRhbnVzaXR2YW55IGEgTmV0\n"+ + "TG9jayBLZnQuIE1pbm9zaXRldHQgU3pvbGdhbHRhdGFzaSBTemFiYWx5emF0YWJh\n"+ + "biBsZWlydCBlbGphcmFzb2sgYWxhcGphbiBrZXN6dWx0LiBBIG1pbm9zaXRldHQg\n"+ + "ZWxla3Ryb25pa3VzIGFsYWlyYXMgam9naGF0YXMgZXJ2ZW55ZXN1bGVzZW5laywg\n"+ + "dmFsYW1pbnQgZWxmb2dhZGFzYW5hayBmZWx0ZXRlbGUgYSBNaW5vc2l0ZXR0IFN6\n"+ + "b2xnYWx0YXRhc2kgU3phYmFseXphdGJhbiwgYXogQWx0YWxhbm9zIFN6ZXJ6b2Rl\n"+ + "c2kgRmVsdGV0ZWxla2JlbiBlbG9pcnQgZWxsZW5vcnplc2kgZWxqYXJhcyBtZWd0\n"+ + "ZXRlbGUuIEEgZG9rdW1lbnR1bW9rIG1lZ3RhbGFsaGF0b2sgYSBodHRwczovL3d3\n"+ + "dy5uZXRsb2NrLmh1L2RvY3MvIGNpbWVuIHZhZ3kga2VyaGV0b2sgYXogaW5mb0Bu\n"+ + "ZXRsb2NrLm5ldCBlLW1haWwgY2ltZW4uIFdBUk5JTkchIFRoZSBpc3N1YW5jZSBh\n"+ + "bmQgdGhlIHVzZSBvZiB0aGlzIGNlcnRpZmljYXRlIGFyZSBzdWJqZWN0IHRvIHRo\n"+ + "ZSBOZXRMb2NrIFF1YWxpZmllZCBDUFMgYXZhaWxhYmxlIGF0IGh0dHBzOi8vd3d3\n"+ + "Lm5ldGxvY2suaHUvZG9jcy8gb3IgYnkgZS1tYWlsIGF0IGluZm9AbmV0bG9jay5u\n"+ + "ZXQwHQYDVR0OBBYEFAlqYhaSsFq7VQ7LdTI6MuWyIckoMA0GCSqGSIb3DQEBBQUA\n"+ + "A4IBAQCRalCc23iBmz+LQuM7/KbD7kPgz/PigDVJRXYC4uMvBcXxKufAQTPGtpvQ\n"+ + "MznNwNuhrWw3AkxYQTvyl5LGSKjN5Yo5iWH5Upfpvfb5lHTocQ68d4bDBsxafEp+\n"+ + "NFAwLvt/MpqNPfMgW/hqyobzMUwsWYACff44yTB1HLdV47yfuqhthCgFdbOLDcCR\n"+ + "VCHnpgu0mfVRQdzNo0ci2ccBgcTcR08m6h/t280NmPSjnLRzMkqWmf68f8glWPhY\n"+ + "83ZmiVSkpj7EUFy6iRiCdUgh0k8T6GB+B3bbELVR5qq5aKrN9p2QdRLqOBrKROi3\n"+ + "macqaJVmlaut74nLYKkGEsaUR+ko\n"+ + "-----END CERTIFICATE-----"); + super.addPEMCertificate("NetLock Notary (Class A) Root", + // X500 Subject, for lookups. + "MIGvMQswCQYDVQQGEwJIVTEQMA4GA1UECBMHSHVuZ2FyeTERMA8GA1UEBxMIQnVkYXBlc3QxJzAl"+ + "BgNVBAoTHk5ldExvY2sgSGFsb3phdGJpenRvbnNhZ2kgS2Z0LjEaMBgGA1UECxMRVGFudXNpdHZh"+ + "bnlraWFkb2sxNjA0BgNVBAMTLU5ldExvY2sgS296amVneXpvaSAoQ2xhc3MgQSkgVGFudXNpdHZh"+ + "bnlraWFkbw==", + "-----BEGIN CERTIFICATE-----\n"+ + "MIIGfTCCBWWgAwIBAgICAQMwDQYJKoZIhvcNAQEEBQAwga8xCzAJBgNVBAYTAkhV\n"+ + "MRAwDgYDVQQIEwdIdW5nYXJ5MREwDwYDVQQHEwhCdWRhcGVzdDEnMCUGA1UEChMe\n"+ + "TmV0TG9jayBIYWxvemF0Yml6dG9uc2FnaSBLZnQuMRowGAYDVQQLExFUYW51c2l0\n"+ + "dmFueWtpYWRvazE2MDQGA1UEAxMtTmV0TG9jayBLb3pqZWd5em9pIChDbGFzcyBB\n"+ + "KSBUYW51c2l0dmFueWtpYWRvMB4XDTk5MDIyNDIzMTQ0N1oXDTE5MDIxOTIzMTQ0\n"+ + "N1owga8xCzAJBgNVBAYTAkhVMRAwDgYDVQQIEwdIdW5nYXJ5MREwDwYDVQQHEwhC\n"+ + "dWRhcGVzdDEnMCUGA1UEChMeTmV0TG9jayBIYWxvemF0Yml6dG9uc2FnaSBLZnQu\n"+ + "MRowGAYDVQQLExFUYW51c2l0dmFueWtpYWRvazE2MDQGA1UEAxMtTmV0TG9jayBL\n"+ + "b3pqZWd5em9pIChDbGFzcyBBKSBUYW51c2l0dmFueWtpYWRvMIIBIjANBgkqhkiG\n"+ + "9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvHSMD7tM9DceqQWC2ObhbHDqeLVu0ThEDaiD\n"+ + "zl3S1tWBxdRL51uUcCbbO51qTGL3cfNk1mE7PetzozfZz+qMkjvN9wfcZnSX9EUi\n"+ + "3fRc4L9t875lM+QVOr/bmJBVOMTtplVjC7B4BPTjbsE/jvxReB+SnoPC/tmwqcm8\n"+ + "WgD/qaiYdPv2LD4VOQ22BFWoDpggQrOxJa1+mm9dU7GrDPzr4PN6s6iz/0b2Y6LY\n"+ + "Oph7tqyF/7AlT3Rj5xMHpQqPBffAZG9+pyeAlt7ULoZgx2srXnN7F+eRP2QM2Esi\n"+ + "NCubMvJIH5+hCoR64sKtlz2O1cH5VqNQ6ca0+pii7pXmKgOM3wIDAQABo4ICnzCC\n"+ + "ApswDgYDVR0PAQH/BAQDAgAGMBIGA1UdEwEB/wQIMAYBAf8CAQQwEQYJYIZIAYb4\n"+ + "QgEBBAQDAgAHMIICYAYJYIZIAYb4QgENBIICURaCAk1GSUdZRUxFTSEgRXplbiB0\n"+ + "YW51c2l0dmFueSBhIE5ldExvY2sgS2Z0LiBBbHRhbGFub3MgU3pvbGdhbHRhdGFz\n"+ + "aSBGZWx0ZXRlbGVpYmVuIGxlaXJ0IGVsamFyYXNvayBhbGFwamFuIGtlc3p1bHQu\n"+ + "IEEgaGl0ZWxlc2l0ZXMgZm9seWFtYXRhdCBhIE5ldExvY2sgS2Z0LiB0ZXJtZWtm\n"+ + "ZWxlbG9zc2VnLWJpenRvc2l0YXNhIHZlZGkuIEEgZGlnaXRhbGlzIGFsYWlyYXMg\n"+ + "ZWxmb2dhZGFzYW5hayBmZWx0ZXRlbGUgYXogZWxvaXJ0IGVsbGVub3J6ZXNpIGVs\n"+ + "amFyYXMgbWVndGV0ZWxlLiBBeiBlbGphcmFzIGxlaXJhc2EgbWVndGFsYWxoYXRv\n"+ + "IGEgTmV0TG9jayBLZnQuIEludGVybmV0IGhvbmxhcGphbiBhIGh0dHBzOi8vd3d3\n"+ + "Lm5ldGxvY2submV0L2RvY3MgY2ltZW4gdmFneSBrZXJoZXRvIGF6IGVsbGVub3J6\n"+ + "ZXNAbmV0bG9jay5uZXQgZS1tYWlsIGNpbWVuLiBJTVBPUlRBTlQhIFRoZSBpc3N1\n"+ + "YW5jZSBhbmQgdGhlIHVzZSBvZiB0aGlzIGNlcnRpZmljYXRlIGlzIHN1YmplY3Qg\n"+ + "dG8gdGhlIE5ldExvY2sgQ1BTIGF2YWlsYWJsZSBhdCBodHRwczovL3d3dy5uZXRs\n"+ + "b2NrLm5ldC9kb2NzIG9yIGJ5IGUtbWFpbCBhdCBjcHNAbmV0bG9jay5uZXQuMA0G\n"+ + "CSqGSIb3DQEBBAUAA4IBAQBIJEb3ulZv+sgoA0BO5TE5ayZrU3/b39/zcT0mwBQO\n"+ + "xmd7I6gMc90Bu8bKbjc5VdXHjFYgDigKDtIqpLBJUsY4B/6+CgmM0ZjPytoUMaFP\n"+ + "0jn8DxEsQ8Pdq5PHVT5HfBgaANzze9jyf1JsIPQLX2lS9O74silg6+NJMSEN1rUQ\n"+ + "QeJBCWziGppWS3cC9qCbmieH6FUpccKQn0V4GuEVZD3QDtigdp+uxdAu6tYPVuxk\n"+ + "f1qbFFgBJ34TUMdrKuZoPL9coAob4Q566eKAw+np9v1sEZ7Q5SgnK1QyQhSCdeZK\n"+ + "8CtmdWOMovsEPoMOmzbwGOQmIMOM8CgHrTwXZoi1/baI\n"+ + "-----END CERTIFICATE-----"); + super.addPEMCertificate("NetLock Business (Class B) Root", + // X500 Subject, for lookups. + "MIGZMQswCQYDVQQGEwJIVTERMA8GA1UEBxMIQnVkYXBlc3QxJzAlBgNVBAoTHk5ldExvY2sgSGFs"+ + "b3phdGJpenRvbnNhZ2kgS2Z0LjEaMBgGA1UECxMRVGFudXNpdHZhbnlraWFkb2sxMjAwBgNVBAMT"+ + "KU5ldExvY2sgVXpsZXRpIChDbGFzcyBCKSBUYW51c2l0dmFueWtpYWRv", + "-----BEGIN CERTIFICATE-----\n"+ + "MIIFSzCCBLSgAwIBAgIBaTANBgkqhkiG9w0BAQQFADCBmTELMAkGA1UEBhMCSFUx\n"+ + "ETAPBgNVBAcTCEJ1ZGFwZXN0MScwJQYDVQQKEx5OZXRMb2NrIEhhbG96YXRiaXp0\n"+ + "b25zYWdpIEtmdC4xGjAYBgNVBAsTEVRhbnVzaXR2YW55a2lhZG9rMTIwMAYDVQQD\n"+ + "EylOZXRMb2NrIFV6bGV0aSAoQ2xhc3MgQikgVGFudXNpdHZhbnlraWFkbzAeFw05\n"+ + "OTAyMjUxNDEwMjJaFw0xOTAyMjAxNDEwMjJaMIGZMQswCQYDVQQGEwJIVTERMA8G\n"+ + "A1UEBxMIQnVkYXBlc3QxJzAlBgNVBAoTHk5ldExvY2sgSGFsb3phdGJpenRvbnNh\n"+ + "Z2kgS2Z0LjEaMBgGA1UECxMRVGFudXNpdHZhbnlraWFkb2sxMjAwBgNVBAMTKU5l\n"+ + "dExvY2sgVXpsZXRpIChDbGFzcyBCKSBUYW51c2l0dmFueWtpYWRvMIGfMA0GCSqG\n"+ + "SIb3DQEBAQUAA4GNADCBiQKBgQCx6gTsIKAjwo84YM/HRrPVG/77uZmeBNwcf4xK\n"+ + "gZjupNTKihe5In+DCnVMm8Bp2GQ5o+2So/1bXHQawEfKOml2mrriRBf8TKPV/riX\n"+ + "iK+IA4kfpPIEPsgHC+b5sy96YhQJRhTKZPWLgLViqNhr1nGTLbO/CVRY7QbrqHvc\n"+ + "Q7GhaQIDAQABo4ICnzCCApswEgYDVR0TAQH/BAgwBgEB/wIBBDAOBgNVHQ8BAf8E\n"+ + "BAMCAAYwEQYJYIZIAYb4QgEBBAQDAgAHMIICYAYJYIZIAYb4QgENBIICURaCAk1G\n"+ + "SUdZRUxFTSEgRXplbiB0YW51c2l0dmFueSBhIE5ldExvY2sgS2Z0LiBBbHRhbGFu\n"+ + "b3MgU3pvbGdhbHRhdGFzaSBGZWx0ZXRlbGVpYmVuIGxlaXJ0IGVsamFyYXNvayBh\n"+ + "bGFwamFuIGtlc3p1bHQuIEEgaGl0ZWxlc2l0ZXMgZm9seWFtYXRhdCBhIE5ldExv\n"+ + "Y2sgS2Z0LiB0ZXJtZWtmZWxlbG9zc2VnLWJpenRvc2l0YXNhIHZlZGkuIEEgZGln\n"+ + "aXRhbGlzIGFsYWlyYXMgZWxmb2dhZGFzYW5hayBmZWx0ZXRlbGUgYXogZWxvaXJ0\n"+ + "IGVsbGVub3J6ZXNpIGVsamFyYXMgbWVndGV0ZWxlLiBBeiBlbGphcmFzIGxlaXJh\n"+ + "c2EgbWVndGFsYWxoYXRvIGEgTmV0TG9jayBLZnQuIEludGVybmV0IGhvbmxhcGph\n"+ + "biBhIGh0dHBzOi8vd3d3Lm5ldGxvY2submV0L2RvY3MgY2ltZW4gdmFneSBrZXJo\n"+ + "ZXRvIGF6IGVsbGVub3J6ZXNAbmV0bG9jay5uZXQgZS1tYWlsIGNpbWVuLiBJTVBP\n"+ + "UlRBTlQhIFRoZSBpc3N1YW5jZSBhbmQgdGhlIHVzZSBvZiB0aGlzIGNlcnRpZmlj\n"+ + "YXRlIGlzIHN1YmplY3QgdG8gdGhlIE5ldExvY2sgQ1BTIGF2YWlsYWJsZSBhdCBo\n"+ + "dHRwczovL3d3dy5uZXRsb2NrLm5ldC9kb2NzIG9yIGJ5IGUtbWFpbCBhdCBjcHNA\n"+ + "bmV0bG9jay5uZXQuMA0GCSqGSIb3DQEBBAUAA4GBAATbrowXr/gOkDFOzT4JwG06\n"+ + "sPgzTEdM43WIEJessDgVkcYplswhwG08pXTP2IKlOcNl40JwuyKQ433bNXbhoLXa\n"+ + "n3BukxowOR0w2y7jfLKRstE3Kfq51hdcR0/jHTjrn9V7lagonhVK0dHQKwCXoOKS\n"+ + "NitjrFgBazMpUIaD8QFI\n"+ + "-----END CERTIFICATE-----"); + super.addPEMCertificate("NetLock Express (Class C) Root", + // X500 Subject, for lookups. + "MIGbMQswCQYDVQQGEwJIVTERMA8GA1UEBxMIQnVkYXBlc3QxJzAlBgNVBAoTHk5ldExvY2sgSGFs"+ + "b3phdGJpenRvbnNhZ2kgS2Z0LjEaMBgGA1UECxMRVGFudXNpdHZhbnlraWFkb2sxNDAyBgNVBAMT"+ + "K05ldExvY2sgRXhwcmVzc3ogKENsYXNzIEMpIFRhbnVzaXR2YW55a2lhZG8=", + "-----BEGIN CERTIFICATE-----\n"+ + "MIIFTzCCBLigAwIBAgIBaDANBgkqhkiG9w0BAQQFADCBmzELMAkGA1UEBhMCSFUx\n"+ + "ETAPBgNVBAcTCEJ1ZGFwZXN0MScwJQYDVQQKEx5OZXRMb2NrIEhhbG96YXRiaXp0\n"+ + "b25zYWdpIEtmdC4xGjAYBgNVBAsTEVRhbnVzaXR2YW55a2lhZG9rMTQwMgYDVQQD\n"+ + "EytOZXRMb2NrIEV4cHJlc3N6IChDbGFzcyBDKSBUYW51c2l0dmFueWtpYWRvMB4X\n"+ + "DTk5MDIyNTE0MDgxMVoXDTE5MDIyMDE0MDgxMVowgZsxCzAJBgNVBAYTAkhVMREw\n"+ + "DwYDVQQHEwhCdWRhcGVzdDEnMCUGA1UEChMeTmV0TG9jayBIYWxvemF0Yml6dG9u\n"+ + "c2FnaSBLZnQuMRowGAYDVQQLExFUYW51c2l0dmFueWtpYWRvazE0MDIGA1UEAxMr\n"+ + "TmV0TG9jayBFeHByZXNzeiAoQ2xhc3MgQykgVGFudXNpdHZhbnlraWFkbzCBnzAN\n"+ + "BgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA6+ywbGGKIyWvYCDj2Z/8kwvbXY2wobNA\n"+ + "OoLO/XXgeDIDhlqGlZHtU/qdQPzm6N3ZW3oDvV3zOwzDUXmbrVWg6dADEK8KuhRC\n"+ + "2VImESLH0iDMgqSaqf64gXadarfSNnU+sYYJ9m5tfk63euyucYT2BDMIJTLrdKwW\n"+ + "RMbkQJMdf60CAwEAAaOCAp8wggKbMBIGA1UdEwEB/wQIMAYBAf8CAQQwDgYDVR0P\n"+ + "AQH/BAQDAgAGMBEGCWCGSAGG+EIBAQQEAwIABzCCAmAGCWCGSAGG+EIBDQSCAlEW\n"+ + "ggJNRklHWUVMRU0hIEV6ZW4gdGFudXNpdHZhbnkgYSBOZXRMb2NrIEtmdC4gQWx0\n"+ + "YWxhbm9zIFN6b2xnYWx0YXRhc2kgRmVsdGV0ZWxlaWJlbiBsZWlydCBlbGphcmFz\n"+ + "b2sgYWxhcGphbiBrZXN6dWx0LiBBIGhpdGVsZXNpdGVzIGZvbHlhbWF0YXQgYSBO\n"+ + "ZXRMb2NrIEtmdC4gdGVybWVrZmVsZWxvc3NlZy1iaXp0b3NpdGFzYSB2ZWRpLiBB\n"+ + "IGRpZ2l0YWxpcyBhbGFpcmFzIGVsZm9nYWRhc2FuYWsgZmVsdGV0ZWxlIGF6IGVs\n"+ + "b2lydCBlbGxlbm9yemVzaSBlbGphcmFzIG1lZ3RldGVsZS4gQXogZWxqYXJhcyBs\n"+ + "ZWlyYXNhIG1lZ3RhbGFsaGF0byBhIE5ldExvY2sgS2Z0LiBJbnRlcm5ldCBob25s\n"+ + "YXBqYW4gYSBodHRwczovL3d3dy5uZXRsb2NrLm5ldC9kb2NzIGNpbWVuIHZhZ3kg\n"+ + "a2VyaGV0byBheiBlbGxlbm9yemVzQG5ldGxvY2submV0IGUtbWFpbCBjaW1lbi4g\n"+ + "SU1QT1JUQU5UISBUaGUgaXNzdWFuY2UgYW5kIHRoZSB1c2Ugb2YgdGhpcyBjZXJ0\n"+ + "aWZpY2F0ZSBpcyBzdWJqZWN0IHRvIHRoZSBOZXRMb2NrIENQUyBhdmFpbGFibGUg\n"+ + "YXQgaHR0cHM6Ly93d3cubmV0bG9jay5uZXQvZG9jcyBvciBieSBlLW1haWwgYXQg\n"+ + "Y3BzQG5ldGxvY2submV0LjANBgkqhkiG9w0BAQQFAAOBgQAQrX/XDDKACtiG8XmY\n"+ + "ta3UzbM2xJZIwVzNmtkFLp++UOv0JhQQLdRmF/iewSf98e3ke0ugbLWrmldwpu2g\n"+ + "pO0u9f38vf5NNwgMvOOWgyL1SRt/Syu0VMGAfJlOHdCM7tCs5ZL6dVb+ZKATj7i4\n"+ + "Fp1hBWeAyNDYpQcCNJgEjTME1A==\n"+ + "-----END CERTIFICATE-----"); + super.addPEMCertificate("XRamp Global CA Root", + // X500 Subject, for lookups. + "MIGCMQswCQYDVQQGEwJVUzEeMBwGA1UECxMVd3d3LnhyYW1wc2VjdXJpdHkuY29tMSQwIgYDVQQK"+ + "ExtYUmFtcCBTZWN1cml0eSBTZXJ2aWNlcyBJbmMxLTArBgNVBAMTJFhSYW1wIEdsb2JhbCBDZXJ0"+ + "aWZpY2F0aW9uIEF1dGhvcml0eQ==", + "-----BEGIN CERTIFICATE-----\n"+ + "MIIEMDCCAxigAwIBAgIQUJRs7Bjq1ZxN1ZfvdY+grTANBgkqhkiG9w0BAQUFADCB\n"+ + "gjELMAkGA1UEBhMCVVMxHjAcBgNVBAsTFXd3dy54cmFtcHNlY3VyaXR5LmNvbTEk\n"+ + "MCIGA1UEChMbWFJhbXAgU2VjdXJpdHkgU2VydmljZXMgSW5jMS0wKwYDVQQDEyRY\n"+ + "UmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQxMTAxMTcx\n"+ + "NDA0WhcNMzUwMTAxMDUzNzE5WjCBgjELMAkGA1UEBhMCVVMxHjAcBgNVBAsTFXd3\n"+ + "dy54cmFtcHNlY3VyaXR5LmNvbTEkMCIGA1UEChMbWFJhbXAgU2VjdXJpdHkgU2Vy\n"+ + "dmljZXMgSW5jMS0wKwYDVQQDEyRYUmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBB\n"+ + "dXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCYJB69FbS6\n"+ + "38eMpSe2OAtp87ZOqCwuIR1cRN8hXX4jdP5efrRKt6atH67gBhbim1vZZ3RrXYCP\n"+ + "KZ2GG9mcDZhtdhAoWORlsH9KmHmf4MMxfoArtYzAQDsRhtDLooY2YKTVMIJt2W7Q\n"+ + "DxIEM5dfT2Fa8OT5kavnHTu86M/0ay00fOJIYRyO82FEzG+gSqmUsE3a56k0enI4\n"+ + "qEHMPJQRfevIpoy3hsvKMzvZPTeL+3o+hiznc9cKV6xkmxnr9A8ECIqsAxcZZPRa\n"+ + "JSKNNCyy9mgdEm3Tih4U2sSPpuIjhdV6Db1q4Ons7Be7QhtnqiXtRYMh/MHJfNVi\n"+ + "PvryxS3T/dRlAgMBAAGjgZ8wgZwwEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0P\n"+ + "BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFMZPoj0GY4QJnM5i5ASs\n"+ + "jVy16bYbMDYGA1UdHwQvMC0wK6ApoCeGJWh0dHA6Ly9jcmwueHJhbXBzZWN1cml0\n"+ + "eS5jb20vWEdDQS5jcmwwEAYJKwYBBAGCNxUBBAMCAQEwDQYJKoZIhvcNAQEFBQAD\n"+ + "ggEBAJEVOQMBG2f7Shz5CmBbodpNl2L5JFMn14JkTpAuw0kbK5rc/Kh4ZzXxHfAR\n"+ + "vbdI4xD2Dd8/0sm2qlWkSLoC295ZLhVbO50WfUfXN+pfTXYSNrsf16GBBEYgoyxt\n"+ + "qZ4Bfj8pzgCT3/3JknOJiWSe5yvkHJEs0rnOfc5vMZnT5r7SHpDwCRR5XCOrTdLa\n"+ + "IR9NmXmd4c8nnxCbHIgNsIpkQTG4DmyQJKSbXHGPurt+HBvbaoAPIbzp26a3QPSy\n"+ + "i6mx5O+aGtA9aZnuqCij4Tyz8LIRnM98QObd50N9otg6tamN8jSZxNQQ4Qb9CYQQ\n"+ + "O+7ETPTsJ3xCwnR8gooJybQDJbw=\n"+ + "-----END CERTIFICATE-----"); + super.addPEMCertificate("Go Daddy Class 2 CA", + // X500 Subject, for lookups. + "MGMxCzAJBgNVBAYTAlVTMSEwHwYDVQQKExhUaGUgR28gRGFkZHkgR3JvdXAsIEluYy4xMTAvBgNV"+ + "BAsTKEdvIERhZGR5IENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHk=", + "-----BEGIN CERTIFICATE-----\n"+ + "MIIEADCCAuigAwIBAgIBADANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEh\n"+ + "MB8GA1UEChMYVGhlIEdvIERhZGR5IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBE\n"+ + "YWRkeSBDbGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA0MDYyOTE3\n"+ + "MDYyMFoXDTM0MDYyOTE3MDYyMFowYzELMAkGA1UEBhMCVVMxITAfBgNVBAoTGFRo\n"+ + "ZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28gRGFkZHkgQ2xhc3Mg\n"+ + "MiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQADggEN\n"+ + "ADCCAQgCggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XCA\n"+ + "PVYYYwhv2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6w\n"+ + "wdhFJ2+qN1j3hybX2C32qRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXi\n"+ + "EqITLdiOr18SPaAIBQi2XKVlOARFmR6jYGB0xUGlcmIbYsUfb18aQr4CUWWoriMY\n"+ + "avx4A6lNf4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmYvLEHZ6IVDd2gWMZEewo+\n"+ + "YihfukEHU1jPEX44dMX4/7VpkI+EdOqXG68CAQOjgcAwgb0wHQYDVR0OBBYEFNLE\n"+ + "sNKR1EwRcbNhyz2h/t2oatTjMIGNBgNVHSMEgYUwgYKAFNLEsNKR1EwRcbNhyz2h\n"+ + "/t2oatTjoWekZTBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYVGhlIEdvIERhZGR5\n"+ + "IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRpZmlj\n"+ + "YXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQAD\n"+ + "ggEBADJL87LKPpH8EsahB4yOd6AzBhRckB4Y9wimPQoZ+YeAEW5p5JYXMP80kWNy\n"+ + "OO7MHAGjHZQopDH2esRU1/blMVgDoszOYtuURXO1v0XJJLXVggKtI3lpjbi2Tc7P\n"+ + "TMozI+gciKqdi0FuFskg5YmezTvacPd+mSYgFFQlq25zheabIZ0KbIIOqPjCDPoQ\n"+ + "HmyW74cNxA9hi63ugyuV+I6ShHI56yDqg+2DzZduCLzrTia2cyvk0/ZM/iZx4mER\n"+ + "dEr/VxqHD3VILs9RaRegAhJhldXRQLIQTO7ErBBDpqWeCtWVYpoNz4iCxTIM5Cuf\n"+ + "ReYNnyicsbkqWletNw+vHX/bvZ8=\n"+ + "-----END CERTIFICATE-----"); + super.addPEMCertificate("Starfield Class 2 CA", + // X500 Subject, for lookups. + "MGgxCzAJBgNVBAYTAlVTMSUwIwYDVQQKExxTdGFyZmllbGQgVGVjaG5vbG9naWVzLCBJbmMuMTIw"+ + "MAYDVQQLEylTdGFyZmllbGQgQ2xhc3MgMiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eQ==", + "-----BEGIN CERTIFICATE-----\n"+ + "MIIEDzCCAvegAwIBAgIBADANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJVUzEl\n"+ + "MCMGA1UEChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMp\n"+ + "U3RhcmZpZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQw\n"+ + "NjI5MTczOTE2WhcNMzQwNjI5MTczOTE2WjBoMQswCQYDVQQGEwJVUzElMCMGA1UE\n"+ + "ChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMpU3RhcmZp\n"+ + "ZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEgMA0GCSqGSIb3\n"+ + "DQEBAQUAA4IBDQAwggEIAoIBAQC3Msj+6XGmBIWtDBFk385N78gDGIc/oav7PKaf\n"+ + "8MOh2tTYbitTkPskpD6E8J7oX+zlJ0T1KKY/e97gKvDIr1MvnsoFAZMej2YcOadN\n"+ + "+lq2cwQlZut3f+dZxkqZJRRU6ybH838Z1TBwj6+wRir/resp7defqgSHo9T5iaU0\n"+ + "X9tDkYI22WY8sbi5gv2cOj4QyDvvBmVmepsZGD3/cVE8MC5fvj13c7JdBmzDI1aa\n"+ + "K4UmkhynArPkPw2vCHmCuDY96pzTNbO8acr1zJ3o/WSNF4Azbl5KXZnJHoe0nRrA\n"+ + "1W4TNSNe35tfPe/W93bC6j67eA0cQmdrBNj41tpvi/JEoAGrAgEDo4HFMIHCMB0G\n"+ + "A1UdDgQWBBS/X7fRzt0fhvRbVazc1xDCDqmI5zCBkgYDVR0jBIGKMIGHgBS/X7fR\n"+ + "zt0fhvRbVazc1xDCDqmI56FspGowaDELMAkGA1UEBhMCVVMxJTAjBgNVBAoTHFN0\n"+ + "YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAsTKVN0YXJmaWVsZCBD\n"+ + "bGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8w\n"+ + "DQYJKoZIhvcNAQEFBQADggEBAAWdP4id0ckaVaGsafPzWdqbAYcaT1epoXkJKtv3\n"+ + "L7IezMdeatiDh6GX70k1PncGQVhiv45YuApnP+yz3SFmH8lU+nLMPUxA2IGvd56D\n"+ + "eruix/U0F47ZEUD0/CwqTRV/p2JdLiXTAAsgGh1o+Re49L2L7ShZ3U0WixeDyLJl\n"+ + "xy16paq8U4Zt3VekyvggQQto8PT7dL5WXXp59fkdheMtlb71cZBDzI0fmgAKhynp\n"+ + "VSJYACPq4xJDKVtHCN2MQWplBqjlIapBtJUhlbl90TSrE9atvNziPTnNvT51cKEY\n"+ + "WQPJIrSPnNVeKtelttQKbfi3QBFGmh95DmK/D5fs4C8fF5Q=\n"+ + "-----END CERTIFICATE-----"); + super.addPEMCertificate("StartCom Ltd.", + // X500 Subject, for lookups. + "MIGwMQswCQYDVQQGEwJJTDEPMA0GA1UECBMGSXNyYWVsMQ4wDAYDVQQHEwVFaWxhdDEWMBQGA1UE"+ + "ChMNU3RhcnRDb20gTHRkLjEaMBgGA1UECxMRQ0EgQXV0aG9yaXR5IERlcC4xKTAnBgNVBAMTIEZy"+ + "ZWUgU1NMIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MSEwHwYJKoZIhvcNAQkBFhJhZG1pbkBzdGFy"+ + "dGNvbS5vcmc=", + "-----BEGIN CERTIFICATE-----\n"+ + "MIIFFjCCBH+gAwIBAgIBADANBgkqhkiG9w0BAQQFADCBsDELMAkGA1UEBhMCSUwx\n"+ + "DzANBgNVBAgTBklzcmFlbDEOMAwGA1UEBxMFRWlsYXQxFjAUBgNVBAoTDVN0YXJ0\n"+ + "Q29tIEx0ZC4xGjAYBgNVBAsTEUNBIEF1dGhvcml0eSBEZXAuMSkwJwYDVQQDEyBG\n"+ + "cmVlIFNTTCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEhMB8GCSqGSIb3DQEJARYS\n"+ + "YWRtaW5Ac3RhcnRjb20ub3JnMB4XDTA1MDMxNzE3Mzc0OFoXDTM1MDMxMDE3Mzc0\n"+ + "OFowgbAxCzAJBgNVBAYTAklMMQ8wDQYDVQQIEwZJc3JhZWwxDjAMBgNVBAcTBUVp\n"+ + "bGF0MRYwFAYDVQQKEw1TdGFydENvbSBMdGQuMRowGAYDVQQLExFDQSBBdXRob3Jp\n"+ + "dHkgRGVwLjEpMCcGA1UEAxMgRnJlZSBTU0wgQ2VydGlmaWNhdGlvbiBBdXRob3Jp\n"+ + "dHkxITAfBgkqhkiG9w0BCQEWEmFkbWluQHN0YXJ0Y29tLm9yZzCBnzANBgkqhkiG\n"+ + "9w0BAQEFAAOBjQAwgYkCgYEA7YRgACOeyEpRKSfeOqE5tWmrCbIvNP1h3D3TsM+x\n"+ + "18LEwrHkllbEvqoUDufMOlDIOmKdw6OsWXuO7lUaHEe+o5c5s7XvIywI6Nivcy+5\n"+ + "yYPo7QAPyHWlLzRMGOh2iCNJitu27Wjaw7ViKUylS7eYtAkUEKD4/mJ2IhULpNYI\n"+ + "LzUCAwEAAaOCAjwwggI4MA8GA1UdEwEB/wQFMAMBAf8wCwYDVR0PBAQDAgHmMB0G\n"+ + "A1UdDgQWBBQcicOWzL3+MtUNjIExtpidjShkjTCB3QYDVR0jBIHVMIHSgBQcicOW\n"+ + "zL3+MtUNjIExtpidjShkjaGBtqSBszCBsDELMAkGA1UEBhMCSUwxDzANBgNVBAgT\n"+ + "BklzcmFlbDEOMAwGA1UEBxMFRWlsYXQxFjAUBgNVBAoTDVN0YXJ0Q29tIEx0ZC4x\n"+ + "GjAYBgNVBAsTEUNBIEF1dGhvcml0eSBEZXAuMSkwJwYDVQQDEyBGcmVlIFNTTCBD\n"+ + "ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEhMB8GCSqGSIb3DQEJARYSYWRtaW5Ac3Rh\n"+ + "cnRjb20ub3JnggEAMB0GA1UdEQQWMBSBEmFkbWluQHN0YXJ0Y29tLm9yZzAdBgNV\n"+ + "HRIEFjAUgRJhZG1pbkBzdGFydGNvbS5vcmcwEQYJYIZIAYb4QgEBBAQDAgAHMC8G\n"+ + "CWCGSAGG+EIBDQQiFiBGcmVlIFNTTCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAy\n"+ + "BglghkgBhvhCAQQEJRYjaHR0cDovL2NlcnQuc3RhcnRjb20ub3JnL2NhLWNybC5j\n"+ + "cmwwKAYJYIZIAYb4QgECBBsWGWh0dHA6Ly9jZXJ0LnN0YXJ0Y29tLm9yZy8wOQYJ\n"+ + "YIZIAYb4QgEIBCwWKmh0dHA6Ly9jZXJ0LnN0YXJ0Y29tLm9yZy9pbmRleC5waHA/\n"+ + "YXBwPTExMTANBgkqhkiG9w0BAQQFAAOBgQBscSXhnjSRIe/bbL0BCFaPiNhBOlP1\n"+ + "ct8nV0t2hPdopP7rPwl+KLhX6h/BquL/lp9JmeaylXOWxkjHXo0Hclb4g4+fd68p\n"+ + "00UOpO6wNnQt8M2YI3s3S9r+UZjEHjQ8iP2ZO1CnwYszx8JSFhKVU2Ui77qLzmLb\n"+ + "cCOxgN8aIDjnfg==\n"+ + "-----END CERTIFICATE-----"); + super.addPEMCertificate("StartCom Certification Authority", + // X500 Subject, for lookups. + "MH0xCzAJBgNVBAYTAklMMRYwFAYDVQQKEw1TdGFydENvbSBMdGQuMSswKQYDVQQLEyJTZWN1cmUg"+ + "RGlnaXRhbCBDZXJ0aWZpY2F0ZSBTaWduaW5nMSkwJwYDVQQDEyBTdGFydENvbSBDZXJ0aWZpY2F0"+ + "aW9uIEF1dGhvcml0eQ==", + "-----BEGIN CERTIFICATE-----\n"+ + "MIIHyTCCBbGgAwIBAgIBATANBgkqhkiG9w0BAQUFADB9MQswCQYDVQQGEwJJTDEW\n"+ + "MBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwg\n"+ + "Q2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3RhcnRDb20gQ2VydGlmaWNh\n"+ + "dGlvbiBBdXRob3JpdHkwHhcNMDYwOTE3MTk0NjM2WhcNMzYwOTE3MTk0NjM2WjB9\n"+ + "MQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMi\n"+ + "U2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3Rh\n"+ + "cnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUA\n"+ + "A4ICDwAwggIKAoICAQDBiNsJvGxGfHiflXu1M5DycmLWwTYgIiRezul38kMKogZk\n"+ + "pMyONvg45iPwbm2xPN1yo4UcodM9tDMr0y+v/uqwQVlntsQGfQqedIXWeUyAN3rf\n"+ + "OQVSWff0G0ZDpNKFhdLDcfN1YjS6LIp/Ho/u7TTQEceWzVI9ujPW3U3eCztKS5/C\n"+ + "Ji/6tRYccjV3yjxd5srhJosaNnZcAdt0FCX+7bWgiA/deMotHweXMAEtcnn6RtYT\n"+ + "Kqi5pquDSR3l8u/d5AGOGAqPY1MWhWKpDhk6zLVmpsJrdAfkK+F2PrRt2PZE4XNi\n"+ + "HzvEvqBTViVsUQn3qqvKv3b9bZvzndu/PWa8DFaqr5hIlTpL36dYUNk4dalb6kMM\n"+ + "Av+Z6+hsTXBbKWWc3apdzK8BMewM69KN6Oqce+Zu9ydmDBpI125C4z/eIT574Q1w\n"+ + "+2OqqGwaVLRcJXrJosmLFqa7LH4XXgVNWG4SHQHuEhANxjJ/GP/89PrNbpHoNkm+\n"+ + "Gkhpi8KWTRoSsmkXwQqQ1vp5Iki/untp+HDH+no32NgN0nZPV/+Qt+OR0t3vwmC3\n"+ + "Zzrd/qqc8NSLf3Iizsafl7b4r4qgEKjZ+xjGtrVcUjyJthkqcwEKDwOzEmDyei+B\n"+ + "26Nu/yYwl/WL3YlXtq09s68rxbd2AvCl1iuahhQqcvbjM4xdCUsT37uMdBNSSwID\n"+ + "AQABo4ICUjCCAk4wDAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMCAa4wHQYDVR0OBBYE\n"+ + "FE4L7xqkQFulF2mHMMo0aEPQQa7yMGQGA1UdHwRdMFswLKAqoCiGJmh0dHA6Ly9j\n"+ + "ZXJ0LnN0YXJ0Y29tLm9yZy9zZnNjYS1jcmwuY3JsMCugKaAnhiVodHRwOi8vY3Js\n"+ + "LnN0YXJ0Y29tLm9yZy9zZnNjYS1jcmwuY3JsMIIBXQYDVR0gBIIBVDCCAVAwggFM\n"+ + "BgsrBgEEAYG1NwEBATCCATswLwYIKwYBBQUHAgEWI2h0dHA6Ly9jZXJ0LnN0YXJ0\n"+ + "Y29tLm9yZy9wb2xpY3kucGRmMDUGCCsGAQUFBwIBFilodHRwOi8vY2VydC5zdGFy\n"+ + "dGNvbS5vcmcvaW50ZXJtZWRpYXRlLnBkZjCB0AYIKwYBBQUHAgIwgcMwJxYgU3Rh\n"+ + "cnQgQ29tbWVyY2lhbCAoU3RhcnRDb20pIEx0ZC4wAwIBARqBl0xpbWl0ZWQgTGlh\n"+ + "YmlsaXR5LCByZWFkIHRoZSBzZWN0aW9uICpMZWdhbCBMaW1pdGF0aW9ucyogb2Yg\n"+ + "dGhlIFN0YXJ0Q29tIENlcnRpZmljYXRpb24gQXV0aG9yaXR5IFBvbGljeSBhdmFp\n"+ + "bGFibGUgYXQgaHR0cDovL2NlcnQuc3RhcnRjb20ub3JnL3BvbGljeS5wZGYwEQYJ\n"+ + "YIZIAYb4QgEBBAQDAgAHMDgGCWCGSAGG+EIBDQQrFilTdGFydENvbSBGcmVlIFNT\n"+ + "TCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTANBgkqhkiG9w0BAQUFAAOCAgEAFmyZ\n"+ + "9GYMNPXQhV59CuzaEE44HF7fpiUFS5Eyweg78T3dRAlbB0mKKctmArexmvclmAk8\n"+ + "jhvh3TaHK0u7aNM5Zj2gJsfyOZEdUauCe37Vzlrk4gNXcGmXCPleWKYK34wGmkUW\n"+ + "FjgKXlf2Ysd6AgXmvB618p70qSmD+LIU424oh0TDkBreOKk8rENNZEXO3SipXPJz\n"+ + "ewT4F+irsfMuXGRuczE6Eri8sxHkfY+BUZo7jYn0TZNmezwD7dOaHZrzZVD1oNB1\n"+ + "ny+v8OqCQ5j4aZyJecRDjkZy42Q2Eq/3JR44iZB3fsNrarnDy0RLrHiQi+fHLB5L\n"+ + "EUTINFInzQpdn4XBidUaePKVEFMy3YCEZnXZtWgo+2EuvoSoOMCZEoalHmdkrQYu\n"+ + "L6lwhceWD3yJZfWOQ1QOq92lgDmUYMA0yZZwLKMS9R9Ie70cfmu3nZD0Ijuu+Pwq\n"+ + "yvqCUqDvr0tVk+vBtfAii6w0TiYiBKGHLHVKt+V9E9e4DGTANtLJL4YSjCMJwRuC\n"+ + "O3NJo2pXh5Tl1njFmUNj403gdy3hZZlyaQQaRwnmDwFWJPsfvw55qVguucQJAX6V\n"+ + "um0ABj6y6koQOdjQK/W/7HW/lwLFCRsI3FU34oH7N4RDYiDK51ZLZer+bMEkkySh\n"+ + "NOsF/5oirpt9P/FlUQqmMGqz9IgcgA38corog14=\n"+ + "-----END CERTIFICATE-----"); + super.addPEMCertificate("Taiwan GRCA", + // X500 Subject, for lookups. + "MD8xCzAJBgNVBAYTAlRXMTAwLgYDVQQKDCdHb3Zlcm5tZW50IFJvb3QgQ2VydGlmaWNhdGlvbiBB"+ + "dXRob3JpdHk=", + "-----BEGIN CERTIFICATE-----\n"+ + "MIIFcjCCA1qgAwIBAgIQH51ZWtcvwgZEpYAIaeNe9jANBgkqhkiG9w0BAQUFADA/\n"+ + "MQswCQYDVQQGEwJUVzEwMC4GA1UECgwnR292ZXJubWVudCBSb290IENlcnRpZmlj\n"+ + "YXRpb24gQXV0aG9yaXR5MB4XDTAyMTIwNTEzMjMzM1oXDTMyMTIwNTEzMjMzM1ow\n"+ + "PzELMAkGA1UEBhMCVFcxMDAuBgNVBAoMJ0dvdmVybm1lbnQgUm9vdCBDZXJ0aWZp\n"+ + "Y2F0aW9uIEF1dGhvcml0eTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB\n"+ + "AJoluOzMonWoe/fOW1mKydGGEghU7Jzy50b2iPN86aXfTEc2pBsBHH8eV4qNw8XR\n"+ + "IePaJD9IK/ufLqGU5ywck9G/GwGHU5nOp/UKIXZ3/6m3xnOUT0b3EEk3+qhZSV1q\n"+ + "gQdW8or5BtD3cCJNtLdBuTK4sfCxw5w/cP1T3YGq2GN49thTbqGsaoQkclSGxtKy\n"+ + "yhwOeYHWtXBiCAEuTk8O1RGvqa/lmr/czIdtJuTJV6L7lvnM4T9TjGxMfptTCAts\n"+ + "F/tnyMKtsc2AtJfcdgEWFelq16TheEfOhtX7MfP6Mb40qij7cEwdScevLJ1tZqa2\n"+ + "jWR+tSBqnTuBto9AAGdLiYa4zGX+FVPpBMHWXx1E1wovJ5pGfaENda1UhhXcSTvx\n"+ + "ls4Pm6Dso3pdvtUqdULle96ltqqvKKyskKw4t9VoNSZ63Pc78/1Fm9G7Q3hub/FC\n"+ + "VGqY8A2tl+lSXunVanLeavcbYBT0peS2cWeqH+riTcFCQP5nRhc4L0c/cZyu5SHK\n"+ + "YS1tB6iEfC3uUSXxY5Ce/eFXiGvviiNtsea9P63RPZYLhY3Naye7twWb7LuRqQoH\n"+ + "EgKXTiCQ8P8NHuJBO9NAOueNXdpm5AKwB1KYXA6OM5zCppX7VRluTI6uSw+9wThN\n"+ + "Xo+EHWbNxWCWtFJaBYmOlXqYwZE8lSOyDvR5tMl8wUohAgMBAAGjajBoMB0GA1Ud\n"+ + "DgQWBBTMzO/MKWCkO7GStjz6MmKPrCUVOzAMBgNVHRMEBTADAQH/MDkGBGcqBwAE\n"+ + "MTAvMC0CAQAwCQYFKw4DAhoFADAHBgVnKgMAAAQUA5vwIhP/lSg209yewDL7MTqK\n"+ + "UWUwDQYJKoZIhvcNAQEFBQADggIBAECASvomyc5eMN1PhnR2WPWus4MzeKR6dBcZ\n"+ + "TulStbngCnRiqmjKeKBMmo4sIy7VahIkv9Ro04rQ2JyftB8M3jh+Vzj8jeJPXgyf\n"+ + "qzvS/3WXy6TjZwj/5cAWtUgBfen5Cv8b5Wppv3ghqMKnI6mGq3ZW6A4M9hPdKmaK\n"+ + "ZEk9GhiHkASfQlK3T8v+R0F2Ne//AHY2RTKbxkaFXeIksB7jSJaYV0eUVXoPQbFE\n"+ + "JPPB/hprv4j9wabak2BegUqZIJxIZhm1AHlUD7gsL0u8qV1bYH+Mh6XgUmMqvtg7\n"+ + "hUAV/h62ZT/FS9p+tXo1KaMuephgIqP0fSdOLeq0dDzpD6QzDxARvBMB1uUO07+1\n"+ + "EqLhRSPAzAhuYbeJq4PjJB7mXQfnHyA+z2fI56wwbSdLaG5LKlwCCDTb+HbkZ6Mm\n"+ + "nD+iMsJKxYEYMRBWqoTvLQr/uB930r+lWKBi5NdLkXWNiYCYfm3LU05er/ayl4WX\n"+ + "udpVBrkk7tfGOB5jGxI7leFYrPLfhNVfmS8NVVvmONsuP3LpSIXLuykTjx44Vbnz\n"+ + "ssQwmSNOXfJIoRIM3BKQCZBUkQM8R+XVyWXgt0t97EfTsws+rZ7QdAAO671RrcDe\n"+ + "LMDDav7v3Aun+kbfYNucpllQdSNpc5Oy+fwC00fmcc4QAu4njIT/rEUNE1yDMuAl\n"+ + "pYYsfPQS\n"+ + "-----END CERTIFICATE-----"); + super.addPEMCertificate("Firmaprofesional Root CA", + // X500 Subject, for lookups. + "MIGdMQswCQYDVQQGEwJFUzEiMCAGA1UEBxMZQy8gTXVudGFuZXIgMjQ0IEJhcmNlbG9uYTFCMEAG"+ + "A1UEAxM5QXV0b3JpZGFkIGRlIENlcnRpZmljYWNpb24gRmlybWFwcm9mZXNpb25hbCBDSUYgQTYy"+ + "NjM0MDY4MSYwJAYJKoZIhvcNAQkBFhdjYUBmaXJtYXByb2Zlc2lvbmFsLmNvbQ==", + "-----BEGIN CERTIFICATE-----\n"+ + "MIIEVzCCAz+gAwIBAgIBATANBgkqhkiG9w0BAQUFADCBnTELMAkGA1UEBhMCRVMx\n"+ + "IjAgBgNVBAcTGUMvIE11bnRhbmVyIDI0NCBCYXJjZWxvbmExQjBABgNVBAMTOUF1\n"+ + "dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1hcHJvZmVzaW9uYWwgQ0lGIEE2\n"+ + "MjYzNDA2ODEmMCQGCSqGSIb3DQEJARYXY2FAZmlybWFwcm9mZXNpb25hbC5jb20w\n"+ + "HhcNMDExMDI0MjIwMDAwWhcNMTMxMDI0MjIwMDAwWjCBnTELMAkGA1UEBhMCRVMx\n"+ + "IjAgBgNVBAcTGUMvIE11bnRhbmVyIDI0NCBCYXJjZWxvbmExQjBABgNVBAMTOUF1\n"+ + "dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1hcHJvZmVzaW9uYWwgQ0lGIEE2\n"+ + "MjYzNDA2ODEmMCQGCSqGSIb3DQEJARYXY2FAZmlybWFwcm9mZXNpb25hbC5jb20w\n"+ + "ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDnIwNvbyOlXnjOlSztlB5u\n"+ + "Cp4Bx+ow0Syd3Tfom5h5VtP8c9/Qit5Vj1H5WuretXDE7aTt/6MNbg9kUDGvASdY\n"+ + "rv5sp0ovFy3Tc9UTHI9ZpTQsHVQERc1ouKDAA6XPhUJHlShbz++AbOCQl4oBPB3z\n"+ + "hxAwJkh91/zpnZFx/0GaqUC1N5wpIE8fUuOgfRNtVLcK3ulqTgesrBlf3H5idPay\n"+ + "BQC6haD9HThuy1q7hryUZzM1gywfI834yJFxzJeL764P3CkDG8A563DtwW4O2GcL\n"+ + "iam8NeTvtjS0pbbELaW+0MOUJEjb35bTALVmGotmBQ/dPz/LP6pemkr4tErvlTcb\n"+ + "AgMBAAGjgZ8wgZwwKgYDVR0RBCMwIYYfaHR0cDovL3d3dy5maXJtYXByb2Zlc2lv\n"+ + "bmFsLmNvbTASBgNVHRMBAf8ECDAGAQH/AgEBMCsGA1UdEAQkMCKADzIwMDExMDI0\n"+ + "MjIwMDAwWoEPMjAxMzEwMjQyMjAwMDBaMA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4E\n"+ + "FgQUMwugZtHq2s7eYpMEKFK1FH84aLcwDQYJKoZIhvcNAQEFBQADggEBAEdz/o0n\n"+ + "VPD11HecJ3lXV7cVVuzH2Fi3AQL0M+2TUIiefEaxvT8Ub/GzR0iLjJcG1+p+o1wq\n"+ + "u00vR+L4OQbJnC4xGgN49Lw4xiKLMzHwFgQEffl25EvXwOaD7FnMP97/T2u3Z36m\n"+ + "hoEyIwOdyPdfwUpgpZKpsaSgYMN4h7Mi8yrrW6ntBas3D7Hi05V2Y1Z0jFhyGzfl\n"+ + "ZKG+TQyTmAyX9odtsz/ny4Cm7YjHX1BiAuiZdBbQ5rQ58SfLyEDW44YQqSMSkuBp\n"+ + "QWOnryULwMWSyx6Yo1q6xTMPoJcB3X/ge9YGVM+h4k0460tQtcsm9MracEpqoeJ5\n"+ + "quGnM/b9Sh/22WA=\n"+ + "-----END CERTIFICATE-----"); + super.addPEMCertificate("Wells Fargo Root CA", + // X500 Subject, for lookups. + "MIGCMQswCQYDVQQGEwJVUzEUMBIGA1UEChMLV2VsbHMgRmFyZ28xLDAqBgNVBAsTI1dlbGxzIEZh"+ + "cmdvIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MS8wLQYDVQQDEyZXZWxscyBGYXJnbyBSb290IENl"+ + "cnRpZmljYXRlIEF1dGhvcml0eQ==", + "-----BEGIN CERTIFICATE-----\n"+ + "MIID5TCCAs2gAwIBAgIEOeSXnjANBgkqhkiG9w0BAQUFADCBgjELMAkGA1UEBhMC\n"+ + "VVMxFDASBgNVBAoTC1dlbGxzIEZhcmdvMSwwKgYDVQQLEyNXZWxscyBGYXJnbyBD\n"+ + "ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEvMC0GA1UEAxMmV2VsbHMgRmFyZ28gUm9v\n"+ + "dCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcNMDAxMDExMTY0MTI4WhcNMjEwMTE0\n"+ + "MTY0MTI4WjCBgjELMAkGA1UEBhMCVVMxFDASBgNVBAoTC1dlbGxzIEZhcmdvMSww\n"+ + "KgYDVQQLEyNXZWxscyBGYXJnbyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEvMC0G\n"+ + "A1UEAxMmV2VsbHMgRmFyZ28gUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEi\n"+ + "MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDVqDM7Jvk0/82bfuUER84A4n13\n"+ + "5zHCLielTWi5MbqNQ1mXx3Oqfz1cQJ4F5aHiidlMuD+b+Qy0yGIZLEWukR5zcUHE\n"+ + "SxP9cMIlrCL1dQu3U+SlK93OvRw6esP3E48mVJwWa2uv+9iWsWCaSOAlIiR5NM4O\n"+ + "JgALTqv9i86C1y8IcGjBqAr5dE8Hq6T54oN+J3N0Prj5OEL8pahbSCOz6+MlsoCu\n"+ + "ltQKnMJ4msZoGK43YjdeUXWoWGPAUe5AeH6orxqg4bB4nVCMe+ez/I4jsNtlAHCE\n"+ + "AQgAFG5Uhpq6zPk3EPbg3oQtnaSFN9OH4xXQwReQfhkhahKpdv0SAulPIV4XAgMB\n"+ + "AAGjYTBfMA8GA1UdEwEB/wQFMAMBAf8wTAYDVR0gBEUwQzBBBgtghkgBhvt7hwcB\n"+ + "CzAyMDAGCCsGAQUFBwIBFiRodHRwOi8vd3d3LndlbGxzZmFyZ28uY29tL2NlcnRw\n"+ + "b2xpY3kwDQYJKoZIhvcNAQEFBQADggEBANIn3ZwKdyu7IvICtUpKkfnRLb7kuxpo\n"+ + "7w6kAOnu5+/u9vnldKTC2FJYxHT7zmu1Oyl5GFrvm+0fazbuSCUlFLZWohDo7qd/\n"+ + "0D+j0MNdJu4HzMPBJCGHHt8qElNvQRbn7a6U+oxy+hNH8Dx+rn0ROhPs7fpvcmR7\n"+ + "nX1/Jv16+yWt6j4pf0zjAFcysLPp7VMX2YuyFA4w6OXVE8Zkr8QA1dhYJPz1j+zx\n"+ + "x32l2w8n0cbyQIjmH/ZhqPRCyLk306m+LFZ4wnKbWV01QIroTmMatukgalHizqSQ\n"+ + "33ZwmVxwQ023tqcZZE6St8WRPH9IFmV7Fv3L/PvZ1dZPIWU7Sn9Ho/s=\n"+ + "-----END CERTIFICATE-----"); + super.addPEMCertificate("Swisscom Root CA 1", + // X500 Subject, for lookups. + "MGQxCzAJBgNVBAYTAmNoMREwDwYDVQQKEwhTd2lzc2NvbTElMCMGA1UECxMcRGlnaXRhbCBDZXJ0"+ + "aWZpY2F0ZSBTZXJ2aWNlczEbMBkGA1UEAxMSU3dpc3Njb20gUm9vdCBDQSAx", + "-----BEGIN CERTIFICATE-----\n"+ + "MIIF2TCCA8GgAwIBAgIQXAuFXAvnWUHfV8w/f52oNjANBgkqhkiG9w0BAQUFADBk\n"+ + "MQswCQYDVQQGEwJjaDERMA8GA1UEChMIU3dpc3Njb20xJTAjBgNVBAsTHERpZ2l0\n"+ + "YWwgQ2VydGlmaWNhdGUgU2VydmljZXMxGzAZBgNVBAMTElN3aXNzY29tIFJvb3Qg\n"+ + "Q0EgMTAeFw0wNTA4MTgxMjA2MjBaFw0yNTA4MTgyMjA2MjBaMGQxCzAJBgNVBAYT\n"+ + "AmNoMREwDwYDVQQKEwhTd2lzc2NvbTElMCMGA1UECxMcRGlnaXRhbCBDZXJ0aWZp\n"+ + "Y2F0ZSBTZXJ2aWNlczEbMBkGA1UEAxMSU3dpc3Njb20gUm9vdCBDQSAxMIICIjAN\n"+ + "BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA0LmwqAzZuz8h+BvVM5OAFmUgdbI9\n"+ + "m2BtRsiMMW8Xw/qabFbtPMWRV8PNq5ZJkCoZSx6jbVfd8StiKHVFXqrWW/oLJdih\n"+ + "FvkcxC7mlSpnzNApbjyFNDhhSbEAn9Y6cV9Nbc5fuankiX9qUvrKm/LcqfmdmUc/\n"+ + "TilftKaNXXsLmREDA/7n29uj/x2lzZAeAR81sH8A25Bvxn570e56eqeqDFdvpG3F\n"+ + "EzuwpdntMhy0XmeLVNxzh+XTF3xmUHJd1BpYwdnP2IkCb6dJtDZd0KTeByy2dbco\n"+ + "kdaXvij1mB7qWybJvbCXc9qukSbraMH5ORXWZ0sKbU/Lz7DkQnGMU3nn7uHbHaBu\n"+ + "HYwadzVcFh4rUx80i9Fs/PJnB3r1re3WmquhsUvhzDdf/X/NTa64H5xD+SpYVUNF\n"+ + "vJbNcA78yeNmuk6NO4HLFWR7uZToXTNShXEuT46iBhFRyePLoW4xCGQMwtI89Tbo\n"+ + "19AOeCMgkckkKmUpWyL3Ic6DXqTz3kvTaI9GdVyDCW4pa8RwjPWd1yAv/0bSKzjC\n"+ + "L3UcPX7ape8eYIVpQtPM+GP+HkM5haa2Y0EQs3MevNP6yn0WR+Kn1dCjigoIlmJW\n"+ + "bjTb2QK5MHXjBNLnj8KwEUAKrNVxAmKLMb7dxiNYMUJDLXT5xp6mig/p/r+D5kNX\n"+ + "JLrvRjSq1xIBOO0CAwEAAaOBhjCBgzAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0hBBYw\n"+ + "FDASBgdghXQBUwABBgdghXQBUwABMBIGA1UdEwEB/wQIMAYBAf8CAQcwHwYDVR0j\n"+ + "BBgwFoAUAyUv3m+CATpcLNwroWm1Z9SM0/0wHQYDVR0OBBYEFAMlL95vggE6XCzc\n"+ + "K6FptWfUjNP9MA0GCSqGSIb3DQEBBQUAA4ICAQA1EMvspgQNDQ/NwNurqPKIlwzf\n"+ + "ky9NfEBWMXrrpA9gzXrzvsMnjgM+pN0S734edAY8PzHyHHuRMSG08NBsl9Tpl7Ik\n"+ + "Vh5WwzW9iAUPWxAaZOHHgjD5Mq2eUCzneAXQMbFamIp1TpBcahQq4FJHgmDmHtqB\n"+ + "sfsUC1rxn9KVuj7QG9YVHaO+htXbD8BJZLsuUBlL0iT43R4HVtA4oJVwIHaM190e\n"+ + "3p9xxCPvgxNcoyQVTSlAPGrEqdi3pkSlDfTgnXceQHAm/NrZNuR55LU/vJtlvrsR\n"+ + "ls/bxig5OgjOR1tTWsWZ/l2p3e9M1MalrQLmjAcSHm8D0W+go/MpvRLHUKKwf4ip\n"+ + "mXeascClOS5cfGniLLDqN2qk4Vrh9VDlg++luyqI54zb/W1elxmofmZ1a3Hqv7HH\n"+ + "b6D0jqTsNFFbjCYDcKF31QESVwA12yPeDooomf2xEG9L/zgtYE4snOtnta1J7ksf\n"+ + "rK/7DZBaZmBwXarNeNQk7shBoJMBkpxqnvy5JMWzFYJ+vq6VK+uxwNrjAWALXmms\n"+ + "hFZhvnEX/h0TD/7Gh0Xp/jKgGg0TpJRVcaUWi7rKibCyx/yP2FS1k2Kdzs9Z+z0Y\n"+ + "zirLNRWCXf9UIltxUvu3yf5gmwBBZPCqKuy2QkPOiWaByIufOVQDJdMWNY6E0F/6\n"+ + "MBr1mmz0DlP5OlvRHA==\n"+ + "-----END CERTIFICATE-----"); + super.addPEMCertificate("DigiCert Assured ID Root CA", + // X500 Subject, for lookups. + "MGUxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdp"+ + "Y2VydC5jb20xJDAiBgNVBAMTG0RpZ2lDZXJ0IEFzc3VyZWQgSUQgUm9vdCBDQQ==", + "-----BEGIN CERTIFICATE-----\n"+ + "MIIDtzCCAp+gAwIBAgIQDOfg5RfYRv6P5WD8G/AwOTANBgkqhkiG9w0BAQUFADBl\n"+ + "MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3\n"+ + "d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv\n"+ + "b3QgQ0EwHhcNMDYxMTEwMDAwMDAwWhcNMzExMTEwMDAwMDAwWjBlMQswCQYDVQQG\n"+ + "EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl\n"+ + "cnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0EwggEi\n"+ + "MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCtDhXO5EOAXLGH87dg+XESpa7c\n"+ + "JpSIqvTO9SA5KFhgDPiA2qkVlTJhPLWxKISKityfCgyDF3qPkKyK53lTXDGEKvYP\n"+ + "mDI2dsze3Tyoou9q+yHyUmHfnyDXH+Kx2f4YZNISW1/5WBg1vEfNoTb5a3/UsDg+\n"+ + "wRvDjDPZ2C8Y/igPs6eD1sNuRMBhNZYW/lmci3Zt1/GiSw0r/wty2p5g0I6QNcZ4\n"+ + "VYcgoc/lbQrISXwxmDNsIumH0DJaoroTghHtORedmTpyoeb6pNnVFzF1roV9Iq4/\n"+ + "AUaG9ih5yLHa5FcXxH4cDrC0kqZWs72yl+2qp/C3xag/lRbQ/6GW6whfGHdPAgMB\n"+ + "AAGjYzBhMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW\n"+ + "BBRF66Kv9JLLgjEtUYunpyGd823IDzAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYun\n"+ + "pyGd823IDzANBgkqhkiG9w0BAQUFAAOCAQEAog683+Lt8ONyc3pklL/3cmbYMuRC\n"+ + "dWKuh+vy1dneVrOfzM4UKLkNl2BcEkxY5NM9g0lFWJc1aRqoR+pWxnmrEthngYTf\n"+ + "fwk8lOa4JiwgvT2zKIn3X/8i4peEH+ll74fg38FnSbNd67IJKusm7Xi+fT8r87cm\n"+ + "NW1fiQG2SVufAQWbqz0lwcy2f8Lxb4bG+mRo64EtlOtCt/qMHt1i8b5QZ7dsvfPx\n"+ + "H2sMNgcWfzd8qVttevESRmCD1ycEvkvOl77DZypoEd+A5wwzZr8TDRRu838fYxAe\n"+ + "+o0bJW1sj6W3YQGx0qMmoRBxna3iw/nDmVG3KwcIzi7mULKn+gpFL6Lw8g==\n"+ + "-----END CERTIFICATE-----"); + super.addPEMCertificate("DigiCert Global Root CA", + // X500 Subject, for lookups. + "MGExCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdp"+ + "Y2VydC5jb20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENB", + "-----BEGIN CERTIFICATE-----\n"+ + "MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh\n"+ + "MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3\n"+ + "d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD\n"+ + "QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT\n"+ + "MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j\n"+ + "b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG\n"+ + "9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB\n"+ + "CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97\n"+ + "nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt\n"+ + "43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P\n"+ + "T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4\n"+ + "gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO\n"+ + "BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR\n"+ + "TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw\n"+ + "DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr\n"+ + "hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg\n"+ + "06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF\n"+ + "PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls\n"+ + "YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk\n"+ + "CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4=\n"+ + "-----END CERTIFICATE-----"); + super.addPEMCertificate("DigiCert High Assurance EV Root CA", + // X500 Subject, for lookups. + "MGwxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdp"+ + "Y2VydC5jb20xKzApBgNVBAMTIkRpZ2lDZXJ0IEhpZ2ggQXNzdXJhbmNlIEVWIFJvb3QgQ0E=", + "-----BEGIN CERTIFICATE-----\n"+ + "MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBs\n"+ + "MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3\n"+ + "d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j\n"+ + "ZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTMxMTExMDAwMDAwMFowbDEL\n"+ + "MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3\n"+ + "LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug\n"+ + "RVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm\n"+ + "+9S75S0tMqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTW\n"+ + "PNt0OKRKzE0lgvdKpVMSOO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEM\n"+ + "xChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFB\n"+ + "Ik5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQNAQTXKFx01p8VdteZOE3\n"+ + "hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUeh10aUAsg\n"+ + "EsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQF\n"+ + "MAMBAf8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaA\n"+ + "FLE+w2kD+L9HAdSYJhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3Nec\n"+ + "nzyIZgYIVyHbIUf4KmeqvxgydkAQV8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6z\n"+ + "eM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFpmyPInngiK3BD41VHMWEZ71jF\n"+ + "hS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkKmNEVX58Svnw2\n"+ + "Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe\n"+ + "vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep\n"+ + "+OkuE6N36B9K\n"+ + "-----END CERTIFICATE-----"); + super.addPEMCertificate("Certplus Class 2 Primary CA", + // X500 Subject, for lookups. + "MD0xCzAJBgNVBAYTAkZSMREwDwYDVQQKEwhDZXJ0cGx1czEbMBkGA1UEAxMSQ2xhc3MgMiBQcmlt"+ + "YXJ5IENB", + "-----BEGIN CERTIFICATE-----\n"+ + "MIIDkjCCAnqgAwIBAgIRAIW9S/PY2uNp9pTXX8OlRCMwDQYJKoZIhvcNAQEFBQAw\n"+ + "PTELMAkGA1UEBhMCRlIxETAPBgNVBAoTCENlcnRwbHVzMRswGQYDVQQDExJDbGFz\n"+ + "cyAyIFByaW1hcnkgQ0EwHhcNOTkwNzA3MTcwNTAwWhcNMTkwNzA2MjM1OTU5WjA9\n"+ + "MQswCQYDVQQGEwJGUjERMA8GA1UEChMIQ2VydHBsdXMxGzAZBgNVBAMTEkNsYXNz\n"+ + "IDIgUHJpbWFyeSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANxQ\n"+ + "ltAS+DXSCHh6tlJw/W/uz7kRy1134ezpfgSN1sxvc0NXYKwzCkTsA18cgCSR5aiR\n"+ + "VhKC9+Ar9NuuYS6JEI1rbLqzAr3VNsVINyPi8Fo3UjMXEuLRYE2+L0ER4/YXJQyL\n"+ + "kcAbmXuZVg2v7tK8R1fjeUl7NIknJITesezpWE7+Tt9avkGtrAjFGA7v0lPubNCd\n"+ + "EgETjdyAYveVqUSISnFOYFWe2yMZeVYHDD9jC1yw4r5+FfyUM1hBOHTE4Y+L3yas\n"+ + "H7WLO7dDWWuwJKZtkIvEcupdM5i3y95ee++U8Rs+yskhwcWYAqqi9lt3m/V+llU0\n"+ + "HGdpwPFC40es/CgcZlUCAwEAAaOBjDCBiTAPBgNVHRMECDAGAQH/AgEKMAsGA1Ud\n"+ + "DwQEAwIBBjAdBgNVHQ4EFgQU43Mt38sOKAze3bOkynm4jrvoMIkwEQYJYIZIAYb4\n"+ + "QgEBBAQDAgEGMDcGA1UdHwQwMC4wLKAqoCiGJmh0dHA6Ly93d3cuY2VydHBsdXMu\n"+ + "Y29tL0NSTC9jbGFzczIuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQCnVM+IRBnL39R/\n"+ + "AN9WM2K191EBkOvDP9GIROkkXe/nFL0gt5o8AP5tn9uQ3Nf0YtaLcF3n5QRIqWh8\n"+ + "yfFC82x/xXp8HVGIutIKPidd3i1RTtMTZGnkLuPT55sJmabglZvOGtd/vjzOUrMR\n"+ + "FcEPF80Du5wlFbqidon8BvEY0JNLDnyCt6X09l/+7UCmnYR0ObncHoUW2ikbhiMA\n"+ + "ybuJfm6AiB4vFLQDJKgybwOaRywwvlbGp0ICcBvqQNi6BQNwB6SW//1IMwrh3KWB\n"+ + "kJtN3X3n57LNXMhqlfil9o3EXXgIvnsG1knPGTZQIy4I5p4FTUcY1Rbpsda2ENW7\n"+ + "l7+ijrRU\n"+ + "-----END CERTIFICATE-----"); + } + override public function addPEMCertificate(name:String,subject:String,pem:String):void { + throw new Error("Cannot add certificates to the Root CA store."); + } + override public function addCertificate(cert:X509Certificate):void { + throw new Error("Cannot add certificates to the Root CA store."); + } + } +} diff --git a/flash-src/third-party/com/hurlant/crypto/cert/X509Certificate.as b/flash-src/third-party/com/hurlant/crypto/cert/X509Certificate.as new file mode 100755 index 0000000..db4ea1c --- /dev/null +++ b/flash-src/third-party/com/hurlant/crypto/cert/X509Certificate.as @@ -0,0 +1,218 @@ +/**
+ * X509Certificate
+ *
+ * A representation for a X509 Certificate, with
+ * methods to parse, verify and sign it.
+ * Copyright (c) 2007 Henri Torgemane
+ *
+ * See LICENSE.txt for full license information.
+ */
+package com.hurlant.crypto.cert {
+ import com.hurlant.crypto.hash.IHash;
+ import com.hurlant.crypto.hash.MD2;
+ import com.hurlant.crypto.hash.MD5;
+ import com.hurlant.crypto.hash.SHA1;
+ import com.hurlant.crypto.rsa.RSAKey;
+ import com.hurlant.util.ArrayUtil;
+ import com.hurlant.util.Base64;
+ import com.hurlant.util.der.ByteString;
+ import com.hurlant.util.der.DER;
+ import com.hurlant.util.der.OID;
+ import com.hurlant.util.der.ObjectIdentifier;
+ import com.hurlant.util.der.PEM;
+ import com.hurlant.util.der.PrintableString;
+ import com.hurlant.util.der.Sequence;
+ import com.hurlant.util.der.Type;
+
+ import flash.utils.ByteArray;
+
+ public class X509Certificate {
+ private var _loaded:Boolean;
+ private var _param:*;
+ private var _obj:Object;
+ public function X509Certificate(p:*) {
+ _loaded = false;
+ _param = p;
+ // lazy initialization, to avoid unnecessary parsing of every builtin CA at start-up.
+ }
+ private function load():void {
+ if (_loaded) return;
+ var p:* = _param;
+ var b:ByteArray;
+ if (p is String) {
+ b = PEM.readCertIntoArray(p as String);
+ } else if (p is ByteArray) {
+ b = p;
+ }
+ if (b!=null) {
+ _obj = DER.parse(b, Type.TLS_CERT);
+ _loaded = true;
+ } else {
+ throw new Error("Invalid x509 Certificate parameter: "+p);
+ }
+ }
+ public function isSigned(store:X509CertificateCollection, CAs:X509CertificateCollection, time:Date=null):Boolean {
+ load();
+ // check timestamps first. cheapest.
+ if (time==null) {
+ time = new Date;
+ }
+ var notBefore:Date = getNotBefore();
+ var notAfter:Date = getNotAfter();
+ if (time.getTime()<notBefore.getTime()) return false; // cert isn't born yet.
+ if (time.getTime()>notAfter.getTime()) return false; // cert died of old age.
+ // check signature.
+ var subject:String = getIssuerPrincipal();
+ // try from CA first, since they're treated better.
+ var parent:X509Certificate = CAs.getCertificate(subject);
+ var parentIsAuthoritative:Boolean = false;
+ if (parent == null) {
+ parent = store.getCertificate(subject);
+ if (parent == null) {
+ return false; // issuer not found
+ }
+ } else {
+ parentIsAuthoritative = true;
+ }
+ if (parent == this) { // pathological case. avoid infinite loop
+ return false; // isSigned() returns false if we're self-signed.
+ }
+ if (!(parentIsAuthoritative&&parent.isSelfSigned(time)) &&
+ !parent.isSigned(store, CAs, time)) {
+ return false;
+ }
+ var key:RSAKey = parent.getPublicKey();
+ return verifyCertificate(key);
+ }
+ public function isSelfSigned(time:Date):Boolean {
+ load();
+
+ var key:RSAKey = getPublicKey();
+ return verifyCertificate(key);
+ }
+ private function verifyCertificate(key:RSAKey):Boolean {
+ var algo:String = getAlgorithmIdentifier();
+ var hash:IHash;
+ var oid:String;
+ switch (algo) {
+ case OID.SHA1_WITH_RSA_ENCRYPTION:
+ hash = new SHA1;
+ oid = OID.SHA1_ALGORITHM;
+ break;
+ case OID.MD2_WITH_RSA_ENCRYPTION:
+ hash = new MD2;
+ oid = OID.MD2_ALGORITHM;
+ break;
+ case OID.MD5_WITH_RSA_ENCRYPTION:
+ hash = new MD5;
+ oid = OID.MD5_ALGORITHM;
+ break;
+ default:
+ return false;
+ }
+ var data:ByteArray = _obj.signedCertificate_bin;
+ var buf:ByteArray = new ByteArray;
+ key.verify(_obj.encrypted, buf, _obj.encrypted.length);
+ buf.position=0;
+ data = hash.hash(data);
+ var obj:Object = DER.parse(buf, Type.RSA_SIGNATURE);
+ if (obj.algorithm.algorithmId.toString() != oid) {
+ return false; // wrong algorithm
+ }
+ if (!ArrayUtil.equals(obj.hash, data)) {
+ return false; // hashes don't match
+ }
+ return true;
+ }
+
+ /**
+ * This isn't used anywhere so far.
+ * It would become useful if we started to offer facilities
+ * to generate and sign X509 certificates.
+ *
+ * @param key
+ * @param algo
+ * @return
+ *
+ */
+ private function signCertificate(key:RSAKey, algo:String):ByteArray {
+ var hash:IHash;
+ var oid:String;
+ switch (algo) {
+ case OID.SHA1_WITH_RSA_ENCRYPTION:
+ hash = new SHA1;
+ oid = OID.SHA1_ALGORITHM;
+ break;
+ case OID.MD2_WITH_RSA_ENCRYPTION:
+ hash = new MD2;
+ oid = OID.MD2_ALGORITHM;
+ break;
+ case OID.MD5_WITH_RSA_ENCRYPTION:
+ hash = new MD5;
+ oid = OID.MD5_ALGORITHM;
+ break;
+ default:
+ return null
+ }
+ var data:ByteArray = _obj.signedCertificate_bin;
+ data = hash.hash(data);
+ var seq1:Sequence = new Sequence;
+ seq1[0] = new Sequence;
+ seq1[0][0] = new ObjectIdentifier(0,0, oid);
+ seq1[0][1] = null;
+ seq1[1] = new ByteString;
+ seq1[1].writeBytes(data);
+ data = seq1.toDER();
+ var buf:ByteArray = new ByteArray;
+ key.sign(data, buf, data.length);
+ return buf;
+ }
+
+ public function getPublicKey():RSAKey {
+ load();
+ var pk:ByteArray = _obj.signedCertificate.subjectPublicKeyInfo.subjectPublicKey as ByteArray;
+ pk.position = 0;
+ var rsaKey:Object = DER.parse(pk, [{name:"N"},{name:"E"}]);
+ return new RSAKey(rsaKey.N, rsaKey.E.valueOf());
+ }
+
+ /**
+ * Returns a subject principal, as an opaque base64 string.
+ * This is only used as a hash key for known certificates.
+ *
+ * Note that this assumes X509 DER-encoded certificates are uniquely encoded,
+ * as we look for exact matches between Issuer and Subject fields.
+ *
+ */
+ public function getSubjectPrincipal():String {
+ load();
+ return Base64.encodeByteArray(_obj.signedCertificate.subject_bin);
+ }
+ /**
+ * Returns an issuer principal, as an opaque base64 string.
+ * This is only used to quickly find matching parent certificates.
+ *
+ * Note that this assumes X509 DER-encoded certificates are uniquely encoded,
+ * as we look for exact matches between Issuer and Subject fields.
+ *
+ */
+ public function getIssuerPrincipal():String {
+ load();
+ return Base64.encodeByteArray(_obj.signedCertificate.issuer_bin);
+ }
+ public function getAlgorithmIdentifier():String {
+ return _obj.algorithmIdentifier.algorithmId.toString();
+ }
+ public function getNotBefore():Date {
+ return _obj.signedCertificate.validity.notBefore.date;
+ }
+ public function getNotAfter():Date {
+ return _obj.signedCertificate.validity.notAfter.date;
+ }
+
+ public function getCommonName():String {
+ var subject:Sequence = _obj.signedCertificate.subject;
+ return (subject.findAttributeValue(OID.COMMON_NAME) as PrintableString).getString();
+ }
+ }
+}
\ No newline at end of file diff --git a/flash-src/third-party/com/hurlant/crypto/cert/X509CertificateCollection.as b/flash-src/third-party/com/hurlant/crypto/cert/X509CertificateCollection.as new file mode 100755 index 0000000..db11e40 --- /dev/null +++ b/flash-src/third-party/com/hurlant/crypto/cert/X509CertificateCollection.as @@ -0,0 +1,57 @@ +/**
+ * X509CertificateCollection
+ *
+ * A class to store and index X509 Certificates by Subject.
+ * Copyright (c) 2007 Henri Torgemane
+ *
+ * See LICENSE.txt for full license information.
+ */
+package com.hurlant.crypto.cert {
+
+ public class X509CertificateCollection {
+
+ private var _map:Object;
+
+ public function X509CertificateCollection() {
+ _map = {};
+ }
+
+ /**
+ * Mostly meant for built-in CA loading.
+ * This entry-point allows to index CAs without parsing them.
+ *
+ * @param name A friendly name. not currently used
+ * @param subject base64 DER encoded Subject principal for the Cert
+ * @param pem PEM encoded certificate data
+ *
+ */
+ public function addPEMCertificate(name:String, subject:String, pem:String):void {
+ _map[subject] = new X509Certificate(pem);
+ }
+
+ /**
+ * Adds a X509 certificate to the collection.
+ * This call will force the certificate to be parsed.
+ *
+ * @param cert A X509 certificate
+ *
+ */
+ public function addCertificate(cert:X509Certificate):void {
+ var subject:String = cert.getSubjectPrincipal();
+ _map[subject] = cert;
+ }
+
+ /**
+ * Returns a X509 Certificate present in the collection, given
+ * a base64 DER encoded X500 Subject principal
+ *
+ * @param subject A Base64 DER-encoded Subject principal
+ * @return A matching certificate, or null.
+ *
+ */
+ public function getCertificate(subject:String):X509Certificate {
+ return _map[subject];
+ }
+
+ }
+}
\ No newline at end of file diff --git a/flash-src/third-party/com/hurlant/crypto/hash/HMAC.as b/flash-src/third-party/com/hurlant/crypto/hash/HMAC.as new file mode 100644 index 0000000..8215afc --- /dev/null +++ b/flash-src/third-party/com/hurlant/crypto/hash/HMAC.as @@ -0,0 +1,82 @@ +/**
+ * HMAC
+ *
+ * An ActionScript 3 implementation of HMAC, Keyed-Hashing for Message
+ * Authentication, as defined by RFC-2104
+ * Copyright (c) 2007 Henri Torgemane
+ *
+ * See LICENSE.txt for full license information.
+ */
+package com.hurlant.crypto.hash
+{
+ import flash.utils.ByteArray;
+ import com.hurlant.util.Hex;
+
+ public class HMAC implements IHMAC
+ {
+ private var hash:IHash;
+ private var bits:uint;
+
+ /**
+ * Create a HMAC object, using a Hash function, and
+ * optionally a number of bits to return.
+ * The HMAC will be truncated to that size if needed.
+ */
+ public function HMAC(hash:IHash, bits:uint=0) {
+ this.hash = hash;
+ this.bits = bits;
+ }
+
+
+ public function getHashSize():uint {
+ if (bits!=0) {
+ return bits/8;
+ } else {
+ return hash.getHashSize();
+ }
+ }
+
+ /**
+ * Compute a HMAC using a key and some data.
+ * It doesn't modify either, and returns a new ByteArray with the HMAC value.
+ */
+ public function compute(key:ByteArray, data:ByteArray):ByteArray {
+ var hashKey:ByteArray;
+ if (key.length>hash.getInputSize()) {
+ hashKey = hash.hash(key);
+ } else {
+ hashKey = new ByteArray;
+ hashKey.writeBytes(key);
+ }
+ while (hashKey.length<hash.getInputSize()) {
+ hashKey[hashKey.length]=0;
+ }
+ var innerKey:ByteArray = new ByteArray;
+ var outerKey:ByteArray = new ByteArray;
+ for (var i:uint=0;i<hashKey.length;i++) {
+ innerKey[i] = hashKey[i] ^ 0x36;
+ outerKey[i] = hashKey[i] ^ 0x5c;
+ }
+ // inner + data
+ innerKey.position = hashKey.length;
+ innerKey.writeBytes(data);
+ var innerHash:ByteArray = hash.hash(innerKey);
+ // outer + innerHash
+ outerKey.position = hashKey.length;
+ outerKey.writeBytes(innerHash);
+ var outerHash:ByteArray = hash.hash(outerKey);
+ if (bits>0 && bits<8*outerHash.length) {
+ outerHash.length = bits/8;
+ }
+ return outerHash;
+ }
+ public function dispose():void {
+ hash = null;
+ bits = 0;
+ }
+ public function toString():String {
+ return "hmac-"+(bits>0?bits+"-":"")+hash.toString();
+ }
+
+ }
+}
\ No newline at end of file diff --git a/flash-src/third-party/com/hurlant/crypto/hash/IHMAC.as b/flash-src/third-party/com/hurlant/crypto/hash/IHMAC.as new file mode 100755 index 0000000..f0ee063 --- /dev/null +++ b/flash-src/third-party/com/hurlant/crypto/hash/IHMAC.as @@ -0,0 +1,27 @@ +/**
+ * HMAC
+ *
+ * An ActionScript 3 interface for HMAC & MAC
+ * implementations.
+ *
+ * Loosely copyrighted by Bobby Parker
+ *
+ * See LICENSE.txt for full license information.
+ */
+package com.hurlant.crypto.hash
+{
+ import flash.utils.ByteArray;
+
+ public interface IHMAC
+ {
+ function getHashSize():uint;
+ /**
+ * Compute a HMAC using a key and some data.
+ * It doesn't modify either, and returns a new ByteArray with the HMAC value.
+ */
+ function compute(key:ByteArray, data:ByteArray):ByteArray;
+ function dispose():void;
+ function toString():String;
+
+ }
+}
\ No newline at end of file diff --git a/flash-src/third-party/com/hurlant/crypto/hash/IHash.as b/flash-src/third-party/com/hurlant/crypto/hash/IHash.as new file mode 100644 index 0000000..32c5321 --- /dev/null +++ b/flash-src/third-party/com/hurlant/crypto/hash/IHash.as @@ -0,0 +1,21 @@ +/**
+ * IHash
+ *
+ * An interface for each hash function to implement
+ * Copyright (c) 2007 Henri Torgemane
+ *
+ * See LICENSE.txt for full license information.
+ */
+package com.hurlant.crypto.hash
+{
+ import flash.utils.ByteArray;
+
+ public interface IHash
+ {
+ function getInputSize():uint;
+ function getHashSize():uint;
+ function hash(src:ByteArray):ByteArray;
+ function toString():String;
+ function getPadSize():int;
+ }
+}
\ No newline at end of file diff --git a/flash-src/third-party/com/hurlant/crypto/hash/MAC.as b/flash-src/third-party/com/hurlant/crypto/hash/MAC.as new file mode 100755 index 0000000..0815d6c --- /dev/null +++ b/flash-src/third-party/com/hurlant/crypto/hash/MAC.as @@ -0,0 +1,137 @@ +/**
+ * MAC
+ *
+ * An ActionScript 3 implementation of MAC, Message Authentication Code
+ * for use with SSL 3.0.
+ * Loosely copyrighted by Bobby Parker.
+ * As3crypto copyrighted by Henri Torgemane.
+ *
+ * See LICENSE.txt for full license information.
+ */
+package com.hurlant.crypto.hash
+{
+ import flash.utils.ByteArray;
+ import com.hurlant.util.Hex;
+
+ public class MAC implements IHMAC
+ {
+ private var hash:IHash;
+ private var bits:uint;
+ private var pad_1:ByteArray;
+ private var pad_2:ByteArray;
+ private var innerHash:ByteArray;
+ private var outerHash:ByteArray;
+ private var outerKey:ByteArray;
+ private var innerKey:ByteArray;
+ /**
+ * Create a MAC object (for SSL 3.0 ) and
+ * optionally a number of bits to return.
+ * The MAC will be truncated to that size if needed.
+ */
+ public function MAC(hash:IHash, bits:uint=0) {
+ this.hash = hash;
+ this.bits = bits;
+ innerHash = new ByteArray();
+ outerHash = new ByteArray();
+ innerKey = new ByteArray();
+ outerKey = new ByteArray();
+
+
+ if (hash != null) {
+ var pad_size:int = hash.getPadSize();
+ pad_1 = new ByteArray();
+ pad_2 = new ByteArray();
+
+ for (var x:int = 0; x < pad_size; x++) {
+ pad_1.writeByte(0x36);
+ pad_2.writeByte(0x5c);
+ }
+ }
+ }
+
+ public function setPadSize(pad_size:int) : void { }
+
+ public function getHashSize():uint {
+ if (bits!=0) {
+ return bits/8;
+ } else {
+ return hash.getHashSize();
+ }
+ }
+
+
+ /**
+ * Compute a MAC using a key and some data.
+ *
+ */
+ public function compute(key:ByteArray, data:ByteArray):ByteArray {
+ // take that incoming key and do hash(key + pad_2 + hash(key + pad_1 + sequence + length + record)
+ // note that data = (sequence + type + length + record)
+
+ if (pad_1 == null) {
+ var pad_size:int = hash.getPadSize();
+ pad_1 = new ByteArray();
+ pad_2 = new ByteArray();
+
+ for (var x:int = 0; x < pad_size; x++) {
+ pad_1.writeByte(0x36);
+ pad_2.writeByte(0x5c);
+ }
+ }
+
+ // Do some preliminary checking on stuff
+ /*
+ if (key.length > hash.getInputSize()) {
+ hashKey = hash.hash(key);
+ } else {
+ hashKey = new ByteArray;
+ hashKey.writeBytes(key);
+ }
+
+ while (hashKey.length < hash.getInputSize() ) {
+ hashKey[hashKey.length] = 0;
+ } */
+ // Henri's conventions work just fine here..
+
+ innerKey.length = 0;
+ outerKey.length = 0;
+ // trace("MAC Key: " + Hex.fromArray(key));
+ // trace("Key Length: " + key.length);
+ // trace("Pad_1 : " + Hex.fromArray(pad_1));
+ // inner hash calc
+ innerKey.writeBytes(key);
+ innerKey.writeBytes(pad_1);
+ innerKey.writeBytes(data);
+ // trace("MAC Inner Key: " + Hex.fromArray(innerKey));
+
+ innerHash = hash.hash(innerKey);
+ // trace("MAC Inner Hash: " + Hex.fromArray(innerHash));
+
+ // outer hash calc
+ outerKey.writeBytes(key);
+ outerKey.writeBytes(pad_2);
+ outerKey.writeBytes(innerHash);
+
+ // trace("MAC Outer Key: " + Hex.fromArray(outerKey));
+ outerHash = hash.hash(outerKey);
+
+
+ if (bits > 0 && bits < 8*outerHash.length) {
+ outerHash.length = bits/8;
+ }
+
+ // trace("MAC for record: " + Hex.fromArray(outerHash));
+ return outerHash;
+
+ }
+
+ public function dispose():void {
+ hash = null;
+ bits = 0;
+ }
+ public function toString():String {
+ return "mac-"+(bits>0?bits+"-":"")+hash.toString();
+ }
+
+ }
+}
\ No newline at end of file diff --git a/flash-src/third-party/com/hurlant/crypto/hash/MD2.as b/flash-src/third-party/com/hurlant/crypto/hash/MD2.as new file mode 100644 index 0000000..e104f0d --- /dev/null +++ b/flash-src/third-party/com/hurlant/crypto/hash/MD2.as @@ -0,0 +1,124 @@ +/**
+ * MD2
+ *
+ * An ActionScript 3 implementation of the RSA Data Security, Inc MD2 Message
+ * Digest Algorithm, as defined in RFC 1319
+ * Copyright (c) 2007 Henri Torgemane
+ *
+ * See LICENSE.txt for full license information.
+ *
+ * Excerpt from http://en.wikipedia.org/wiki/MD2:
+ * >
+ * > Rogier and Chauvaud (1997) described collisions of MD2's compression function,
+ * > although they were unable to extend the attack to the full MD2.
+ * >
+ * > In 2004, MD2 was shown to be vulnerable to a preimage attack with time
+ * > complexity equivalent to 2104 applications of the compression function
+ * > (Muller, 2004).
+ * > The author concludes, "MD2 can no longer be considered a secure one-way
+ * > hash function".
+ *
+ * also, this implementaton is quite slow.
+ */
+
+package com.hurlant.crypto.hash
+{
+ import flash.utils.ByteArray;
+
+ public class MD2 implements IHash
+ {
+ public static const HASH_SIZE:int = 16;
+ public var pad_size:int = 48; // probably will never get used, only here for SSL 3.0 support
+
+ private static const S:Array = [ // PI Digits
+ 41, 46, 67, 201, 162, 216, 124, 1, 61, 54, 84, 161, 236, 240, 6, 19,
+ 98, 167, 5, 243, 192, 199, 115, 140, 152, 147, 43, 217, 188, 76, 130, 202,
+ 30, 155, 87, 60, 253, 212, 224, 22, 103, 66, 111, 24, 138, 23, 229, 18,
+190, 78, 196, 214, 218, 158, 222, 73, 160, 251, 245, 142, 187, 47, 238, 122,
+169, 104, 121, 145, 21, 178, 7, 63, 148, 194, 16, 137, 11, 34, 95, 33,
+128, 127, 93, 154, 90, 144, 50, 39, 53, 62, 204, 231, 191, 247, 151, 3,
+255, 25, 48, 179, 72, 165, 181, 209, 215, 94, 146, 42, 172, 86, 170, 198,
+ 79, 184, 56, 210, 150, 164, 125, 182, 118, 252, 107, 226, 156, 116, 4, 241,
+ 69, 157, 112, 89, 100, 113, 135, 32, 134, 91, 207, 101, 230, 45, 168, 2,
+ 27, 96, 37, 173, 174, 176, 185, 246, 28, 70, 97, 105, 52, 64, 126, 15,
+ 85, 71, 163, 35, 221, 81, 175, 58, 195, 92, 249, 206, 186, 197, 234, 38,
+ 44, 83, 13, 110, 133, 40, 132, 9, 211, 223, 205, 244, 65, 129, 77, 82,
+106, 220, 55, 200, 108, 193, 171, 250, 36, 225, 123, 8, 12, 189, 177, 74,
+120, 136, 149, 139, 227, 99, 232, 109, 233, 203, 213, 254, 59, 0, 29, 57,
+242, 239, 183, 14, 102, 88, 208, 228, 166, 119, 114, 248, 235, 117, 75, 10,
+ 49, 68, 80, 180, 143, 237, 31, 26, 219, 153, 141, 51, 159, 17, 131, 20 ];
+
+
+ public function MD2() { }
+
+ public function getInputSize():uint
+ {
+ return 16;
+ }
+
+ public function getPadSize():int {
+ return pad_size;
+ }
+
+ public function getHashSize():uint
+ {
+ return HASH_SIZE;
+ }
+
+ public function hash(src:ByteArray):ByteArray
+ {
+ var savedLength:uint = src.length;
+
+ // 3.1 Step 1. Padding
+ var i:uint = (16-src.length%16) || 16;
+ do {
+ src[src.length]=i;
+ } while (src.length%16!=0);
+
+ // 3.2 Step 2. Checksum
+ var len:uint = src.length;
+ var checksum:ByteArray = new ByteArray;
+ var L:uint = 0;
+ for (i = 0;i<len;i+=16) {
+ for (var j:uint=0;j<16;j++) {
+ L = checksum[j] ^= S[src[i+j] ^ L];
+ }
+ }
+ src.position = src.length;
+ src.writeBytes(checksum);
+ len += 16;
+
+ // 3.3 Step 3. MD Buffer
+ var X:ByteArray = new ByteArray;
+
+ // 3.4 Process Message
+ for (i=0;i<len;i+=16) {
+
+ /* Copy block i into X */
+ for (j=0;j<16;j++) {
+ X[32+j] = (X[16+j] = src[i+j])^X[j];
+ }
+ var t:uint=0;
+ /* Do 18 rounds */
+ for (j=0;j<18;j++) {
+ /* Round j. */
+ for (var k:uint=0;k<48;k++) {
+ X[k] = t = X[k]^S[t];
+ }
+ t = (t+j)&0xff;
+ }
+ }
+ // 3.5 Step 5. Output
+ X.length = 16;
+ // restore original length;
+ src.length = savedLength;
+ return X;
+ }
+
+ public function toString():String
+ {
+ return "md2";
+ }
+
+ }
+}
diff --git a/flash-src/third-party/com/hurlant/crypto/hash/MD5.as b/flash-src/third-party/com/hurlant/crypto/hash/MD5.as new file mode 100644 index 0000000..81836ed --- /dev/null +++ b/flash-src/third-party/com/hurlant/crypto/hash/MD5.as @@ -0,0 +1,204 @@ +/**
+ * MD5
+ *
+ * An ActionScript 3 implementation of the RSA Data Security, Inc. MD5 Message
+ * Digest Algorithm, as defined in RFC 1321.
+ * Copyright (c) 2007 Henri Torgemane
+ *
+ * Derived from
+ * A JavaScript implementation of the same.
+ * Version 2.1 Copyright (C) Paul Johnston 1999 - 2002.
+ * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
+ *
+ * Note:
+ * This algorithm should not be your first choice for new developements, but is
+ * included to allow interoperability with existing codes and protocols.
+ *
+ * See LICENSE.txt for full license information.
+ */
+package com.hurlant.crypto.hash
+{
+ import flash.utils.ByteArray;
+ import flash.utils.Endian;
+
+ public class MD5 implements IHash
+ {
+ public static const HASH_SIZE:int = 16;
+ public var pad_size:int = 48;
+
+ public function MD5() { }
+
+ public function getInputSize():uint
+ {
+ return 64;
+ }
+
+ public function getHashSize():uint
+ {
+ return HASH_SIZE;
+ }
+
+ public function getPadSize():int
+ {
+ return pad_size;
+ }
+
+ public function hash(src:ByteArray):ByteArray
+ {
+ var len:uint = src.length *8;
+ var savedEndian:String = src.endian;
+ // pad to nearest int.
+ while (src.length%4!=0) {
+ src[src.length]=0;
+ }
+ // convert ByteArray to an array of uint
+ src.position=0;
+ var a:Array = [];
+ src.endian=Endian.LITTLE_ENDIAN
+ for (var i:uint=0;i<src.length;i+=4) {
+ a.push(src.readUnsignedInt());
+ }
+ var h:Array = core_md5(a, len);
+ var out:ByteArray = new ByteArray;
+ out.endian=Endian.LITTLE_ENDIAN;
+ for (i=0;i<4;i++) {
+ out.writeUnsignedInt(h[i]);
+ }
+ // restore length!
+ src.length = len/8;
+ src.endian = savedEndian;
+
+ return out;
+ }
+
+ private function core_md5(x:Array, len:uint):Array {
+ /* append padding */
+ x[len >> 5] |= 0x80 << ((len) % 32);
+ x[(((len + 64) >>> 9) << 4) + 14] = len;
+
+ var a:uint = 0x67452301; // 1732584193;
+ var b:uint = 0xEFCDAB89; //-271733879;
+ var c:uint = 0x98BADCFE; //-1732584194;
+ var d:uint = 0x10325476; // 271733878;
+
+ for(var i:uint = 0; i < x.length; i += 16)
+ {
+ x[i]||=0; x[i+1]||=0; x[i+2]||=0; x[i+3]||=0;
+ x[i+4]||=0; x[i+5]||=0; x[i+6]||=0; x[i+7]||=0;
+ x[i+8]||=0; x[i+9]||=0; x[i+10]||=0; x[i+11]||=0;
+ x[i+12]||=0; x[i+13]||=0; x[i+14]||=0; x[i+15]||=0;
+
+ var olda:uint = a;
+ var oldb:uint = b;
+ var oldc:uint = c;
+ var oldd:uint = d;
+
+ a = ff(a, b, c, d, x[i+ 0], 7 , 0xD76AA478);
+ d = ff(d, a, b, c, x[i+ 1], 12, 0xE8C7B756);
+ c = ff(c, d, a, b, x[i+ 2], 17, 0x242070DB);
+ b = ff(b, c, d, a, x[i+ 3], 22, 0xC1BDCEEE);
+ a = ff(a, b, c, d, x[i+ 4], 7 , 0xF57C0FAF);
+ d = ff(d, a, b, c, x[i+ 5], 12, 0x4787C62A);
+ c = ff(c, d, a, b, x[i+ 6], 17, 0xA8304613);
+ b = ff(b, c, d, a, x[i+ 7], 22, 0xFD469501);
+ a = ff(a, b, c, d, x[i+ 8], 7 , 0x698098D8);
+ d = ff(d, a, b, c, x[i+ 9], 12, 0x8B44F7AF);
+ c = ff(c, d, a, b, x[i+10], 17, 0xFFFF5BB1);
+ b = ff(b, c, d, a, x[i+11], 22, 0x895CD7BE);
+ a = ff(a, b, c, d, x[i+12], 7 , 0x6B901122);
+ d = ff(d, a, b, c, x[i+13], 12, 0xFD987193);
+ c = ff(c, d, a, b, x[i+14], 17, 0xA679438E);
+ b = ff(b, c, d, a, x[i+15], 22, 0x49B40821);
+
+ a = gg(a, b, c, d, x[i+ 1], 5 , 0xf61e2562);
+ d = gg(d, a, b, c, x[i+ 6], 9 , 0xc040b340);
+ c = gg(c, d, a, b, x[i+11], 14, 0x265e5a51);
+ b = gg(b, c, d, a, x[i+ 0], 20, 0xe9b6c7aa);
+ a = gg(a, b, c, d, x[i+ 5], 5 , 0xd62f105d);
+ d = gg(d, a, b, c, x[i+10], 9 , 0x2441453);
+ c = gg(c, d, a, b, x[i+15], 14, 0xd8a1e681);
+ b = gg(b, c, d, a, x[i+ 4], 20, 0xe7d3fbc8);
+ a = gg(a, b, c, d, x[i+ 9], 5 , 0x21e1cde6);
+ d = gg(d, a, b, c, x[i+14], 9 , 0xc33707d6);
+ c = gg(c, d, a, b, x[i+ 3], 14, 0xf4d50d87);
+ b = gg(b, c, d, a, x[i+ 8], 20, 0x455a14ed);
+ a = gg(a, b, c, d, x[i+13], 5 , 0xa9e3e905);
+ d = gg(d, a, b, c, x[i+ 2], 9 , 0xfcefa3f8);
+ c = gg(c, d, a, b, x[i+ 7], 14, 0x676f02d9);
+ b = gg(b, c, d, a, x[i+12], 20, 0x8d2a4c8a);
+
+ a = hh(a, b, c, d, x[i+ 5], 4 , 0xfffa3942);
+ d = hh(d, a, b, c, x[i+ 8], 11, 0x8771f681);
+ c = hh(c, d, a, b, x[i+11], 16, 0x6d9d6122);
+ b = hh(b, c, d, a, x[i+14], 23, 0xfde5380c);
+ a = hh(a, b, c, d, x[i+ 1], 4 , 0xa4beea44);
+ d = hh(d, a, b, c, x[i+ 4], 11, 0x4bdecfa9);
+ c = hh(c, d, a, b, x[i+ 7], 16, 0xf6bb4b60);
+ b = hh(b, c, d, a, x[i+10], 23, 0xbebfbc70);
+ a = hh(a, b, c, d, x[i+13], 4 , 0x289b7ec6);
+ d = hh(d, a, b, c, x[i+ 0], 11, 0xeaa127fa);
+ c = hh(c, d, a, b, x[i+ 3], 16, 0xd4ef3085);
+ b = hh(b, c, d, a, x[i+ 6], 23, 0x4881d05);
+ a = hh(a, b, c, d, x[i+ 9], 4 , 0xd9d4d039);
+ d = hh(d, a, b, c, x[i+12], 11, 0xe6db99e5);
+ c = hh(c, d, a, b, x[i+15], 16, 0x1fa27cf8);
+ b = hh(b, c, d, a, x[i+ 2], 23, 0xc4ac5665);
+
+ a = ii(a, b, c, d, x[i+ 0], 6 , 0xf4292244);
+ d = ii(d, a, b, c, x[i+ 7], 10, 0x432aff97);
+ c = ii(c, d, a, b, x[i+14], 15, 0xab9423a7);
+ b = ii(b, c, d, a, x[i+ 5], 21, 0xfc93a039);
+ a = ii(a, b, c, d, x[i+12], 6 , 0x655b59c3);
+ d = ii(d, a, b, c, x[i+ 3], 10, 0x8f0ccc92);
+ c = ii(c, d, a, b, x[i+10], 15, 0xffeff47d);
+ b = ii(b, c, d, a, x[i+ 1], 21, 0x85845dd1);
+ a = ii(a, b, c, d, x[i+ 8], 6 , 0x6fa87e4f);
+ d = ii(d, a, b, c, x[i+15], 10, 0xfe2ce6e0);
+ c = ii(c, d, a, b, x[i+ 6], 15, 0xa3014314);
+ b = ii(b, c, d, a, x[i+13], 21, 0x4e0811a1);
+ a = ii(a, b, c, d, x[i+ 4], 6 , 0xf7537e82);
+ d = ii(d, a, b, c, x[i+11], 10, 0xbd3af235);
+ c = ii(c, d, a, b, x[i+ 2], 15, 0x2ad7d2bb);
+ b = ii(b, c, d, a, x[i+ 9], 21, 0xeb86d391);
+
+ a += olda;
+ b += oldb;
+ c += oldc;
+ d += oldd;
+
+ }
+ return [ a, b, c, d ];
+ }
+
+ /*
+ * Bitwise rotate a 32-bit number to the left.
+ */
+ private function rol(num:uint, cnt:uint):uint
+ {
+ return (num << cnt) | (num >>> (32 - cnt));
+ }
+
+ /*
+ * These functions implement the four basic operations the algorithm uses.
+ */
+ private function cmn(q:uint, a:uint, b:uint, x:uint, s:uint, t:uint):uint {
+ return rol(a + q + x + t, s) + b;
+ }
+ private function ff(a:uint, b:uint, c:uint, d:uint, x:uint, s:uint, t:uint):uint {
+ return cmn((b & c) | ((~b) & d), a, b, x, s, t);
+ }
+ private function gg(a:uint, b:uint, c:uint, d:uint, x:uint, s:uint, t:uint):uint {
+ return cmn((b & d) | (c & (~d)), a, b, x, s, t);
+ }
+ private function hh(a:uint, b:uint, c:uint, d:uint, x:uint, s:uint, t:uint):uint {
+ return cmn(b ^ c ^ d, a, b, x, s, t);
+ }
+ private function ii(a:uint, b:uint, c:uint, d:uint, x:uint, s:uint, t:uint):uint {
+ return cmn(c ^ (b | (~d)), a, b, x, s, t);
+ }
+
+ public function toString():String {
+ return "md5";
+ }
+ }
+}
diff --git a/flash-src/third-party/com/hurlant/crypto/hash/SHA1.as b/flash-src/third-party/com/hurlant/crypto/hash/SHA1.as new file mode 100644 index 0000000..5b186f3 --- /dev/null +++ b/flash-src/third-party/com/hurlant/crypto/hash/SHA1.as @@ -0,0 +1,106 @@ +/**
+ * SHA1
+ *
+ * An ActionScript 3 implementation of Secure Hash Algorithm, SHA-1, as defined
+ * in FIPS PUB 180-1
+ * Copyright (c) 2007 Henri Torgemane
+ *
+ * Derived from:
+ * A JavaScript implementation of the Secure Hash Algorithm, SHA-1, as defined
+ * in FIPS PUB 180-1
+ * Version 2.1a Copyright Paul Johnston 2000 - 2002.
+ * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
+ *
+ * See LICENSE.txt for full license information.
+ */
+package com.hurlant.crypto.hash
+{
+
+
+ public class SHA1 extends SHABase implements IHash
+ {
+ public static const HASH_SIZE:int = 20;
+
+ public override function getHashSize():uint {
+ return HASH_SIZE;
+ }
+
+ protected override function core(x:Array, len:uint):Array
+ {
+ /* append padding */
+ x[len >> 5] |= 0x80 << (24 - len % 32);
+ x[((len + 64 >> 9) << 4) + 15] = len;
+
+ var w:Array = [];
+ var a:uint = 0x67452301; //1732584193;
+ var b:uint = 0xEFCDAB89; //-271733879;
+ var c:uint = 0x98BADCFE; //-1732584194;
+ var d:uint = 0x10325476; //271733878;
+ var e:uint = 0xC3D2E1F0; //-1009589776;
+
+ for(var i:uint = 0; i < x.length; i += 16)
+ {
+
+ var olda:uint = a;
+ var oldb:uint = b;
+ var oldc:uint = c;
+ var oldd:uint = d;
+ var olde:uint = e;
+
+ for(var j:uint = 0; j < 80; j++)
+ {
+ if (j < 16) {
+ w[j] = x[i + j] || 0;
+ } else {
+ w[j] = rol(w[j-3] ^ w[j-8] ^ w[j-14] ^ w[j-16], 1);
+ }
+ var t:uint = rol(a,5) + ft(j,b,c,d) + e + w[j] + kt(j);
+ e = d;
+ d = c;
+ c = rol(b, 30);
+ b = a;
+ a = t;
+ }
+ a += olda;
+ b += oldb;
+ c += oldc;
+ d += oldd;
+ e += olde;
+ }
+ return [ a, b, c, d, e ];
+
+ }
+
+ /*
+ * Bitwise rotate a 32-bit number to the left.
+ */
+ private function rol(num:uint, cnt:uint):uint
+ {
+ return (num << cnt) | (num >>> (32 - cnt));
+ }
+
+ /*
+ * Perform the appropriate triplet combination function for the current
+ * iteration
+ */
+ private function ft(t:uint, b:uint, c:uint, d:uint):uint
+ {
+ if(t < 20) return (b & c) | ((~b) & d);
+ if(t < 40) return b ^ c ^ d;
+ if(t < 60) return (b & c) | (b & d) | (c & d);
+ return b ^ c ^ d;
+ }
+
+ /*
+ * Determine the appropriate additive constant for the current iteration
+ */
+ private function kt(t:uint):uint
+ {
+ return (t < 20) ? 0x5A827999 : (t < 40) ? 0x6ED9EBA1 :
+ (t < 60) ? 0x8F1BBCDC : 0xCA62C1D6;
+ }
+ public override function toString():String {
+ return "sha1";
+ }
+ }
+}
diff --git a/flash-src/third-party/com/hurlant/crypto/hash/SHA224.as b/flash-src/third-party/com/hurlant/crypto/hash/SHA224.as new file mode 100644 index 0000000..345aa3d --- /dev/null +++ b/flash-src/third-party/com/hurlant/crypto/hash/SHA224.as @@ -0,0 +1,28 @@ +/**
+ * SHA224
+ *
+ * An ActionScript 3 implementation of Secure Hash Algorithm, SHA-224, as defined
+ * in FIPS PUB 180-2
+ * Copyright (c) 2007 Henri Torgemane
+ *
+ * See LICENSE.txt for full license information.
+ */
+package com.hurlant.crypto.hash
+{
+ public class SHA224 extends SHA256
+ {
+ function SHA224() {
+ h = [
+ 0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939,
+ 0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4
+ ];
+ }
+
+ public override function getHashSize():uint {
+ return 28;
+ }
+ public override function toString():String {
+ return "sha224";
+ }
+ }
+}
\ No newline at end of file diff --git a/flash-src/third-party/com/hurlant/crypto/hash/SHA256.as b/flash-src/third-party/com/hurlant/crypto/hash/SHA256.as new file mode 100644 index 0000000..67bdbb4 --- /dev/null +++ b/flash-src/third-party/com/hurlant/crypto/hash/SHA256.as @@ -0,0 +1,115 @@ +/**
+ * SHA256
+ *
+ * An ActionScript 3 implementation of Secure Hash Algorithm, SHA-256, as defined
+ * in FIPS PUB 180-2
+ * Copyright (c) 2007 Henri Torgemane
+ *
+ * Derived from:
+ * A JavaScript implementation of the Secure Hash Standard
+ * Version 0.3 Copyright Angel Marin 2003-2004 - http://anmar.eu.org/
+ * Derived from:
+ * A JavaScript implementation of the Secure Hash Algorithm, SHA-1, as defined
+ * in FIPS PUB 180-1
+ * Version 2.1a Copyright Paul Johnston 2000 - 2002.
+ * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
+ *
+ * See LICENSE.txt for full license information.
+ */
+package com.hurlant.crypto.hash
+{
+
+
+ public class SHA256 extends SHABase implements IHash
+ {
+
+ protected static const k:Array = [
+ 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
+ 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
+ 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
+ 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
+ 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
+ 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
+ 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
+ 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2];
+ protected var h:Array = [
+ 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
+ ];
+
+ public function SHA256(){
+ }
+
+ public override function getHashSize():uint
+ {
+ return 32;
+ }
+
+ protected override function core(x:Array, len:uint):Array {
+ /* append padding */
+ x[len >> 5] |= 0x80 << (24 - len % 32);
+ x[((len + 64 >> 9) << 4) + 15] = len;
+
+ var w:Array = [];
+ var a:uint = h[0];
+ var b:uint = h[1];
+ var c:uint = h[2];
+ var d:uint = h[3];
+ var e:uint = h[4];
+ var f:uint = h[5];
+ var g:uint = h[6];
+ var h:uint = h[7];
+
+ for (var i:uint=0; i<x.length; i+=16) {
+ var olda:uint = a;
+ var oldb:uint = b;
+ var oldc:uint = c;
+ var oldd:uint = d;
+ var olde:uint = e;
+ var oldf:uint = f;
+ var oldg:uint = g;
+ var oldh:uint = h;
+
+ for (var j:uint=0; j<64; j++) {
+ if (j<16) {
+ w[j] = x[i+j] || 0;
+ } else {
+ var s0:uint = rrol(w[j-15],7)^rrol(w[j-15],18)^(w[j-15]>>>3);
+ var s1:uint = rrol(w[j-2], 17)^rrol(w[j-2],19)^(w[j-2]>>>10);
+ w[j] = w[j-16] + s0 + w[j-7] + s1;
+ }
+ var t2:uint = (rrol(a,2) ^ rrol(a,13) ^ rrol(a,22)) + ((a&b) ^ (a&c) ^ (b&c));
+ var t1:uint = h + (rrol(e,6) ^ rrol(e,11) ^ rrol(e,25)) + ((e&f)^(g&~e)) + k[j] + w[j]
+ h = g;
+ g = f;
+ f = e;
+ e = d + t1;
+ d = c;
+ c = b;
+ b = a;
+ a = t1 + t2;
+
+ }
+ a += olda;
+ b += oldb;
+ c += oldc;
+ d += oldd;
+ e += olde;
+ f += oldf;
+ g += oldg;
+ h += oldh;
+ }
+ return [ a,b,c,d,e,f,g,h ];
+ }
+
+ /*
+ * Bitwise rotate a 32-bit number to the right.
+ */
+ protected function rrol(num:uint, cnt:uint):uint {
+ return (num << (32-cnt)) | (num >>> cnt);
+ }
+
+ public override function toString():String {
+ return "sha256";
+ }
+ }
+}
\ No newline at end of file diff --git a/flash-src/third-party/com/hurlant/crypto/hash/SHABase.as b/flash-src/third-party/com/hurlant/crypto/hash/SHABase.as new file mode 100644 index 0000000..dc9bafe --- /dev/null +++ b/flash-src/third-party/com/hurlant/crypto/hash/SHABase.as @@ -0,0 +1,71 @@ +/**
+ * SHABase
+ *
+ * An ActionScript 3 abstract class for the SHA family of hash functions
+ * Copyright (c) 2007 Henri Torgemane
+ *
+ * See LICENSE.txt for full license information.
+ */
+package com.hurlant.crypto.hash
+{
+ import flash.utils.ByteArray;
+ import flash.utils.Endian;
+
+ public class SHABase implements IHash
+ {
+
+ public function SHABase() { }
+
+ public var pad_size:int = 40;
+ public function getInputSize():uint
+ {
+ return 64;
+ }
+
+ public function getHashSize():uint
+ {
+ return 0;
+ }
+
+ public function getPadSize():int
+ {
+ return pad_size;
+ }
+
+ public function hash(src:ByteArray):ByteArray
+ {
+ var savedLength:uint = src.length;
+ var savedEndian:String = src.endian;
+
+ src.endian = Endian.BIG_ENDIAN;
+ var len:uint = savedLength *8;
+ // pad to nearest int.
+ while (src.length%4!=0) {
+ src[src.length]=0;
+ }
+ // convert ByteArray to an array of uint
+ src.position=0;
+ var a:Array = [];
+ for (var i:uint=0;i<src.length;i+=4) {
+ a.push(src.readUnsignedInt());
+ }
+ var h:Array = core(a, len);
+ var out:ByteArray = new ByteArray;
+ var words:uint = getHashSize()/4;
+ for (i=0;i<words;i++) {
+ out.writeUnsignedInt(h[i]);
+ }
+ // unpad, to leave the source untouched.
+ src.length = savedLength;
+ src.endian = savedEndian;
+ return out;
+ }
+ protected function core(x:Array, len:uint):Array {
+ return null;
+ }
+
+ public function toString():String {
+ return "sha";
+ }
+ }
+}
diff --git a/flash-src/third-party/com/hurlant/crypto/prng/ARC4.as b/flash-src/third-party/com/hurlant/crypto/prng/ARC4.as new file mode 100644 index 0000000..f09a638 --- /dev/null +++ b/flash-src/third-party/com/hurlant/crypto/prng/ARC4.as @@ -0,0 +1,90 @@ +/**
+ * ARC4
+ *
+ * An ActionScript 3 implementation of RC4
+ * Copyright (c) 2007 Henri Torgemane
+ *
+ * Derived from:
+ * The jsbn library, Copyright (c) 2003-2005 Tom Wu
+ *
+ * See LICENSE.txt for full license information.
+ */
+package com.hurlant.crypto.prng
+{
+ import com.hurlant.crypto.symmetric.IStreamCipher;
+ import com.hurlant.util.Memory;
+
+ import flash.utils.ByteArray;
+
+ public class ARC4 implements IPRNG, IStreamCipher {
+ private var i:int = 0;
+ private var j:int = 0;
+ private var S:ByteArray;
+ private const psize:uint = 256;
+ public function ARC4(key:ByteArray = null){
+ S = new ByteArray;
+ if (key) {
+ init(key);
+ }
+ }
+ public function getPoolSize():uint {
+ return psize;
+ }
+ public function init(key:ByteArray):void {
+ var i:int;
+ var j:int;
+ var t:int;
+ for (i=0; i<256; ++i) {
+ S[i] = i;
+ }
+ j=0;
+ for (i=0; i<256; ++i) {
+ j = (j + S[i] + key[i%key.length]) & 255;
+ t = S[i];
+ S[i] = S[j];
+ S[j] = t;
+ }
+ this.i=0;
+ this.j=0;
+ }
+ public function next():uint {
+ var t:int;
+ i = (i+1)&255;
+ j = (j+S[i])&255;
+ t = S[i];
+ S[i] = S[j];
+ S[j] = t;
+ return S[(t+S[i])&255];
+ }
+
+ public function getBlockSize():uint {
+ return 1;
+ }
+
+ public function encrypt(block:ByteArray):void {
+ var i:uint = 0;
+ while (i<block.length) {
+ block[i++] ^= next();
+ }
+ }
+ public function decrypt(block:ByteArray):void {
+ encrypt(block); // the beauty of XOR.
+ }
+ public function dispose():void {
+ var i:uint = 0;
+ if (S!=null) {
+ for (i=0;i<S.length;i++) {
+ S[i] = Math.random()*256;
+ }
+ S.length=0;
+ S = null;
+ }
+ this.i = 0;
+ this.j = 0;
+ Memory.gc();
+ }
+ public function toString():String {
+ return "rc4";
+ }
+ }
+}
\ No newline at end of file diff --git a/flash-src/third-party/com/hurlant/crypto/prng/IPRNG.as b/flash-src/third-party/com/hurlant/crypto/prng/IPRNG.as new file mode 100644 index 0000000..2c61e93 --- /dev/null +++ b/flash-src/third-party/com/hurlant/crypto/prng/IPRNG.as @@ -0,0 +1,20 @@ +/**
+ * IPRNG
+ *
+ * An interface for classes that can be used a pseudo-random number generators
+ * Copyright (c) 2007 Henri Torgemane
+ *
+ * See LICENSE.txt for full license information.
+ */
+package com.hurlant.crypto.prng
+{
+ import flash.utils.ByteArray;
+
+ public interface IPRNG {
+ function getPoolSize():uint;
+ function init(key:ByteArray):void;
+ function next():uint;
+ function dispose():void;
+ function toString():String;
+ }
+}
\ No newline at end of file diff --git a/flash-src/third-party/com/hurlant/crypto/prng/Random.as b/flash-src/third-party/com/hurlant/crypto/prng/Random.as new file mode 100644 index 0000000..f6f5184 --- /dev/null +++ b/flash-src/third-party/com/hurlant/crypto/prng/Random.as @@ -0,0 +1,119 @@ +/**
+ * Random
+ *
+ * An ActionScript 3 implementation of a Random Number Generator
+ * Copyright (c) 2007 Henri Torgemane
+ *
+ * Derived from:
+ * The jsbn library, Copyright (c) 2003-2005 Tom Wu
+ *
+ * See LICENSE.txt for full license information.
+ */
+package com.hurlant.crypto.prng
+{
+ import flash.utils.ByteArray;
+ import com.hurlant.util.Memory;
+ import flash.system.System;
+ import flash.system.Capabilities;
+ import flash.accessibility.AccessibilityProperties;
+ import flash.display.SWFVersion;
+ import flash.display.Stage;
+ import flash.utils.getTimer;
+ import flash.text.Font;
+
+ public class Random
+ {
+ private var state:IPRNG;
+ private var ready:Boolean = false;
+ private var pool:ByteArray;
+ private var psize:int;
+ private var pptr:int;
+ private var seeded:Boolean = false;
+
+ public function Random(prng:Class = null) {
+ if (prng==null) prng = ARC4;
+ state = new prng as IPRNG;
+ psize= state.getPoolSize();
+ pool = new ByteArray;
+ pptr = 0;
+ while (pptr <psize) {
+ var t:uint = 65536*Math.random();
+ pool[pptr++] = t >>> 8;
+ pool[pptr++] = t&255;
+ }
+ pptr=0;
+ seed();
+ }
+
+ public function seed(x:int = 0):void {
+ if (x==0) {
+ x = new Date().getTime();
+ }
+ pool[pptr++] ^= x & 255;
+ pool[pptr++] ^= (x>>8)&255;
+ pool[pptr++] ^= (x>>16)&255;
+ pool[pptr++] ^= (x>>24)&255;
+ pptr %= psize;
+ seeded = true;
+ }
+
+ /**
+ * Gather anything we have that isn't entirely predictable:
+ * - memory used
+ * - system capabilities
+ * - timing stuff
+ * - installed fonts
+ */
+ public function autoSeed():void {
+ var b:ByteArray = new ByteArray;
+ b.writeUnsignedInt(System.totalMemory);
+ b.writeUTF(Capabilities.serverString);
+ b.writeUnsignedInt(getTimer());
+ b.writeUnsignedInt((new Date).getTime());
+ var a:Array = Font.enumerateFonts(true);
+ for each (var f:Font in a) {
+ b.writeUTF(f.fontName);
+ b.writeUTF(f.fontStyle);
+ b.writeUTF(f.fontType);
+ }
+ b.position=0;
+ while (b.bytesAvailable>=4) {
+ seed(b.readUnsignedInt());
+ }
+ }
+
+
+ public function nextBytes(buffer:ByteArray, length:int):void {
+ while (length--) {
+ buffer.writeByte(nextByte());
+ }
+ }
+ public function nextByte():int {
+ if (!ready) {
+ if (!seeded) {
+ autoSeed();
+ }
+ state.init(pool);
+ pool.length = 0;
+ pptr = 0;
+ ready = true;
+ }
+ return state.next();
+ }
+ public function dispose():void {
+ for (var i:uint=0;i<pool.length;i++) {
+ pool[i] = Math.random()*256;
+ }
+ pool.length=0;
+ pool = null;
+ state.dispose();
+ state = null;
+ psize = 0;
+ pptr = 0;
+ Memory.gc();
+ }
+ public function toString():String {
+ return "random-"+state.toString();
+ }
+ }
+}
diff --git a/flash-src/third-party/com/hurlant/crypto/prng/TLSPRF.as b/flash-src/third-party/com/hurlant/crypto/prng/TLSPRF.as new file mode 100644 index 0000000..97553d4 --- /dev/null +++ b/flash-src/third-party/com/hurlant/crypto/prng/TLSPRF.as @@ -0,0 +1,142 @@ +/**
+ * TLSPRF
+ *
+ * An ActionScript 3 implementation of a pseudo-random generator
+ * that follows the TLS specification
+ * Copyright (c) 2007 Henri Torgemane
+ *
+ * See LICENSE.txt for full license information.
+ */
+package com.hurlant.crypto.prng
+{
+ import flash.utils.ByteArray;
+ import com.hurlant.crypto.hash.HMAC;
+ import com.hurlant.crypto.hash.MD5;
+ import com.hurlant.crypto.hash.SHA1;
+ import com.hurlant.util.Memory;
+ import com.hurlant.util.Hex;
+ import flash.utils.IDataOutput;
+
+ /**
+ * There's "Random", and then there's TLS Random.
+ * .
+ * Still Pseudo-random, though.
+ */
+ public class TLSPRF
+ {
+ // XXX WAY TOO MANY STRUCTURES HERE
+
+ // seed
+ private var seed:ByteArray;
+ // P_MD5's secret
+ private var s1:ByteArray;
+ // P_SHA-1's secret
+ private var s2:ByteArray;
+ // HMAC_MD5's A
+ private var a1:ByteArray;
+ // HMAC_SHA1's A
+ private var a2:ByteArray;
+ // Pool for P_MD5
+ private var p1:ByteArray;
+ // Pool for P_SHA1
+ private var p2:ByteArray;
+ // Data for HMAC_MD5
+ private var d1:ByteArray;
+ // Data for HMAC_SHA1
+ private var d2:ByteArray;
+
+
+ private var hmac_md5:HMAC;
+ private var hmac_sha1:HMAC;
+
+ public function TLSPRF(secret:ByteArray, label:String, seed:ByteArray) {
+ var l:int = Math.ceil(secret.length/2);
+ var s1:ByteArray = new ByteArray;
+ var s2:ByteArray = new ByteArray;
+ s1.writeBytes(secret, 0, l);
+ s2.writeBytes(secret, secret.length-l, l);
+ var s:ByteArray = new ByteArray;
+ s.writeUTFBytes(label);
+ s.writeBytes(seed);
+ this.seed = s;
+ this.s1 = s1;
+ this.s2 = s2;
+ hmac_md5 = new HMAC(new MD5);
+ hmac_sha1 = new HMAC(new SHA1);
+
+ this.a1 = hmac_md5.compute(s1, this.seed);
+ this.a2 = hmac_sha1.compute(s2, this.seed);
+
+ p1 = new ByteArray;
+ p2 = new ByteArray;
+
+ d1 = new ByteArray;
+ d2 = new ByteArray;
+ d1.position = MD5.HASH_SIZE;
+ d1.writeBytes(this.seed);
+ d2.position = SHA1.HASH_SIZE;
+ d2.writeBytes(this.seed);
+ }
+
+ // XXX HORRIBLY SLOW. REWRITE.
+ public function nextBytes(buffer:IDataOutput, length:int):void {
+ while (length--) {
+ buffer.writeByte(nextByte());
+ }
+ }
+ public function nextByte():int {
+ if (p1.bytesAvailable==0) {
+ more_md5();
+ }
+ if (p2.bytesAvailable==0) {
+ more_sha1();
+ }
+ return p1.readUnsignedByte()^p2.readUnsignedByte();
+ }
+ public function dispose():void {
+ seed = dba(seed);
+ s1 = dba(s1);
+ s2 = dba(s2);
+ a1 = dba(a1);
+ a2 = dba(a2);
+ p1 = dba(p1);
+ p2 = dba(p2);
+ d1 = dba(d1);
+ d2 = dba(d2);
+ hmac_md5.dispose();
+ hmac_md5 = null;
+ hmac_sha1.dispose();
+ hmac_sha1 = null;
+ Memory.gc();
+ }
+ public function toString():String {
+ return "tls-prf";
+ }
+ private function dba(ba:ByteArray):ByteArray {
+ for (var i:uint=0;i<ba.length;i++) {
+ ba[i]=0;
+ }
+ ba.length=0;
+ return null;
+ }
+ private function more_md5():void {
+ d1.position=0;
+ d1.writeBytes(a1);
+ var p:int = p1.position;
+ var more:ByteArray = hmac_md5.compute(s1, d1);
+ a1 = hmac_md5.compute(s1, a1);
+ p1.writeBytes(more);
+ p1.position=p;
+ }
+ private function more_sha1():void {
+ d2.position=0;
+ d2.writeBytes(a2);
+ var p:int = p2.position;
+ var more:ByteArray = hmac_sha1.compute(s2, d2);
+ a2 = hmac_sha1.compute(s2, a2);
+ p2.writeBytes(more);
+ p2.position=p;
+ }
+
+ }
+}
\ No newline at end of file diff --git a/flash-src/third-party/com/hurlant/crypto/rsa/RSAKey.as b/flash-src/third-party/com/hurlant/crypto/rsa/RSAKey.as new file mode 100644 index 0000000..02fd83d --- /dev/null +++ b/flash-src/third-party/com/hurlant/crypto/rsa/RSAKey.as @@ -0,0 +1,339 @@ +/**
+ * RSAKey
+ *
+ * An ActionScript 3 implementation of RSA + PKCS#1 (light version)
+ * Copyright (c) 2007 Henri Torgemane
+ *
+ * Derived from:
+ * The jsbn library, Copyright (c) 2003-2005 Tom Wu
+ *
+ * See LICENSE.txt for full license information.
+ */
+package com.hurlant.crypto.rsa
+{
+ import com.hurlant.crypto.prng.Random;
+ import com.hurlant.math.BigInteger;
+ import com.hurlant.util.Memory;
+
+ import flash.utils.ByteArray;
+ import com.hurlant.crypto.hash.IHash;
+ import com.hurlant.util.Hex;
+ import com.hurlant.util.der.DER;
+ import com.hurlant.util.der.OID;
+ import com.hurlant.util.ArrayUtil;
+ import com.hurlant.util.der.Type;
+ import com.hurlant.util.der.Sequence;
+ import com.hurlant.util.der.ObjectIdentifier;
+ import com.hurlant.util.der.ByteString; + import com.hurlant.crypto.tls.TLSError;
+
+ /**
+ * Current limitations:
+ * exponent must be smaller than 2^31.
+ */
+ public class RSAKey
+ {
+ // public key
+ public var e:int; // public exponent. must be <2^31
+ public var n:BigInteger; // modulus
+ // private key
+ public var d:BigInteger;
+ // extended private key
+ public var p:BigInteger;
+ public var q:BigInteger;
+ public var dmp1:BigInteger
+ public var dmq1:BigInteger;
+ public var coeff:BigInteger;
+ // flags. flags are cool.
+ protected var canDecrypt:Boolean;
+ protected var canEncrypt:Boolean;
+
+ public function RSAKey(N:BigInteger, E:int,
+ D:BigInteger=null,
+ P:BigInteger = null, Q:BigInteger=null,
+ DP:BigInteger=null, DQ:BigInteger=null,
+ C:BigInteger=null) {
+
+ this.n = N;
+ this.e = E;
+ this.d = D;
+ this.p = P;
+ this.q = Q;
+ this.dmp1 = DP;
+ this.dmq1 = DQ;
+ this.coeff = C;
+
+ // adjust a few flags.
+ canEncrypt = (n!=null&&e!=0);
+ canDecrypt = (canEncrypt&&d!=null);
+
+
+ }
+
+ public static function parsePublicKey(N:String, E:String):RSAKey {
+ return new RSAKey(new BigInteger(N, 16, true), parseInt(E,16));
+ }
+ public static function parsePrivateKey(N:String, E:String, D:String,
+ P:String=null,Q:String=null, DMP1:String=null, DMQ1:String=null, IQMP:String=null):RSAKey {
+ if (P==null) {
+ return new RSAKey(new BigInteger(N,16, true), parseInt(E,16), new BigInteger(D,16, true));
+ } else {
+ return new RSAKey(new BigInteger(N,16, true), parseInt(E,16), new BigInteger(D,16, true),
+ new BigInteger(P,16, true), new BigInteger(Q,16, true),
+ new BigInteger(DMP1,16, true), new BigInteger(DMQ1, 16, true),
+ new BigInteger(IQMP, 16, true));
+ }
+ }
+
+ public function getBlockSize():uint {
+ return (n.bitLength()+7)/8;
+ }
+ public function dispose():void {
+ e = 0;
+ n.dispose();
+ n = null;
+ Memory.gc();
+ }
+
+ public function encrypt(src:ByteArray, dst:ByteArray, length:uint, pad:Function=null):void {
+ _encrypt(doPublic, src, dst, length, pad, 0x02);
+ }
+ public function decrypt(src:ByteArray, dst:ByteArray, length:uint, pad:Function=null):void {
+ _decrypt(doPrivate2, src, dst, length, pad, 0x02);
+ }
+
+ public function sign(src:ByteArray, dst:ByteArray, length:uint, pad:Function = null):void {
+ _encrypt(doPrivate2, src, dst, length, pad, 0x01);
+ }
+ public function verify(src:ByteArray, dst:ByteArray, length:uint, pad:Function = null):void {
+ _decrypt(doPublic, src, dst, length, pad, 0x01);
+ }
+
+
+ private function _encrypt(op:Function, src:ByteArray, dst:ByteArray, length:uint, pad:Function, padType:int):void {
+ // adjust pad if needed
+ if (pad==null) pad = pkcs1pad;
+ // convert src to BigInteger
+ if (src.position >= src.length) {
+ src.position = 0;
+ }
+ var bl:uint = getBlockSize();
+ var end:int = src.position + length;
+ while (src.position<end) {
+ var block:BigInteger = new BigInteger(pad(src, end, bl, padType), bl, true);
+ var chunk:BigInteger = op(block);
+ chunk.toArray(dst);
+ }
+ }
+ private function _decrypt(op:Function, src:ByteArray, dst:ByteArray, length:uint, pad:Function, padType:int):void {
+ // adjust pad if needed
+ if (pad==null) pad = pkcs1unpad;
+
+ // convert src to BigInteger
+ if (src.position >= src.length) {
+ src.position = 0;
+ }
+ var bl:uint = getBlockSize();
+ var end:int = src.position + length;
+ while (src.position<end) {
+ var block:BigInteger = new BigInteger(src, bl, true);
+ var chunk:BigInteger = op(block);
+ var b:ByteArray = pad(chunk, bl, padType);
+ if (b == null)
+ throw new TLSError( "Decrypt error - padding function returned null!", TLSError.decode_error );
+ // if (b != null)
+ dst.writeBytes(b);
+ }
+ }
+
+ /**
+ * PKCS#1 pad. type 1 (0xff) or 2, random.
+ * puts as much data from src into it, leaves what doesn't fit alone.
+ */
+ private function pkcs1pad(src:ByteArray, end:int, n:uint, type:uint = 0x02):ByteArray {
+ var out:ByteArray = new ByteArray;
+ var p:uint = src.position;
+ end = Math.min(end, src.length, p+n-11);
+ src.position = end;
+ var i:int = end-1;
+ while (i>=p && n>11) {
+ out[--n] = src[i--];
+ }
+ out[--n] = 0;
+ if (type==0x02) { // type 2
+ var rng:Random = new Random;
+ var x:int = 0;
+ while (n>2) {
+ do {
+ x = rng.nextByte();
+ } while (x==0);
+ out[--n] = x;
+ }
+ } else { // type 1
+ while (n>2) {
+ out[--n] = 0xFF;
+ }
+ }
+ out[--n] = type;
+ out[--n] = 0;
+ return out;
+ }
+
+ /**
+ *
+ * @param src
+ * @param n
+ * @param type Not used.
+ * @return
+ *
+ */
+ private function pkcs1unpad(src:BigInteger, n:uint, type:uint = 0x02):ByteArray {
+ var b:ByteArray = src.toByteArray();
+ var out:ByteArray = new ByteArray;
+
+ b.position = 0;
+ var i:int = 0;
+ while (i<b.length && b[i]==0) ++i;
+ if (b.length-i != n-1 || b[i]!=type) {
+ trace("PKCS#1 unpad: i="+i+", expected b[i]=="+type+", got b[i]="+b[i].toString(16));
+ return null;
+ }
+ ++i;
+ while (b[i]!=0) {
+ if (++i>=b.length) {
+ trace("PKCS#1 unpad: i="+i+", b[i-1]!=0 (="+b[i-1].toString(16)+")");
+ return null;
+ }
+ }
+ while (++i < b.length) {
+ out.writeByte(b[i]);
+ }
+ out.position = 0;
+ return out;
+ }
+ /**
+ * Raw pad.
+ */
+ public function rawpad(src:ByteArray, end:int, n:uint, type:uint = 0):ByteArray {
+ return src;
+ }
+ public function rawunpad(src:BigInteger, n:uint, type:uint = 0):ByteArray {
+ return src.toByteArray();
+ }
+
+ public function toString():String {
+ return "rsa";
+ }
+
+ public function dump():String {
+ var s:String= "N="+n.toString(16)+"\n"+
+ "E="+e.toString(16)+"\n";
+ if (canDecrypt) {
+ s+="D="+d.toString(16)+"\n";
+ if (p!=null && q!=null) {
+ s+="P="+p.toString(16)+"\n";
+ s+="Q="+q.toString(16)+"\n";
+ s+="DMP1="+dmp1.toString(16)+"\n";
+ s+="DMQ1="+dmq1.toString(16)+"\n";
+ s+="IQMP="+coeff.toString(16)+"\n";
+ }
+ }
+ return s;
+ }
+
+
+ /**
+ *
+ * note: We should have a "nice" variant of this function that takes a callback,
+ * and perform the computation is small fragments, to keep the web browser
+ * usable.
+ *
+ * @param B
+ * @param E
+ * @return a new random private key B bits long, using public expt E
+ *
+ */
+ public static function generate(B:uint, E:String):RSAKey {
+ var rng:Random = new Random;
+ var qs:uint = B>>1;
+ var key:RSAKey = new RSAKey(null,0,null);
+ key.e = parseInt(E, 16);
+ var ee:BigInteger = new BigInteger(E,16, true);
+ for (;;) {
+ for (;;) {
+ key.p = bigRandom(B-qs, rng);
+ if (key.p.subtract(BigInteger.ONE).gcd(ee).compareTo(BigInteger.ONE)==0 &&
+ key.p.isProbablePrime(10)) break;
+ }
+ for (;;) {
+ key.q = bigRandom(qs, rng);
+ if (key.q.subtract(BigInteger.ONE).gcd(ee).compareTo(BigInteger.ONE)==0 &&
+ key.q.isProbablePrime(10)) break;
+ }
+ if (key.p.compareTo(key.q)<=0) {
+ var t:BigInteger = key.p;
+ key.p = key.q;
+ key.q = t;
+ }
+ var p1:BigInteger = key.p.subtract(BigInteger.ONE);
+ var q1:BigInteger = key.q.subtract(BigInteger.ONE);
+ var phi:BigInteger = p1.multiply(q1);
+ if (phi.gcd(ee).compareTo(BigInteger.ONE)==0) {
+ key.n = key.p.multiply(key.q);
+ key.d = ee.modInverse(phi);
+ key.dmp1 = key.d.mod(p1);
+ key.dmq1 = key.d.mod(q1);
+ key.coeff = key.q.modInverse(key.p);
+ break;
+ }
+ }
+ return key;
+ }
+
+ protected static function bigRandom(bits:int, rnd:Random):BigInteger {
+ if (bits<2) return BigInteger.nbv(1);
+ var x:ByteArray = new ByteArray;
+ rnd.nextBytes(x, (bits>>3));
+ x.position = 0;
+ var b:BigInteger = new BigInteger(x,0,true);
+ b.primify(bits, 1);
+ return b;
+ }
+
+ protected function doPublic(x:BigInteger):BigInteger {
+ return x.modPowInt(e, n);
+ }
+
+ protected function doPrivate2(x:BigInteger):BigInteger {
+ if (p==null && q==null) {
+ return x.modPow(d,n);
+ }
+
+ var xp:BigInteger = x.mod(p).modPow(dmp1, p);
+ var xq:BigInteger = x.mod(q).modPow(dmq1, q);
+
+ while (xp.compareTo(xq)<0) {
+ xp = xp.add(p);
+ }
+ var r:BigInteger = xp.subtract(xq).multiply(coeff).mod(p).multiply(q).add(xq);
+
+ return r;
+ }
+
+ protected function doPrivate(x:BigInteger):BigInteger {
+ if (p==null || q==null) {
+ return x.modPow(d, n);
+ }
+ // TODO: re-calculate any missing CRT params
+ var xp:BigInteger = x.mod(p).modPow(dmp1, p);
+ var xq:BigInteger = x.mod(q).modPow(dmq1, q);
+
+ while (xp.compareTo(xq)<0) {
+ xp = xp.add(p);
+ }
+ return xp.subtract(xq).multiply(coeff).mod(p).multiply(q).add(xq);
+ }
+
+
+ }
+}
\ No newline at end of file diff --git a/flash-src/third-party/com/hurlant/crypto/symmetric/AESKey.as b/flash-src/third-party/com/hurlant/crypto/symmetric/AESKey.as new file mode 100644 index 0000000..a2280b7 --- /dev/null +++ b/flash-src/third-party/com/hurlant/crypto/symmetric/AESKey.as @@ -0,0 +1,2797 @@ +/**
+ * AESKey
+ *
+ * An ActionScript 3 implementation of the Advanced Encryption Standard, as
+ * defined in FIPS PUB 197
+ * Copyright (c) 2007 Henri Torgemane
+ *
+ * Derived from:
+ * A public domain implementation from Karl Malbrain, malbrain@yahoo.com
+ * (http://www.geocities.com/malbrain/aestable_c.html)
+ *
+ * See LICENSE.txt for full license information.
+ */
+package com.hurlant.crypto.symmetric
+{
+ import com.hurlant.crypto.prng.Random;
+ import com.hurlant.util.Hex;
+ import com.hurlant.util.Memory;
+
+ import flash.utils.ByteArray;
+
+ public class AESKey implements ISymmetricKey
+ {
+ // AES only supports Nb=4
+ private static const Nb:uint = 4; // number of columns in the state & expanded key
+
+ // TODO:
+ // - move those tables in binary files, then
+ // - [Embed()] them as ByteArray directly.
+ // (should result in smaller .swf, and faster initialization time.)
+
+ private static const _Sbox:Array = [ // forward s-box
+ 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];
+ private static const _InvSbox:Array = [ // inverse s-box
+ 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];
+ private static const _Xtime2Sbox:Array = [ // combined Xtimes2[Sbox[]]
+ 0xc6, 0xf8, 0xee, 0xf6, 0xff, 0xd6, 0xde, 0x91, 0x60, 0x02, 0xce, 0x56, 0xe7, 0xb5, 0x4d, 0xec,
+ 0x8f, 0x1f, 0x89, 0xfa, 0xef, 0xb2, 0x8e, 0xfb, 0x41, 0xb3, 0x5f, 0x45, 0x23, 0x53, 0xe4, 0x9b,
+ 0x75, 0xe1, 0x3d, 0x4c, 0x6c, 0x7e, 0xf5, 0x83, 0x68, 0x51, 0xd1, 0xf9, 0xe2, 0xab, 0x62, 0x2a,
+ 0x08, 0x95, 0x46, 0x9d, 0x30, 0x37, 0x0a, 0x2f, 0x0e, 0x24, 0x1b, 0xdf, 0xcd, 0x4e, 0x7f, 0xea,
+ 0x12, 0x1d, 0x58, 0x34, 0x36, 0xdc, 0xb4, 0x5b, 0xa4, 0x76, 0xb7, 0x7d, 0x52, 0xdd, 0x5e, 0x13,
+ 0xa6, 0xb9, 0x00, 0xc1, 0x40, 0xe3, 0x79, 0xb6, 0xd4, 0x8d, 0x67, 0x72, 0x94, 0x98, 0xb0, 0x85,
+ 0xbb, 0xc5, 0x4f, 0xed, 0x86, 0x9a, 0x66, 0x11, 0x8a, 0xe9, 0x04, 0xfe, 0xa0, 0x78, 0x25, 0x4b,
+ 0xa2, 0x5d, 0x80, 0x05, 0x3f, 0x21, 0x70, 0xf1, 0x63, 0x77, 0xaf, 0x42, 0x20, 0xe5, 0xfd, 0xbf,
+ 0x81, 0x18, 0x26, 0xc3, 0xbe, 0x35, 0x88, 0x2e, 0x93, 0x55, 0xfc, 0x7a, 0xc8, 0xba, 0x32, 0xe6,
+ 0xc0, 0x19, 0x9e, 0xa3, 0x44, 0x54, 0x3b, 0x0b, 0x8c, 0xc7, 0x6b, 0x28, 0xa7, 0xbc, 0x16, 0xad,
+ 0xdb, 0x64, 0x74, 0x14, 0x92, 0x0c, 0x48, 0xb8, 0x9f, 0xbd, 0x43, 0xc4, 0x39, 0x31, 0xd3, 0xf2,
+ 0xd5, 0x8b, 0x6e, 0xda, 0x01, 0xb1, 0x9c, 0x49, 0xd8, 0xac, 0xf3, 0xcf, 0xca, 0xf4, 0x47, 0x10,
+ 0x6f, 0xf0, 0x4a, 0x5c, 0x38, 0x57, 0x73, 0x97, 0xcb, 0xa1, 0xe8, 0x3e, 0x96, 0x61, 0x0d, 0x0f,
+ 0xe0, 0x7c, 0x71, 0xcc, 0x90, 0x06, 0xf7, 0x1c, 0xc2, 0x6a, 0xae, 0x69, 0x17, 0x99, 0x3a, 0x27,
+ 0xd9, 0xeb, 0x2b, 0x22, 0xd2, 0xa9, 0x07, 0x33, 0x2d, 0x3c, 0x15, 0xc9, 0x87, 0xaa, 0x50, 0xa5,
+ 0x03, 0x59, 0x09, 0x1a, 0x65, 0xd7, 0x84, 0xd0, 0x82, 0x29, 0x5a, 0x1e, 0x7b, 0xa8, 0x6d, 0x2c];
+ private static const _Xtime3Sbox:Array = [ // combined Xtimes3[Sbox[]]
+ 0xa5, 0x84, 0x99, 0x8d, 0x0d, 0xbd, 0xb1, 0x54, 0x50, 0x03, 0xa9, 0x7d, 0x19, 0x62, 0xe6, 0x9a,
+ 0x45, 0x9d, 0x40, 0x87, 0x15, 0xeb, 0xc9, 0x0b, 0xec, 0x67, 0xfd, 0xea, 0xbf, 0xf7, 0x96, 0x5b,
+ 0xc2, 0x1c, 0xae, 0x6a, 0x5a, 0x41, 0x02, 0x4f, 0x5c, 0xf4, 0x34, 0x08, 0x93, 0x73, 0x53, 0x3f,
+ 0x0c, 0x52, 0x65, 0x5e, 0x28, 0xa1, 0x0f, 0xb5, 0x09, 0x36, 0x9b, 0x3d, 0x26, 0x69, 0xcd, 0x9f,
+ 0x1b, 0x9e, 0x74, 0x2e, 0x2d, 0xb2, 0xee, 0xfb, 0xf6, 0x4d, 0x61, 0xce, 0x7b, 0x3e, 0x71, 0x97,
+ 0xf5, 0x68, 0x00, 0x2c, 0x60, 0x1f, 0xc8, 0xed, 0xbe, 0x46, 0xd9, 0x4b, 0xde, 0xd4, 0xe8, 0x4a,
+ 0x6b, 0x2a, 0xe5, 0x16, 0xc5, 0xd7, 0x55, 0x94, 0xcf, 0x10, 0x06, 0x81, 0xf0, 0x44, 0xba, 0xe3,
+ 0xf3, 0xfe, 0xc0, 0x8a, 0xad, 0xbc, 0x48, 0x04, 0xdf, 0xc1, 0x75, 0x63, 0x30, 0x1a, 0x0e, 0x6d,
+ 0x4c, 0x14, 0x35, 0x2f, 0xe1, 0xa2, 0xcc, 0x39, 0x57, 0xf2, 0x82, 0x47, 0xac, 0xe7, 0x2b, 0x95,
+ 0xa0, 0x98, 0xd1, 0x7f, 0x66, 0x7e, 0xab, 0x83, 0xca, 0x29, 0xd3, 0x3c, 0x79, 0xe2, 0x1d, 0x76,
+ 0x3b, 0x56, 0x4e, 0x1e, 0xdb, 0x0a, 0x6c, 0xe4, 0x5d, 0x6e, 0xef, 0xa6, 0xa8, 0xa4, 0x37, 0x8b,
+ 0x32, 0x43, 0x59, 0xb7, 0x8c, 0x64, 0xd2, 0xe0, 0xb4, 0xfa, 0x07, 0x25, 0xaf, 0x8e, 0xe9, 0x18,
+ 0xd5, 0x88, 0x6f, 0x72, 0x24, 0xf1, 0xc7, 0x51, 0x23, 0x7c, 0x9c, 0x21, 0xdd, 0xdc, 0x86, 0x85,
+ 0x90, 0x42, 0xc4, 0xaa, 0xd8, 0x05, 0x01, 0x12, 0xa3, 0x5f, 0xf9, 0xd0, 0x91, 0x58, 0x27, 0xb9,
+ 0x38, 0x13, 0xb3, 0x33, 0xbb, 0x70, 0x89, 0xa7, 0xb6, 0x22, 0x92, 0x20, 0x49, 0xff, 0x78, 0x7a,
+ 0x8f, 0xf8, 0x80, 0x17, 0xda, 0x31, 0xc6, 0xb8, 0xc3, 0xb0, 0x77, 0x11, 0xcb, 0xfc, 0xd6, 0x3a];
+ // modular multiplication tables
+ // based on:
+
+ // Xtime2[x] = (x & 0x80 ? 0x1b : 0) ^ (x + x)
+ // Xtime3[x] = x^Xtime2[x];
+ private static const _Xtime2:Array = [
+ 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];
+ private static const _Xtime9:Array = [
+ 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];
+ private static const _XtimeB:Array = [
+ 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];
+ private static const _XtimeD:Array = [
+ 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];
+ private static const _XtimeE:Array = [
+ 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];
+ static private var _Rcon:Array = [
+ 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36];
+ static private var Sbox:ByteArray;
+ static private var InvSbox:ByteArray;
+ static private var Xtime2Sbox:ByteArray
+ static private var Xtime3Sbox:ByteArray
+ static private var Xtime2:ByteArray;
+ static private var Xtime9:ByteArray;
+ static private var XtimeB:ByteArray;
+ static private var XtimeD:ByteArray;
+ static private var XtimeE:ByteArray;
+ static private var Rcon:ByteArray;
+ // static initializer
+ {
+ static private var i:uint;
+ Sbox = new ByteArray;
+ InvSbox = new ByteArray;
+ Xtime2Sbox = new ByteArray;
+ Xtime3Sbox = new ByteArray;
+ Xtime2 = new ByteArray;
+ Xtime9 = new ByteArray;
+ XtimeB = new ByteArray;
+ XtimeD = new ByteArray;
+ XtimeE = new ByteArray;
+ /*
+ for (i=0;i<256;i++) {
+ Sbox[i] = _Sbox[i];
+ InvSbox[i] = _InvSbox[i];
+ Xtime2Sbox[i] = _Xtime2Sbox[i];
+ Xtime3Sbox[i] = _Xtime3Sbox[i];
+ Xtime2[i] = _Xtime2[i];
+ Xtime9[i] = _Xtime9[i];
+ XtimeB[i] = _XtimeB[i];
+ XtimeD[i] = _XtimeD[i];
+ XtimeE[i] = _XtimeE[i];
+ }
+ */
+ Sbox[0] = _Sbox[0]
+ InvSbox[0] = _InvSbox[0]
+ Xtime2Sbox[0] = _Xtime2Sbox[0]
+ Xtime3Sbox[0] = _Xtime3Sbox[0]
+ Xtime2[0] = _Xtime2[0]
+ Xtime9[0] = _Xtime9[0]
+ XtimeB[0] = _XtimeB[0]
+ XtimeD[0] = _XtimeD[0]
+ XtimeE[0] = _XtimeE[0]
+ Sbox[1] = _Sbox[1]
+ InvSbox[1] = _InvSbox[1]
+ Xtime2Sbox[1] = _Xtime2Sbox[1]
+ Xtime3Sbox[1] = _Xtime3Sbox[1]
+ Xtime2[1] = _Xtime2[1]
+ Xtime9[1] = _Xtime9[1]
+ XtimeB[1] = _XtimeB[1]
+ XtimeD[1] = _XtimeD[1]
+ XtimeE[1] = _XtimeE[1]
+ Sbox[2] = _Sbox[2]
+ InvSbox[2] = _InvSbox[2]
+ Xtime2Sbox[2] = _Xtime2Sbox[2]
+ Xtime3Sbox[2] = _Xtime3Sbox[2]
+ Xtime2[2] = _Xtime2[2]
+ Xtime9[2] = _Xtime9[2]
+ XtimeB[2] = _XtimeB[2]
+ XtimeD[2] = _XtimeD[2]
+ XtimeE[2] = _XtimeE[2]
+ Sbox[3] = _Sbox[3]
+ InvSbox[3] = _InvSbox[3]
+ Xtime2Sbox[3] = _Xtime2Sbox[3]
+ Xtime3Sbox[3] = _Xtime3Sbox[3]
+ Xtime2[3] = _Xtime2[3]
+ Xtime9[3] = _Xtime9[3]
+ XtimeB[3] = _XtimeB[3]
+ XtimeD[3] = _XtimeD[3]
+ XtimeE[3] = _XtimeE[3]
+ Sbox[4] = _Sbox[4]
+ InvSbox[4] = _InvSbox[4]
+ Xtime2Sbox[4] = _Xtime2Sbox[4]
+ Xtime3Sbox[4] = _Xtime3Sbox[4]
+ Xtime2[4] = _Xtime2[4]
+ Xtime9[4] = _Xtime9[4]
+ XtimeB[4] = _XtimeB[4]
+ XtimeD[4] = _XtimeD[4]
+ XtimeE[4] = _XtimeE[4]
+ Sbox[5] = _Sbox[5]
+ InvSbox[5] = _InvSbox[5]
+ Xtime2Sbox[5] = _Xtime2Sbox[5]
+ Xtime3Sbox[5] = _Xtime3Sbox[5]
+ Xtime2[5] = _Xtime2[5]
+ Xtime9[5] = _Xtime9[5]
+ XtimeB[5] = _XtimeB[5]
+ XtimeD[5] = _XtimeD[5]
+ XtimeE[5] = _XtimeE[5]
+ Sbox[6] = _Sbox[6]
+ InvSbox[6] = _InvSbox[6]
+ Xtime2Sbox[6] = _Xtime2Sbox[6]
+ Xtime3Sbox[6] = _Xtime3Sbox[6]
+ Xtime2[6] = _Xtime2[6]
+ Xtime9[6] = _Xtime9[6]
+ XtimeB[6] = _XtimeB[6]
+ XtimeD[6] = _XtimeD[6]
+ XtimeE[6] = _XtimeE[6]
+ Sbox[7] = _Sbox[7]
+ InvSbox[7] = _InvSbox[7]
+ Xtime2Sbox[7] = _Xtime2Sbox[7]
+ Xtime3Sbox[7] = _Xtime3Sbox[7]
+ Xtime2[7] = _Xtime2[7]
+ Xtime9[7] = _Xtime9[7]
+ XtimeB[7] = _XtimeB[7]
+ XtimeD[7] = _XtimeD[7]
+ XtimeE[7] = _XtimeE[7]
+ Sbox[8] = _Sbox[8]
+ InvSbox[8] = _InvSbox[8]
+ Xtime2Sbox[8] = _Xtime2Sbox[8]
+ Xtime3Sbox[8] = _Xtime3Sbox[8]
+ Xtime2[8] = _Xtime2[8]
+ Xtime9[8] = _Xtime9[8]
+ XtimeB[8] = _XtimeB[8]
+ XtimeD[8] = _XtimeD[8]
+ XtimeE[8] = _XtimeE[8]
+ Sbox[9] = _Sbox[9]
+ InvSbox[9] = _InvSbox[9]
+ Xtime2Sbox[9] = _Xtime2Sbox[9]
+ Xtime3Sbox[9] = _Xtime3Sbox[9]
+ Xtime2[9] = _Xtime2[9]
+ Xtime9[9] = _Xtime9[9]
+ XtimeB[9] = _XtimeB[9]
+ XtimeD[9] = _XtimeD[9]
+ XtimeE[9] = _XtimeE[9]
+ Sbox[10] = _Sbox[10]
+ InvSbox[10] = _InvSbox[10]
+ Xtime2Sbox[10] = _Xtime2Sbox[10]
+ Xtime3Sbox[10] = _Xtime3Sbox[10]
+ Xtime2[10] = _Xtime2[10]
+ Xtime9[10] = _Xtime9[10]
+ XtimeB[10] = _XtimeB[10]
+ XtimeD[10] = _XtimeD[10]
+ XtimeE[10] = _XtimeE[10]
+ Sbox[11] = _Sbox[11]
+ InvSbox[11] = _InvSbox[11]
+ Xtime2Sbox[11] = _Xtime2Sbox[11]
+ Xtime3Sbox[11] = _Xtime3Sbox[11]
+ Xtime2[11] = _Xtime2[11]
+ Xtime9[11] = _Xtime9[11]
+ XtimeB[11] = _XtimeB[11]
+ XtimeD[11] = _XtimeD[11]
+ XtimeE[11] = _XtimeE[11]
+ Sbox[12] = _Sbox[12]
+ InvSbox[12] = _InvSbox[12]
+ Xtime2Sbox[12] = _Xtime2Sbox[12]
+ Xtime3Sbox[12] = _Xtime3Sbox[12]
+ Xtime2[12] = _Xtime2[12]
+ Xtime9[12] = _Xtime9[12]
+ XtimeB[12] = _XtimeB[12]
+ XtimeD[12] = _XtimeD[12]
+ XtimeE[12] = _XtimeE[12]
+ Sbox[13] = _Sbox[13]
+ InvSbox[13] = _InvSbox[13]
+ Xtime2Sbox[13] = _Xtime2Sbox[13]
+ Xtime3Sbox[13] = _Xtime3Sbox[13]
+ Xtime2[13] = _Xtime2[13]
+ Xtime9[13] = _Xtime9[13]
+ XtimeB[13] = _XtimeB[13]
+ XtimeD[13] = _XtimeD[13]
+ XtimeE[13] = _XtimeE[13]
+ Sbox[14] = _Sbox[14]
+ InvSbox[14] = _InvSbox[14]
+ Xtime2Sbox[14] = _Xtime2Sbox[14]
+ Xtime3Sbox[14] = _Xtime3Sbox[14]
+ Xtime2[14] = _Xtime2[14]
+ Xtime9[14] = _Xtime9[14]
+ XtimeB[14] = _XtimeB[14]
+ XtimeD[14] = _XtimeD[14]
+ XtimeE[14] = _XtimeE[14]
+ Sbox[15] = _Sbox[15]
+ InvSbox[15] = _InvSbox[15]
+ Xtime2Sbox[15] = _Xtime2Sbox[15]
+ Xtime3Sbox[15] = _Xtime3Sbox[15]
+ Xtime2[15] = _Xtime2[15]
+ Xtime9[15] = _Xtime9[15]
+ XtimeB[15] = _XtimeB[15]
+ XtimeD[15] = _XtimeD[15]
+ XtimeE[15] = _XtimeE[15]
+ Sbox[16] = _Sbox[16]
+ InvSbox[16] = _InvSbox[16]
+ Xtime2Sbox[16] = _Xtime2Sbox[16]
+ Xtime3Sbox[16] = _Xtime3Sbox[16]
+ Xtime2[16] = _Xtime2[16]
+ Xtime9[16] = _Xtime9[16]
+ XtimeB[16] = _XtimeB[16]
+ XtimeD[16] = _XtimeD[16]
+ XtimeE[16] = _XtimeE[16]
+ Sbox[17] = _Sbox[17]
+ InvSbox[17] = _InvSbox[17]
+ Xtime2Sbox[17] = _Xtime2Sbox[17]
+ Xtime3Sbox[17] = _Xtime3Sbox[17]
+ Xtime2[17] = _Xtime2[17]
+ Xtime9[17] = _Xtime9[17]
+ XtimeB[17] = _XtimeB[17]
+ XtimeD[17] = _XtimeD[17]
+ XtimeE[17] = _XtimeE[17]
+ Sbox[18] = _Sbox[18]
+ InvSbox[18] = _InvSbox[18]
+ Xtime2Sbox[18] = _Xtime2Sbox[18]
+ Xtime3Sbox[18] = _Xtime3Sbox[18]
+ Xtime2[18] = _Xtime2[18]
+ Xtime9[18] = _Xtime9[18]
+ XtimeB[18] = _XtimeB[18]
+ XtimeD[18] = _XtimeD[18]
+ XtimeE[18] = _XtimeE[18]
+ Sbox[19] = _Sbox[19]
+ InvSbox[19] = _InvSbox[19]
+ Xtime2Sbox[19] = _Xtime2Sbox[19]
+ Xtime3Sbox[19] = _Xtime3Sbox[19]
+ Xtime2[19] = _Xtime2[19]
+ Xtime9[19] = _Xtime9[19]
+ XtimeB[19] = _XtimeB[19]
+ XtimeD[19] = _XtimeD[19]
+ XtimeE[19] = _XtimeE[19]
+ Sbox[20] = _Sbox[20]
+ InvSbox[20] = _InvSbox[20]
+ Xtime2Sbox[20] = _Xtime2Sbox[20]
+ Xtime3Sbox[20] = _Xtime3Sbox[20]
+ Xtime2[20] = _Xtime2[20]
+ Xtime9[20] = _Xtime9[20]
+ XtimeB[20] = _XtimeB[20]
+ XtimeD[20] = _XtimeD[20]
+ XtimeE[20] = _XtimeE[20]
+ Sbox[21] = _Sbox[21]
+ InvSbox[21] = _InvSbox[21]
+ Xtime2Sbox[21] = _Xtime2Sbox[21]
+ Xtime3Sbox[21] = _Xtime3Sbox[21]
+ Xtime2[21] = _Xtime2[21]
+ Xtime9[21] = _Xtime9[21]
+ XtimeB[21] = _XtimeB[21]
+ XtimeD[21] = _XtimeD[21]
+ XtimeE[21] = _XtimeE[21]
+ Sbox[22] = _Sbox[22]
+ InvSbox[22] = _InvSbox[22]
+ Xtime2Sbox[22] = _Xtime2Sbox[22]
+ Xtime3Sbox[22] = _Xtime3Sbox[22]
+ Xtime2[22] = _Xtime2[22]
+ Xtime9[22] = _Xtime9[22]
+ XtimeB[22] = _XtimeB[22]
+ XtimeD[22] = _XtimeD[22]
+ XtimeE[22] = _XtimeE[22]
+ Sbox[23] = _Sbox[23]
+ InvSbox[23] = _InvSbox[23]
+ Xtime2Sbox[23] = _Xtime2Sbox[23]
+ Xtime3Sbox[23] = _Xtime3Sbox[23]
+ Xtime2[23] = _Xtime2[23]
+ Xtime9[23] = _Xtime9[23]
+ XtimeB[23] = _XtimeB[23]
+ XtimeD[23] = _XtimeD[23]
+ XtimeE[23] = _XtimeE[23]
+ Sbox[24] = _Sbox[24]
+ InvSbox[24] = _InvSbox[24]
+ Xtime2Sbox[24] = _Xtime2Sbox[24]
+ Xtime3Sbox[24] = _Xtime3Sbox[24]
+ Xtime2[24] = _Xtime2[24]
+ Xtime9[24] = _Xtime9[24]
+ XtimeB[24] = _XtimeB[24]
+ XtimeD[24] = _XtimeD[24]
+ XtimeE[24] = _XtimeE[24]
+ Sbox[25] = _Sbox[25]
+ InvSbox[25] = _InvSbox[25]
+ Xtime2Sbox[25] = _Xtime2Sbox[25]
+ Xtime3Sbox[25] = _Xtime3Sbox[25]
+ Xtime2[25] = _Xtime2[25]
+ Xtime9[25] = _Xtime9[25]
+ XtimeB[25] = _XtimeB[25]
+ XtimeD[25] = _XtimeD[25]
+ XtimeE[25] = _XtimeE[25]
+ Sbox[26] = _Sbox[26]
+ InvSbox[26] = _InvSbox[26]
+ Xtime2Sbox[26] = _Xtime2Sbox[26]
+ Xtime3Sbox[26] = _Xtime3Sbox[26]
+ Xtime2[26] = _Xtime2[26]
+ Xtime9[26] = _Xtime9[26]
+ XtimeB[26] = _XtimeB[26]
+ XtimeD[26] = _XtimeD[26]
+ XtimeE[26] = _XtimeE[26]
+ Sbox[27] = _Sbox[27]
+ InvSbox[27] = _InvSbox[27]
+ Xtime2Sbox[27] = _Xtime2Sbox[27]
+ Xtime3Sbox[27] = _Xtime3Sbox[27]
+ Xtime2[27] = _Xtime2[27]
+ Xtime9[27] = _Xtime9[27]
+ XtimeB[27] = _XtimeB[27]
+ XtimeD[27] = _XtimeD[27]
+ XtimeE[27] = _XtimeE[27]
+ Sbox[28] = _Sbox[28]
+ InvSbox[28] = _InvSbox[28]
+ Xtime2Sbox[28] = _Xtime2Sbox[28]
+ Xtime3Sbox[28] = _Xtime3Sbox[28]
+ Xtime2[28] = _Xtime2[28]
+ Xtime9[28] = _Xtime9[28]
+ XtimeB[28] = _XtimeB[28]
+ XtimeD[28] = _XtimeD[28]
+ XtimeE[28] = _XtimeE[28]
+ Sbox[29] = _Sbox[29]
+ InvSbox[29] = _InvSbox[29]
+ Xtime2Sbox[29] = _Xtime2Sbox[29]
+ Xtime3Sbox[29] = _Xtime3Sbox[29]
+ Xtime2[29] = _Xtime2[29]
+ Xtime9[29] = _Xtime9[29]
+ XtimeB[29] = _XtimeB[29]
+ XtimeD[29] = _XtimeD[29]
+ XtimeE[29] = _XtimeE[29]
+ Sbox[30] = _Sbox[30]
+ InvSbox[30] = _InvSbox[30]
+ Xtime2Sbox[30] = _Xtime2Sbox[30]
+ Xtime3Sbox[30] = _Xtime3Sbox[30]
+ Xtime2[30] = _Xtime2[30]
+ Xtime9[30] = _Xtime9[30]
+ XtimeB[30] = _XtimeB[30]
+ XtimeD[30] = _XtimeD[30]
+ XtimeE[30] = _XtimeE[30]
+ Sbox[31] = _Sbox[31]
+ InvSbox[31] = _InvSbox[31]
+ Xtime2Sbox[31] = _Xtime2Sbox[31]
+ Xtime3Sbox[31] = _Xtime3Sbox[31]
+ Xtime2[31] = _Xtime2[31]
+ Xtime9[31] = _Xtime9[31]
+ XtimeB[31] = _XtimeB[31]
+ XtimeD[31] = _XtimeD[31]
+ XtimeE[31] = _XtimeE[31]
+ Sbox[32] = _Sbox[32]
+ InvSbox[32] = _InvSbox[32]
+ Xtime2Sbox[32] = _Xtime2Sbox[32]
+ Xtime3Sbox[32] = _Xtime3Sbox[32]
+ Xtime2[32] = _Xtime2[32]
+ Xtime9[32] = _Xtime9[32]
+ XtimeB[32] = _XtimeB[32]
+ XtimeD[32] = _XtimeD[32]
+ XtimeE[32] = _XtimeE[32]
+ Sbox[33] = _Sbox[33]
+ InvSbox[33] = _InvSbox[33]
+ Xtime2Sbox[33] = _Xtime2Sbox[33]
+ Xtime3Sbox[33] = _Xtime3Sbox[33]
+ Xtime2[33] = _Xtime2[33]
+ Xtime9[33] = _Xtime9[33]
+ XtimeB[33] = _XtimeB[33]
+ XtimeD[33] = _XtimeD[33]
+ XtimeE[33] = _XtimeE[33]
+ Sbox[34] = _Sbox[34]
+ InvSbox[34] = _InvSbox[34]
+ Xtime2Sbox[34] = _Xtime2Sbox[34]
+ Xtime3Sbox[34] = _Xtime3Sbox[34]
+ Xtime2[34] = _Xtime2[34]
+ Xtime9[34] = _Xtime9[34]
+ XtimeB[34] = _XtimeB[34]
+ XtimeD[34] = _XtimeD[34]
+ XtimeE[34] = _XtimeE[34]
+ Sbox[35] = _Sbox[35]
+ InvSbox[35] = _InvSbox[35]
+ Xtime2Sbox[35] = _Xtime2Sbox[35]
+ Xtime3Sbox[35] = _Xtime3Sbox[35]
+ Xtime2[35] = _Xtime2[35]
+ Xtime9[35] = _Xtime9[35]
+ XtimeB[35] = _XtimeB[35]
+ XtimeD[35] = _XtimeD[35]
+ XtimeE[35] = _XtimeE[35]
+ Sbox[36] = _Sbox[36]
+ InvSbox[36] = _InvSbox[36]
+ Xtime2Sbox[36] = _Xtime2Sbox[36]
+ Xtime3Sbox[36] = _Xtime3Sbox[36]
+ Xtime2[36] = _Xtime2[36]
+ Xtime9[36] = _Xtime9[36]
+ XtimeB[36] = _XtimeB[36]
+ XtimeD[36] = _XtimeD[36]
+ XtimeE[36] = _XtimeE[36]
+ Sbox[37] = _Sbox[37]
+ InvSbox[37] = _InvSbox[37]
+ Xtime2Sbox[37] = _Xtime2Sbox[37]
+ Xtime3Sbox[37] = _Xtime3Sbox[37]
+ Xtime2[37] = _Xtime2[37]
+ Xtime9[37] = _Xtime9[37]
+ XtimeB[37] = _XtimeB[37]
+ XtimeD[37] = _XtimeD[37]
+ XtimeE[37] = _XtimeE[37]
+ Sbox[38] = _Sbox[38]
+ InvSbox[38] = _InvSbox[38]
+ Xtime2Sbox[38] = _Xtime2Sbox[38]
+ Xtime3Sbox[38] = _Xtime3Sbox[38]
+ Xtime2[38] = _Xtime2[38]
+ Xtime9[38] = _Xtime9[38]
+ XtimeB[38] = _XtimeB[38]
+ XtimeD[38] = _XtimeD[38]
+ XtimeE[38] = _XtimeE[38]
+ Sbox[39] = _Sbox[39]
+ InvSbox[39] = _InvSbox[39]
+ Xtime2Sbox[39] = _Xtime2Sbox[39]
+ Xtime3Sbox[39] = _Xtime3Sbox[39]
+ Xtime2[39] = _Xtime2[39]
+ Xtime9[39] = _Xtime9[39]
+ XtimeB[39] = _XtimeB[39]
+ XtimeD[39] = _XtimeD[39]
+ XtimeE[39] = _XtimeE[39]
+ Sbox[40] = _Sbox[40]
+ InvSbox[40] = _InvSbox[40]
+ Xtime2Sbox[40] = _Xtime2Sbox[40]
+ Xtime3Sbox[40] = _Xtime3Sbox[40]
+ Xtime2[40] = _Xtime2[40]
+ Xtime9[40] = _Xtime9[40]
+ XtimeB[40] = _XtimeB[40]
+ XtimeD[40] = _XtimeD[40]
+ XtimeE[40] = _XtimeE[40]
+ Sbox[41] = _Sbox[41]
+ InvSbox[41] = _InvSbox[41]
+ Xtime2Sbox[41] = _Xtime2Sbox[41]
+ Xtime3Sbox[41] = _Xtime3Sbox[41]
+ Xtime2[41] = _Xtime2[41]
+ Xtime9[41] = _Xtime9[41]
+ XtimeB[41] = _XtimeB[41]
+ XtimeD[41] = _XtimeD[41]
+ XtimeE[41] = _XtimeE[41]
+ Sbox[42] = _Sbox[42]
+ InvSbox[42] = _InvSbox[42]
+ Xtime2Sbox[42] = _Xtime2Sbox[42]
+ Xtime3Sbox[42] = _Xtime3Sbox[42]
+ Xtime2[42] = _Xtime2[42]
+ Xtime9[42] = _Xtime9[42]
+ XtimeB[42] = _XtimeB[42]
+ XtimeD[42] = _XtimeD[42]
+ XtimeE[42] = _XtimeE[42]
+ Sbox[43] = _Sbox[43]
+ InvSbox[43] = _InvSbox[43]
+ Xtime2Sbox[43] = _Xtime2Sbox[43]
+ Xtime3Sbox[43] = _Xtime3Sbox[43]
+ Xtime2[43] = _Xtime2[43]
+ Xtime9[43] = _Xtime9[43]
+ XtimeB[43] = _XtimeB[43]
+ XtimeD[43] = _XtimeD[43]
+ XtimeE[43] = _XtimeE[43]
+ Sbox[44] = _Sbox[44]
+ InvSbox[44] = _InvSbox[44]
+ Xtime2Sbox[44] = _Xtime2Sbox[44]
+ Xtime3Sbox[44] = _Xtime3Sbox[44]
+ Xtime2[44] = _Xtime2[44]
+ Xtime9[44] = _Xtime9[44]
+ XtimeB[44] = _XtimeB[44]
+ XtimeD[44] = _XtimeD[44]
+ XtimeE[44] = _XtimeE[44]
+ Sbox[45] = _Sbox[45]
+ InvSbox[45] = _InvSbox[45]
+ Xtime2Sbox[45] = _Xtime2Sbox[45]
+ Xtime3Sbox[45] = _Xtime3Sbox[45]
+ Xtime2[45] = _Xtime2[45]
+ Xtime9[45] = _Xtime9[45]
+ XtimeB[45] = _XtimeB[45]
+ XtimeD[45] = _XtimeD[45]
+ XtimeE[45] = _XtimeE[45]
+ Sbox[46] = _Sbox[46]
+ InvSbox[46] = _InvSbox[46]
+ Xtime2Sbox[46] = _Xtime2Sbox[46]
+ Xtime3Sbox[46] = _Xtime3Sbox[46]
+ Xtime2[46] = _Xtime2[46]
+ Xtime9[46] = _Xtime9[46]
+ XtimeB[46] = _XtimeB[46]
+ XtimeD[46] = _XtimeD[46]
+ XtimeE[46] = _XtimeE[46]
+ Sbox[47] = _Sbox[47]
+ InvSbox[47] = _InvSbox[47]
+ Xtime2Sbox[47] = _Xtime2Sbox[47]
+ Xtime3Sbox[47] = _Xtime3Sbox[47]
+ Xtime2[47] = _Xtime2[47]
+ Xtime9[47] = _Xtime9[47]
+ XtimeB[47] = _XtimeB[47]
+ XtimeD[47] = _XtimeD[47]
+ XtimeE[47] = _XtimeE[47]
+ Sbox[48] = _Sbox[48]
+ InvSbox[48] = _InvSbox[48]
+ Xtime2Sbox[48] = _Xtime2Sbox[48]
+ Xtime3Sbox[48] = _Xtime3Sbox[48]
+ Xtime2[48] = _Xtime2[48]
+ Xtime9[48] = _Xtime9[48]
+ XtimeB[48] = _XtimeB[48]
+ XtimeD[48] = _XtimeD[48]
+ XtimeE[48] = _XtimeE[48]
+ Sbox[49] = _Sbox[49]
+ InvSbox[49] = _InvSbox[49]
+ Xtime2Sbox[49] = _Xtime2Sbox[49]
+ Xtime3Sbox[49] = _Xtime3Sbox[49]
+ Xtime2[49] = _Xtime2[49]
+ Xtime9[49] = _Xtime9[49]
+ XtimeB[49] = _XtimeB[49]
+ XtimeD[49] = _XtimeD[49]
+ XtimeE[49] = _XtimeE[49]
+ Sbox[50] = _Sbox[50]
+ InvSbox[50] = _InvSbox[50]
+ Xtime2Sbox[50] = _Xtime2Sbox[50]
+ Xtime3Sbox[50] = _Xtime3Sbox[50]
+ Xtime2[50] = _Xtime2[50]
+ Xtime9[50] = _Xtime9[50]
+ XtimeB[50] = _XtimeB[50]
+ XtimeD[50] = _XtimeD[50]
+ XtimeE[50] = _XtimeE[50]
+ Sbox[51] = _Sbox[51]
+ InvSbox[51] = _InvSbox[51]
+ Xtime2Sbox[51] = _Xtime2Sbox[51]
+ Xtime3Sbox[51] = _Xtime3Sbox[51]
+ Xtime2[51] = _Xtime2[51]
+ Xtime9[51] = _Xtime9[51]
+ XtimeB[51] = _XtimeB[51]
+ XtimeD[51] = _XtimeD[51]
+ XtimeE[51] = _XtimeE[51]
+ Sbox[52] = _Sbox[52]
+ InvSbox[52] = _InvSbox[52]
+ Xtime2Sbox[52] = _Xtime2Sbox[52]
+ Xtime3Sbox[52] = _Xtime3Sbox[52]
+ Xtime2[52] = _Xtime2[52]
+ Xtime9[52] = _Xtime9[52]
+ XtimeB[52] = _XtimeB[52]
+ XtimeD[52] = _XtimeD[52]
+ XtimeE[52] = _XtimeE[52]
+ Sbox[53] = _Sbox[53]
+ InvSbox[53] = _InvSbox[53]
+ Xtime2Sbox[53] = _Xtime2Sbox[53]
+ Xtime3Sbox[53] = _Xtime3Sbox[53]
+ Xtime2[53] = _Xtime2[53]
+ Xtime9[53] = _Xtime9[53]
+ XtimeB[53] = _XtimeB[53]
+ XtimeD[53] = _XtimeD[53]
+ XtimeE[53] = _XtimeE[53]
+ Sbox[54] = _Sbox[54]
+ InvSbox[54] = _InvSbox[54]
+ Xtime2Sbox[54] = _Xtime2Sbox[54]
+ Xtime3Sbox[54] = _Xtime3Sbox[54]
+ Xtime2[54] = _Xtime2[54]
+ Xtime9[54] = _Xtime9[54]
+ XtimeB[54] = _XtimeB[54]
+ XtimeD[54] = _XtimeD[54]
+ XtimeE[54] = _XtimeE[54]
+ Sbox[55] = _Sbox[55]
+ InvSbox[55] = _InvSbox[55]
+ Xtime2Sbox[55] = _Xtime2Sbox[55]
+ Xtime3Sbox[55] = _Xtime3Sbox[55]
+ Xtime2[55] = _Xtime2[55]
+ Xtime9[55] = _Xtime9[55]
+ XtimeB[55] = _XtimeB[55]
+ XtimeD[55] = _XtimeD[55]
+ XtimeE[55] = _XtimeE[55]
+ Sbox[56] = _Sbox[56]
+ InvSbox[56] = _InvSbox[56]
+ Xtime2Sbox[56] = _Xtime2Sbox[56]
+ Xtime3Sbox[56] = _Xtime3Sbox[56]
+ Xtime2[56] = _Xtime2[56]
+ Xtime9[56] = _Xtime9[56]
+ XtimeB[56] = _XtimeB[56]
+ XtimeD[56] = _XtimeD[56]
+ XtimeE[56] = _XtimeE[56]
+ Sbox[57] = _Sbox[57]
+ InvSbox[57] = _InvSbox[57]
+ Xtime2Sbox[57] = _Xtime2Sbox[57]
+ Xtime3Sbox[57] = _Xtime3Sbox[57]
+ Xtime2[57] = _Xtime2[57]
+ Xtime9[57] = _Xtime9[57]
+ XtimeB[57] = _XtimeB[57]
+ XtimeD[57] = _XtimeD[57]
+ XtimeE[57] = _XtimeE[57]
+ Sbox[58] = _Sbox[58]
+ InvSbox[58] = _InvSbox[58]
+ Xtime2Sbox[58] = _Xtime2Sbox[58]
+ Xtime3Sbox[58] = _Xtime3Sbox[58]
+ Xtime2[58] = _Xtime2[58]
+ Xtime9[58] = _Xtime9[58]
+ XtimeB[58] = _XtimeB[58]
+ XtimeD[58] = _XtimeD[58]
+ XtimeE[58] = _XtimeE[58]
+ Sbox[59] = _Sbox[59]
+ InvSbox[59] = _InvSbox[59]
+ Xtime2Sbox[59] = _Xtime2Sbox[59]
+ Xtime3Sbox[59] = _Xtime3Sbox[59]
+ Xtime2[59] = _Xtime2[59]
+ Xtime9[59] = _Xtime9[59]
+ XtimeB[59] = _XtimeB[59]
+ XtimeD[59] = _XtimeD[59]
+ XtimeE[59] = _XtimeE[59]
+ Sbox[60] = _Sbox[60]
+ InvSbox[60] = _InvSbox[60]
+ Xtime2Sbox[60] = _Xtime2Sbox[60]
+ Xtime3Sbox[60] = _Xtime3Sbox[60]
+ Xtime2[60] = _Xtime2[60]
+ Xtime9[60] = _Xtime9[60]
+ XtimeB[60] = _XtimeB[60]
+ XtimeD[60] = _XtimeD[60]
+ XtimeE[60] = _XtimeE[60]
+ Sbox[61] = _Sbox[61]
+ InvSbox[61] = _InvSbox[61]
+ Xtime2Sbox[61] = _Xtime2Sbox[61]
+ Xtime3Sbox[61] = _Xtime3Sbox[61]
+ Xtime2[61] = _Xtime2[61]
+ Xtime9[61] = _Xtime9[61]
+ XtimeB[61] = _XtimeB[61]
+ XtimeD[61] = _XtimeD[61]
+ XtimeE[61] = _XtimeE[61]
+ Sbox[62] = _Sbox[62]
+ InvSbox[62] = _InvSbox[62]
+ Xtime2Sbox[62] = _Xtime2Sbox[62]
+ Xtime3Sbox[62] = _Xtime3Sbox[62]
+ Xtime2[62] = _Xtime2[62]
+ Xtime9[62] = _Xtime9[62]
+ XtimeB[62] = _XtimeB[62]
+ XtimeD[62] = _XtimeD[62]
+ XtimeE[62] = _XtimeE[62]
+ Sbox[63] = _Sbox[63]
+ InvSbox[63] = _InvSbox[63]
+ Xtime2Sbox[63] = _Xtime2Sbox[63]
+ Xtime3Sbox[63] = _Xtime3Sbox[63]
+ Xtime2[63] = _Xtime2[63]
+ Xtime9[63] = _Xtime9[63]
+ XtimeB[63] = _XtimeB[63]
+ XtimeD[63] = _XtimeD[63]
+ XtimeE[63] = _XtimeE[63]
+ Sbox[64] = _Sbox[64]
+ InvSbox[64] = _InvSbox[64]
+ Xtime2Sbox[64] = _Xtime2Sbox[64]
+ Xtime3Sbox[64] = _Xtime3Sbox[64]
+ Xtime2[64] = _Xtime2[64]
+ Xtime9[64] = _Xtime9[64]
+ XtimeB[64] = _XtimeB[64]
+ XtimeD[64] = _XtimeD[64]
+ XtimeE[64] = _XtimeE[64]
+ Sbox[65] = _Sbox[65]
+ InvSbox[65] = _InvSbox[65]
+ Xtime2Sbox[65] = _Xtime2Sbox[65]
+ Xtime3Sbox[65] = _Xtime3Sbox[65]
+ Xtime2[65] = _Xtime2[65]
+ Xtime9[65] = _Xtime9[65]
+ XtimeB[65] = _XtimeB[65]
+ XtimeD[65] = _XtimeD[65]
+ XtimeE[65] = _XtimeE[65]
+ Sbox[66] = _Sbox[66]
+ InvSbox[66] = _InvSbox[66]
+ Xtime2Sbox[66] = _Xtime2Sbox[66]
+ Xtime3Sbox[66] = _Xtime3Sbox[66]
+ Xtime2[66] = _Xtime2[66]
+ Xtime9[66] = _Xtime9[66]
+ XtimeB[66] = _XtimeB[66]
+ XtimeD[66] = _XtimeD[66]
+ XtimeE[66] = _XtimeE[66]
+ Sbox[67] = _Sbox[67]
+ InvSbox[67] = _InvSbox[67]
+ Xtime2Sbox[67] = _Xtime2Sbox[67]
+ Xtime3Sbox[67] = _Xtime3Sbox[67]
+ Xtime2[67] = _Xtime2[67]
+ Xtime9[67] = _Xtime9[67]
+ XtimeB[67] = _XtimeB[67]
+ XtimeD[67] = _XtimeD[67]
+ XtimeE[67] = _XtimeE[67]
+ Sbox[68] = _Sbox[68]
+ InvSbox[68] = _InvSbox[68]
+ Xtime2Sbox[68] = _Xtime2Sbox[68]
+ Xtime3Sbox[68] = _Xtime3Sbox[68]
+ Xtime2[68] = _Xtime2[68]
+ Xtime9[68] = _Xtime9[68]
+ XtimeB[68] = _XtimeB[68]
+ XtimeD[68] = _XtimeD[68]
+ XtimeE[68] = _XtimeE[68]
+ Sbox[69] = _Sbox[69]
+ InvSbox[69] = _InvSbox[69]
+ Xtime2Sbox[69] = _Xtime2Sbox[69]
+ Xtime3Sbox[69] = _Xtime3Sbox[69]
+ Xtime2[69] = _Xtime2[69]
+ Xtime9[69] = _Xtime9[69]
+ XtimeB[69] = _XtimeB[69]
+ XtimeD[69] = _XtimeD[69]
+ XtimeE[69] = _XtimeE[69]
+ Sbox[70] = _Sbox[70]
+ InvSbox[70] = _InvSbox[70]
+ Xtime2Sbox[70] = _Xtime2Sbox[70]
+ Xtime3Sbox[70] = _Xtime3Sbox[70]
+ Xtime2[70] = _Xtime2[70]
+ Xtime9[70] = _Xtime9[70]
+ XtimeB[70] = _XtimeB[70]
+ XtimeD[70] = _XtimeD[70]
+ XtimeE[70] = _XtimeE[70]
+ Sbox[71] = _Sbox[71]
+ InvSbox[71] = _InvSbox[71]
+ Xtime2Sbox[71] = _Xtime2Sbox[71]
+ Xtime3Sbox[71] = _Xtime3Sbox[71]
+ Xtime2[71] = _Xtime2[71]
+ Xtime9[71] = _Xtime9[71]
+ XtimeB[71] = _XtimeB[71]
+ XtimeD[71] = _XtimeD[71]
+ XtimeE[71] = _XtimeE[71]
+ Sbox[72] = _Sbox[72]
+ InvSbox[72] = _InvSbox[72]
+ Xtime2Sbox[72] = _Xtime2Sbox[72]
+ Xtime3Sbox[72] = _Xtime3Sbox[72]
+ Xtime2[72] = _Xtime2[72]
+ Xtime9[72] = _Xtime9[72]
+ XtimeB[72] = _XtimeB[72]
+ XtimeD[72] = _XtimeD[72]
+ XtimeE[72] = _XtimeE[72]
+ Sbox[73] = _Sbox[73]
+ InvSbox[73] = _InvSbox[73]
+ Xtime2Sbox[73] = _Xtime2Sbox[73]
+ Xtime3Sbox[73] = _Xtime3Sbox[73]
+ Xtime2[73] = _Xtime2[73]
+ Xtime9[73] = _Xtime9[73]
+ XtimeB[73] = _XtimeB[73]
+ XtimeD[73] = _XtimeD[73]
+ XtimeE[73] = _XtimeE[73]
+ Sbox[74] = _Sbox[74]
+ InvSbox[74] = _InvSbox[74]
+ Xtime2Sbox[74] = _Xtime2Sbox[74]
+ Xtime3Sbox[74] = _Xtime3Sbox[74]
+ Xtime2[74] = _Xtime2[74]
+ Xtime9[74] = _Xtime9[74]
+ XtimeB[74] = _XtimeB[74]
+ XtimeD[74] = _XtimeD[74]
+ XtimeE[74] = _XtimeE[74]
+ Sbox[75] = _Sbox[75]
+ InvSbox[75] = _InvSbox[75]
+ Xtime2Sbox[75] = _Xtime2Sbox[75]
+ Xtime3Sbox[75] = _Xtime3Sbox[75]
+ Xtime2[75] = _Xtime2[75]
+ Xtime9[75] = _Xtime9[75]
+ XtimeB[75] = _XtimeB[75]
+ XtimeD[75] = _XtimeD[75]
+ XtimeE[75] = _XtimeE[75]
+ Sbox[76] = _Sbox[76]
+ InvSbox[76] = _InvSbox[76]
+ Xtime2Sbox[76] = _Xtime2Sbox[76]
+ Xtime3Sbox[76] = _Xtime3Sbox[76]
+ Xtime2[76] = _Xtime2[76]
+ Xtime9[76] = _Xtime9[76]
+ XtimeB[76] = _XtimeB[76]
+ XtimeD[76] = _XtimeD[76]
+ XtimeE[76] = _XtimeE[76]
+ Sbox[77] = _Sbox[77]
+ InvSbox[77] = _InvSbox[77]
+ Xtime2Sbox[77] = _Xtime2Sbox[77]
+ Xtime3Sbox[77] = _Xtime3Sbox[77]
+ Xtime2[77] = _Xtime2[77]
+ Xtime9[77] = _Xtime9[77]
+ XtimeB[77] = _XtimeB[77]
+ XtimeD[77] = _XtimeD[77]
+ XtimeE[77] = _XtimeE[77]
+ Sbox[78] = _Sbox[78]
+ InvSbox[78] = _InvSbox[78]
+ Xtime2Sbox[78] = _Xtime2Sbox[78]
+ Xtime3Sbox[78] = _Xtime3Sbox[78]
+ Xtime2[78] = _Xtime2[78]
+ Xtime9[78] = _Xtime9[78]
+ XtimeB[78] = _XtimeB[78]
+ XtimeD[78] = _XtimeD[78]
+ XtimeE[78] = _XtimeE[78]
+ Sbox[79] = _Sbox[79]
+ InvSbox[79] = _InvSbox[79]
+ Xtime2Sbox[79] = _Xtime2Sbox[79]
+ Xtime3Sbox[79] = _Xtime3Sbox[79]
+ Xtime2[79] = _Xtime2[79]
+ Xtime9[79] = _Xtime9[79]
+ XtimeB[79] = _XtimeB[79]
+ XtimeD[79] = _XtimeD[79]
+ XtimeE[79] = _XtimeE[79]
+ Sbox[80] = _Sbox[80]
+ InvSbox[80] = _InvSbox[80]
+ Xtime2Sbox[80] = _Xtime2Sbox[80]
+ Xtime3Sbox[80] = _Xtime3Sbox[80]
+ Xtime2[80] = _Xtime2[80]
+ Xtime9[80] = _Xtime9[80]
+ XtimeB[80] = _XtimeB[80]
+ XtimeD[80] = _XtimeD[80]
+ XtimeE[80] = _XtimeE[80]
+ Sbox[81] = _Sbox[81]
+ InvSbox[81] = _InvSbox[81]
+ Xtime2Sbox[81] = _Xtime2Sbox[81]
+ Xtime3Sbox[81] = _Xtime3Sbox[81]
+ Xtime2[81] = _Xtime2[81]
+ Xtime9[81] = _Xtime9[81]
+ XtimeB[81] = _XtimeB[81]
+ XtimeD[81] = _XtimeD[81]
+ XtimeE[81] = _XtimeE[81]
+ Sbox[82] = _Sbox[82]
+ InvSbox[82] = _InvSbox[82]
+ Xtime2Sbox[82] = _Xtime2Sbox[82]
+ Xtime3Sbox[82] = _Xtime3Sbox[82]
+ Xtime2[82] = _Xtime2[82]
+ Xtime9[82] = _Xtime9[82]
+ XtimeB[82] = _XtimeB[82]
+ XtimeD[82] = _XtimeD[82]
+ XtimeE[82] = _XtimeE[82]
+ Sbox[83] = _Sbox[83]
+ InvSbox[83] = _InvSbox[83]
+ Xtime2Sbox[83] = _Xtime2Sbox[83]
+ Xtime3Sbox[83] = _Xtime3Sbox[83]
+ Xtime2[83] = _Xtime2[83]
+ Xtime9[83] = _Xtime9[83]
+ XtimeB[83] = _XtimeB[83]
+ XtimeD[83] = _XtimeD[83]
+ XtimeE[83] = _XtimeE[83]
+ Sbox[84] = _Sbox[84]
+ InvSbox[84] = _InvSbox[84]
+ Xtime2Sbox[84] = _Xtime2Sbox[84]
+ Xtime3Sbox[84] = _Xtime3Sbox[84]
+ Xtime2[84] = _Xtime2[84]
+ Xtime9[84] = _Xtime9[84]
+ XtimeB[84] = _XtimeB[84]
+ XtimeD[84] = _XtimeD[84]
+ XtimeE[84] = _XtimeE[84]
+ Sbox[85] = _Sbox[85]
+ InvSbox[85] = _InvSbox[85]
+ Xtime2Sbox[85] = _Xtime2Sbox[85]
+ Xtime3Sbox[85] = _Xtime3Sbox[85]
+ Xtime2[85] = _Xtime2[85]
+ Xtime9[85] = _Xtime9[85]
+ XtimeB[85] = _XtimeB[85]
+ XtimeD[85] = _XtimeD[85]
+ XtimeE[85] = _XtimeE[85]
+ Sbox[86] = _Sbox[86]
+ InvSbox[86] = _InvSbox[86]
+ Xtime2Sbox[86] = _Xtime2Sbox[86]
+ Xtime3Sbox[86] = _Xtime3Sbox[86]
+ Xtime2[86] = _Xtime2[86]
+ Xtime9[86] = _Xtime9[86]
+ XtimeB[86] = _XtimeB[86]
+ XtimeD[86] = _XtimeD[86]
+ XtimeE[86] = _XtimeE[86]
+ Sbox[87] = _Sbox[87]
+ InvSbox[87] = _InvSbox[87]
+ Xtime2Sbox[87] = _Xtime2Sbox[87]
+ Xtime3Sbox[87] = _Xtime3Sbox[87]
+ Xtime2[87] = _Xtime2[87]
+ Xtime9[87] = _Xtime9[87]
+ XtimeB[87] = _XtimeB[87]
+ XtimeD[87] = _XtimeD[87]
+ XtimeE[87] = _XtimeE[87]
+ Sbox[88] = _Sbox[88]
+ InvSbox[88] = _InvSbox[88]
+ Xtime2Sbox[88] = _Xtime2Sbox[88]
+ Xtime3Sbox[88] = _Xtime3Sbox[88]
+ Xtime2[88] = _Xtime2[88]
+ Xtime9[88] = _Xtime9[88]
+ XtimeB[88] = _XtimeB[88]
+ XtimeD[88] = _XtimeD[88]
+ XtimeE[88] = _XtimeE[88]
+ Sbox[89] = _Sbox[89]
+ InvSbox[89] = _InvSbox[89]
+ Xtime2Sbox[89] = _Xtime2Sbox[89]
+ Xtime3Sbox[89] = _Xtime3Sbox[89]
+ Xtime2[89] = _Xtime2[89]
+ Xtime9[89] = _Xtime9[89]
+ XtimeB[89] = _XtimeB[89]
+ XtimeD[89] = _XtimeD[89]
+ XtimeE[89] = _XtimeE[89]
+ Sbox[90] = _Sbox[90]
+ InvSbox[90] = _InvSbox[90]
+ Xtime2Sbox[90] = _Xtime2Sbox[90]
+ Xtime3Sbox[90] = _Xtime3Sbox[90]
+ Xtime2[90] = _Xtime2[90]
+ Xtime9[90] = _Xtime9[90]
+ XtimeB[90] = _XtimeB[90]
+ XtimeD[90] = _XtimeD[90]
+ XtimeE[90] = _XtimeE[90]
+ Sbox[91] = _Sbox[91]
+ InvSbox[91] = _InvSbox[91]
+ Xtime2Sbox[91] = _Xtime2Sbox[91]
+ Xtime3Sbox[91] = _Xtime3Sbox[91]
+ Xtime2[91] = _Xtime2[91]
+ Xtime9[91] = _Xtime9[91]
+ XtimeB[91] = _XtimeB[91]
+ XtimeD[91] = _XtimeD[91]
+ XtimeE[91] = _XtimeE[91]
+ Sbox[92] = _Sbox[92]
+ InvSbox[92] = _InvSbox[92]
+ Xtime2Sbox[92] = _Xtime2Sbox[92]
+ Xtime3Sbox[92] = _Xtime3Sbox[92]
+ Xtime2[92] = _Xtime2[92]
+ Xtime9[92] = _Xtime9[92]
+ XtimeB[92] = _XtimeB[92]
+ XtimeD[92] = _XtimeD[92]
+ XtimeE[92] = _XtimeE[92]
+ Sbox[93] = _Sbox[93]
+ InvSbox[93] = _InvSbox[93]
+ Xtime2Sbox[93] = _Xtime2Sbox[93]
+ Xtime3Sbox[93] = _Xtime3Sbox[93]
+ Xtime2[93] = _Xtime2[93]
+ Xtime9[93] = _Xtime9[93]
+ XtimeB[93] = _XtimeB[93]
+ XtimeD[93] = _XtimeD[93]
+ XtimeE[93] = _XtimeE[93]
+ Sbox[94] = _Sbox[94]
+ InvSbox[94] = _InvSbox[94]
+ Xtime2Sbox[94] = _Xtime2Sbox[94]
+ Xtime3Sbox[94] = _Xtime3Sbox[94]
+ Xtime2[94] = _Xtime2[94]
+ Xtime9[94] = _Xtime9[94]
+ XtimeB[94] = _XtimeB[94]
+ XtimeD[94] = _XtimeD[94]
+ XtimeE[94] = _XtimeE[94]
+ Sbox[95] = _Sbox[95]
+ InvSbox[95] = _InvSbox[95]
+ Xtime2Sbox[95] = _Xtime2Sbox[95]
+ Xtime3Sbox[95] = _Xtime3Sbox[95]
+ Xtime2[95] = _Xtime2[95]
+ Xtime9[95] = _Xtime9[95]
+ XtimeB[95] = _XtimeB[95]
+ XtimeD[95] = _XtimeD[95]
+ XtimeE[95] = _XtimeE[95]
+ Sbox[96] = _Sbox[96]
+ InvSbox[96] = _InvSbox[96]
+ Xtime2Sbox[96] = _Xtime2Sbox[96]
+ Xtime3Sbox[96] = _Xtime3Sbox[96]
+ Xtime2[96] = _Xtime2[96]
+ Xtime9[96] = _Xtime9[96]
+ XtimeB[96] = _XtimeB[96]
+ XtimeD[96] = _XtimeD[96]
+ XtimeE[96] = _XtimeE[96]
+ Sbox[97] = _Sbox[97]
+ InvSbox[97] = _InvSbox[97]
+ Xtime2Sbox[97] = _Xtime2Sbox[97]
+ Xtime3Sbox[97] = _Xtime3Sbox[97]
+ Xtime2[97] = _Xtime2[97]
+ Xtime9[97] = _Xtime9[97]
+ XtimeB[97] = _XtimeB[97]
+ XtimeD[97] = _XtimeD[97]
+ XtimeE[97] = _XtimeE[97]
+ Sbox[98] = _Sbox[98]
+ InvSbox[98] = _InvSbox[98]
+ Xtime2Sbox[98] = _Xtime2Sbox[98]
+ Xtime3Sbox[98] = _Xtime3Sbox[98]
+ Xtime2[98] = _Xtime2[98]
+ Xtime9[98] = _Xtime9[98]
+ XtimeB[98] = _XtimeB[98]
+ XtimeD[98] = _XtimeD[98]
+ XtimeE[98] = _XtimeE[98]
+ Sbox[99] = _Sbox[99]
+ InvSbox[99] = _InvSbox[99]
+ Xtime2Sbox[99] = _Xtime2Sbox[99]
+ Xtime3Sbox[99] = _Xtime3Sbox[99]
+ Xtime2[99] = _Xtime2[99]
+ Xtime9[99] = _Xtime9[99]
+ XtimeB[99] = _XtimeB[99]
+ XtimeD[99] = _XtimeD[99]
+ XtimeE[99] = _XtimeE[99]
+ Sbox[100] = _Sbox[100]
+ InvSbox[100] = _InvSbox[100]
+ Xtime2Sbox[100] = _Xtime2Sbox[100]
+ Xtime3Sbox[100] = _Xtime3Sbox[100]
+ Xtime2[100] = _Xtime2[100]
+ Xtime9[100] = _Xtime9[100]
+ XtimeB[100] = _XtimeB[100]
+ XtimeD[100] = _XtimeD[100]
+ XtimeE[100] = _XtimeE[100]
+ Sbox[101] = _Sbox[101]
+ InvSbox[101] = _InvSbox[101]
+ Xtime2Sbox[101] = _Xtime2Sbox[101]
+ Xtime3Sbox[101] = _Xtime3Sbox[101]
+ Xtime2[101] = _Xtime2[101]
+ Xtime9[101] = _Xtime9[101]
+ XtimeB[101] = _XtimeB[101]
+ XtimeD[101] = _XtimeD[101]
+ XtimeE[101] = _XtimeE[101]
+ Sbox[102] = _Sbox[102]
+ InvSbox[102] = _InvSbox[102]
+ Xtime2Sbox[102] = _Xtime2Sbox[102]
+ Xtime3Sbox[102] = _Xtime3Sbox[102]
+ Xtime2[102] = _Xtime2[102]
+ Xtime9[102] = _Xtime9[102]
+ XtimeB[102] = _XtimeB[102]
+ XtimeD[102] = _XtimeD[102]
+ XtimeE[102] = _XtimeE[102]
+ Sbox[103] = _Sbox[103]
+ InvSbox[103] = _InvSbox[103]
+ Xtime2Sbox[103] = _Xtime2Sbox[103]
+ Xtime3Sbox[103] = _Xtime3Sbox[103]
+ Xtime2[103] = _Xtime2[103]
+ Xtime9[103] = _Xtime9[103]
+ XtimeB[103] = _XtimeB[103]
+ XtimeD[103] = _XtimeD[103]
+ XtimeE[103] = _XtimeE[103]
+ Sbox[104] = _Sbox[104]
+ InvSbox[104] = _InvSbox[104]
+ Xtime2Sbox[104] = _Xtime2Sbox[104]
+ Xtime3Sbox[104] = _Xtime3Sbox[104]
+ Xtime2[104] = _Xtime2[104]
+ Xtime9[104] = _Xtime9[104]
+ XtimeB[104] = _XtimeB[104]
+ XtimeD[104] = _XtimeD[104]
+ XtimeE[104] = _XtimeE[104]
+ Sbox[105] = _Sbox[105]
+ InvSbox[105] = _InvSbox[105]
+ Xtime2Sbox[105] = _Xtime2Sbox[105]
+ Xtime3Sbox[105] = _Xtime3Sbox[105]
+ Xtime2[105] = _Xtime2[105]
+ Xtime9[105] = _Xtime9[105]
+ XtimeB[105] = _XtimeB[105]
+ XtimeD[105] = _XtimeD[105]
+ XtimeE[105] = _XtimeE[105]
+ Sbox[106] = _Sbox[106]
+ InvSbox[106] = _InvSbox[106]
+ Xtime2Sbox[106] = _Xtime2Sbox[106]
+ Xtime3Sbox[106] = _Xtime3Sbox[106]
+ Xtime2[106] = _Xtime2[106]
+ Xtime9[106] = _Xtime9[106]
+ XtimeB[106] = _XtimeB[106]
+ XtimeD[106] = _XtimeD[106]
+ XtimeE[106] = _XtimeE[106]
+ Sbox[107] = _Sbox[107]
+ InvSbox[107] = _InvSbox[107]
+ Xtime2Sbox[107] = _Xtime2Sbox[107]
+ Xtime3Sbox[107] = _Xtime3Sbox[107]
+ Xtime2[107] = _Xtime2[107]
+ Xtime9[107] = _Xtime9[107]
+ XtimeB[107] = _XtimeB[107]
+ XtimeD[107] = _XtimeD[107]
+ XtimeE[107] = _XtimeE[107]
+ Sbox[108] = _Sbox[108]
+ InvSbox[108] = _InvSbox[108]
+ Xtime2Sbox[108] = _Xtime2Sbox[108]
+ Xtime3Sbox[108] = _Xtime3Sbox[108]
+ Xtime2[108] = _Xtime2[108]
+ Xtime9[108] = _Xtime9[108]
+ XtimeB[108] = _XtimeB[108]
+ XtimeD[108] = _XtimeD[108]
+ XtimeE[108] = _XtimeE[108]
+ Sbox[109] = _Sbox[109]
+ InvSbox[109] = _InvSbox[109]
+ Xtime2Sbox[109] = _Xtime2Sbox[109]
+ Xtime3Sbox[109] = _Xtime3Sbox[109]
+ Xtime2[109] = _Xtime2[109]
+ Xtime9[109] = _Xtime9[109]
+ XtimeB[109] = _XtimeB[109]
+ XtimeD[109] = _XtimeD[109]
+ XtimeE[109] = _XtimeE[109]
+ Sbox[110] = _Sbox[110]
+ InvSbox[110] = _InvSbox[110]
+ Xtime2Sbox[110] = _Xtime2Sbox[110]
+ Xtime3Sbox[110] = _Xtime3Sbox[110]
+ Xtime2[110] = _Xtime2[110]
+ Xtime9[110] = _Xtime9[110]
+ XtimeB[110] = _XtimeB[110]
+ XtimeD[110] = _XtimeD[110]
+ XtimeE[110] = _XtimeE[110]
+ Sbox[111] = _Sbox[111]
+ InvSbox[111] = _InvSbox[111]
+ Xtime2Sbox[111] = _Xtime2Sbox[111]
+ Xtime3Sbox[111] = _Xtime3Sbox[111]
+ Xtime2[111] = _Xtime2[111]
+ Xtime9[111] = _Xtime9[111]
+ XtimeB[111] = _XtimeB[111]
+ XtimeD[111] = _XtimeD[111]
+ XtimeE[111] = _XtimeE[111]
+ Sbox[112] = _Sbox[112]
+ InvSbox[112] = _InvSbox[112]
+ Xtime2Sbox[112] = _Xtime2Sbox[112]
+ Xtime3Sbox[112] = _Xtime3Sbox[112]
+ Xtime2[112] = _Xtime2[112]
+ Xtime9[112] = _Xtime9[112]
+ XtimeB[112] = _XtimeB[112]
+ XtimeD[112] = _XtimeD[112]
+ XtimeE[112] = _XtimeE[112]
+ Sbox[113] = _Sbox[113]
+ InvSbox[113] = _InvSbox[113]
+ Xtime2Sbox[113] = _Xtime2Sbox[113]
+ Xtime3Sbox[113] = _Xtime3Sbox[113]
+ Xtime2[113] = _Xtime2[113]
+ Xtime9[113] = _Xtime9[113]
+ XtimeB[113] = _XtimeB[113]
+ XtimeD[113] = _XtimeD[113]
+ XtimeE[113] = _XtimeE[113]
+ Sbox[114] = _Sbox[114]
+ InvSbox[114] = _InvSbox[114]
+ Xtime2Sbox[114] = _Xtime2Sbox[114]
+ Xtime3Sbox[114] = _Xtime3Sbox[114]
+ Xtime2[114] = _Xtime2[114]
+ Xtime9[114] = _Xtime9[114]
+ XtimeB[114] = _XtimeB[114]
+ XtimeD[114] = _XtimeD[114]
+ XtimeE[114] = _XtimeE[114]
+ Sbox[115] = _Sbox[115]
+ InvSbox[115] = _InvSbox[115]
+ Xtime2Sbox[115] = _Xtime2Sbox[115]
+ Xtime3Sbox[115] = _Xtime3Sbox[115]
+ Xtime2[115] = _Xtime2[115]
+ Xtime9[115] = _Xtime9[115]
+ XtimeB[115] = _XtimeB[115]
+ XtimeD[115] = _XtimeD[115]
+ XtimeE[115] = _XtimeE[115]
+ Sbox[116] = _Sbox[116]
+ InvSbox[116] = _InvSbox[116]
+ Xtime2Sbox[116] = _Xtime2Sbox[116]
+ Xtime3Sbox[116] = _Xtime3Sbox[116]
+ Xtime2[116] = _Xtime2[116]
+ Xtime9[116] = _Xtime9[116]
+ XtimeB[116] = _XtimeB[116]
+ XtimeD[116] = _XtimeD[116]
+ XtimeE[116] = _XtimeE[116]
+ Sbox[117] = _Sbox[117]
+ InvSbox[117] = _InvSbox[117]
+ Xtime2Sbox[117] = _Xtime2Sbox[117]
+ Xtime3Sbox[117] = _Xtime3Sbox[117]
+ Xtime2[117] = _Xtime2[117]
+ Xtime9[117] = _Xtime9[117]
+ XtimeB[117] = _XtimeB[117]
+ XtimeD[117] = _XtimeD[117]
+ XtimeE[117] = _XtimeE[117]
+ Sbox[118] = _Sbox[118]
+ InvSbox[118] = _InvSbox[118]
+ Xtime2Sbox[118] = _Xtime2Sbox[118]
+ Xtime3Sbox[118] = _Xtime3Sbox[118]
+ Xtime2[118] = _Xtime2[118]
+ Xtime9[118] = _Xtime9[118]
+ XtimeB[118] = _XtimeB[118]
+ XtimeD[118] = _XtimeD[118]
+ XtimeE[118] = _XtimeE[118]
+ Sbox[119] = _Sbox[119]
+ InvSbox[119] = _InvSbox[119]
+ Xtime2Sbox[119] = _Xtime2Sbox[119]
+ Xtime3Sbox[119] = _Xtime3Sbox[119]
+ Xtime2[119] = _Xtime2[119]
+ Xtime9[119] = _Xtime9[119]
+ XtimeB[119] = _XtimeB[119]
+ XtimeD[119] = _XtimeD[119]
+ XtimeE[119] = _XtimeE[119]
+ Sbox[120] = _Sbox[120]
+ InvSbox[120] = _InvSbox[120]
+ Xtime2Sbox[120] = _Xtime2Sbox[120]
+ Xtime3Sbox[120] = _Xtime3Sbox[120]
+ Xtime2[120] = _Xtime2[120]
+ Xtime9[120] = _Xtime9[120]
+ XtimeB[120] = _XtimeB[120]
+ XtimeD[120] = _XtimeD[120]
+ XtimeE[120] = _XtimeE[120]
+ Sbox[121] = _Sbox[121]
+ InvSbox[121] = _InvSbox[121]
+ Xtime2Sbox[121] = _Xtime2Sbox[121]
+ Xtime3Sbox[121] = _Xtime3Sbox[121]
+ Xtime2[121] = _Xtime2[121]
+ Xtime9[121] = _Xtime9[121]
+ XtimeB[121] = _XtimeB[121]
+ XtimeD[121] = _XtimeD[121]
+ XtimeE[121] = _XtimeE[121]
+ Sbox[122] = _Sbox[122]
+ InvSbox[122] = _InvSbox[122]
+ Xtime2Sbox[122] = _Xtime2Sbox[122]
+ Xtime3Sbox[122] = _Xtime3Sbox[122]
+ Xtime2[122] = _Xtime2[122]
+ Xtime9[122] = _Xtime9[122]
+ XtimeB[122] = _XtimeB[122]
+ XtimeD[122] = _XtimeD[122]
+ XtimeE[122] = _XtimeE[122]
+ Sbox[123] = _Sbox[123]
+ InvSbox[123] = _InvSbox[123]
+ Xtime2Sbox[123] = _Xtime2Sbox[123]
+ Xtime3Sbox[123] = _Xtime3Sbox[123]
+ Xtime2[123] = _Xtime2[123]
+ Xtime9[123] = _Xtime9[123]
+ XtimeB[123] = _XtimeB[123]
+ XtimeD[123] = _XtimeD[123]
+ XtimeE[123] = _XtimeE[123]
+ Sbox[124] = _Sbox[124]
+ InvSbox[124] = _InvSbox[124]
+ Xtime2Sbox[124] = _Xtime2Sbox[124]
+ Xtime3Sbox[124] = _Xtime3Sbox[124]
+ Xtime2[124] = _Xtime2[124]
+ Xtime9[124] = _Xtime9[124]
+ XtimeB[124] = _XtimeB[124]
+ XtimeD[124] = _XtimeD[124]
+ XtimeE[124] = _XtimeE[124]
+ Sbox[125] = _Sbox[125]
+ InvSbox[125] = _InvSbox[125]
+ Xtime2Sbox[125] = _Xtime2Sbox[125]
+ Xtime3Sbox[125] = _Xtime3Sbox[125]
+ Xtime2[125] = _Xtime2[125]
+ Xtime9[125] = _Xtime9[125]
+ XtimeB[125] = _XtimeB[125]
+ XtimeD[125] = _XtimeD[125]
+ XtimeE[125] = _XtimeE[125]
+ Sbox[126] = _Sbox[126]
+ InvSbox[126] = _InvSbox[126]
+ Xtime2Sbox[126] = _Xtime2Sbox[126]
+ Xtime3Sbox[126] = _Xtime3Sbox[126]
+ Xtime2[126] = _Xtime2[126]
+ Xtime9[126] = _Xtime9[126]
+ XtimeB[126] = _XtimeB[126]
+ XtimeD[126] = _XtimeD[126]
+ XtimeE[126] = _XtimeE[126]
+ Sbox[127] = _Sbox[127]
+ InvSbox[127] = _InvSbox[127]
+ Xtime2Sbox[127] = _Xtime2Sbox[127]
+ Xtime3Sbox[127] = _Xtime3Sbox[127]
+ Xtime2[127] = _Xtime2[127]
+ Xtime9[127] = _Xtime9[127]
+ XtimeB[127] = _XtimeB[127]
+ XtimeD[127] = _XtimeD[127]
+ XtimeE[127] = _XtimeE[127]
+ Sbox[128] = _Sbox[128]
+ InvSbox[128] = _InvSbox[128]
+ Xtime2Sbox[128] = _Xtime2Sbox[128]
+ Xtime3Sbox[128] = _Xtime3Sbox[128]
+ Xtime2[128] = _Xtime2[128]
+ Xtime9[128] = _Xtime9[128]
+ XtimeB[128] = _XtimeB[128]
+ XtimeD[128] = _XtimeD[128]
+ XtimeE[128] = _XtimeE[128]
+ Sbox[129] = _Sbox[129]
+ InvSbox[129] = _InvSbox[129]
+ Xtime2Sbox[129] = _Xtime2Sbox[129]
+ Xtime3Sbox[129] = _Xtime3Sbox[129]
+ Xtime2[129] = _Xtime2[129]
+ Xtime9[129] = _Xtime9[129]
+ XtimeB[129] = _XtimeB[129]
+ XtimeD[129] = _XtimeD[129]
+ XtimeE[129] = _XtimeE[129]
+ Sbox[130] = _Sbox[130]
+ InvSbox[130] = _InvSbox[130]
+ Xtime2Sbox[130] = _Xtime2Sbox[130]
+ Xtime3Sbox[130] = _Xtime3Sbox[130]
+ Xtime2[130] = _Xtime2[130]
+ Xtime9[130] = _Xtime9[130]
+ XtimeB[130] = _XtimeB[130]
+ XtimeD[130] = _XtimeD[130]
+ XtimeE[130] = _XtimeE[130]
+ Sbox[131] = _Sbox[131]
+ InvSbox[131] = _InvSbox[131]
+ Xtime2Sbox[131] = _Xtime2Sbox[131]
+ Xtime3Sbox[131] = _Xtime3Sbox[131]
+ Xtime2[131] = _Xtime2[131]
+ Xtime9[131] = _Xtime9[131]
+ XtimeB[131] = _XtimeB[131]
+ XtimeD[131] = _XtimeD[131]
+ XtimeE[131] = _XtimeE[131]
+ Sbox[132] = _Sbox[132]
+ InvSbox[132] = _InvSbox[132]
+ Xtime2Sbox[132] = _Xtime2Sbox[132]
+ Xtime3Sbox[132] = _Xtime3Sbox[132]
+ Xtime2[132] = _Xtime2[132]
+ Xtime9[132] = _Xtime9[132]
+ XtimeB[132] = _XtimeB[132]
+ XtimeD[132] = _XtimeD[132]
+ XtimeE[132] = _XtimeE[132]
+ Sbox[133] = _Sbox[133]
+ InvSbox[133] = _InvSbox[133]
+ Xtime2Sbox[133] = _Xtime2Sbox[133]
+ Xtime3Sbox[133] = _Xtime3Sbox[133]
+ Xtime2[133] = _Xtime2[133]
+ Xtime9[133] = _Xtime9[133]
+ XtimeB[133] = _XtimeB[133]
+ XtimeD[133] = _XtimeD[133]
+ XtimeE[133] = _XtimeE[133]
+ Sbox[134] = _Sbox[134]
+ InvSbox[134] = _InvSbox[134]
+ Xtime2Sbox[134] = _Xtime2Sbox[134]
+ Xtime3Sbox[134] = _Xtime3Sbox[134]
+ Xtime2[134] = _Xtime2[134]
+ Xtime9[134] = _Xtime9[134]
+ XtimeB[134] = _XtimeB[134]
+ XtimeD[134] = _XtimeD[134]
+ XtimeE[134] = _XtimeE[134]
+ Sbox[135] = _Sbox[135]
+ InvSbox[135] = _InvSbox[135]
+ Xtime2Sbox[135] = _Xtime2Sbox[135]
+ Xtime3Sbox[135] = _Xtime3Sbox[135]
+ Xtime2[135] = _Xtime2[135]
+ Xtime9[135] = _Xtime9[135]
+ XtimeB[135] = _XtimeB[135]
+ XtimeD[135] = _XtimeD[135]
+ XtimeE[135] = _XtimeE[135]
+ Sbox[136] = _Sbox[136]
+ InvSbox[136] = _InvSbox[136]
+ Xtime2Sbox[136] = _Xtime2Sbox[136]
+ Xtime3Sbox[136] = _Xtime3Sbox[136]
+ Xtime2[136] = _Xtime2[136]
+ Xtime9[136] = _Xtime9[136]
+ XtimeB[136] = _XtimeB[136]
+ XtimeD[136] = _XtimeD[136]
+ XtimeE[136] = _XtimeE[136]
+ Sbox[137] = _Sbox[137]
+ InvSbox[137] = _InvSbox[137]
+ Xtime2Sbox[137] = _Xtime2Sbox[137]
+ Xtime3Sbox[137] = _Xtime3Sbox[137]
+ Xtime2[137] = _Xtime2[137]
+ Xtime9[137] = _Xtime9[137]
+ XtimeB[137] = _XtimeB[137]
+ XtimeD[137] = _XtimeD[137]
+ XtimeE[137] = _XtimeE[137]
+ Sbox[138] = _Sbox[138]
+ InvSbox[138] = _InvSbox[138]
+ Xtime2Sbox[138] = _Xtime2Sbox[138]
+ Xtime3Sbox[138] = _Xtime3Sbox[138]
+ Xtime2[138] = _Xtime2[138]
+ Xtime9[138] = _Xtime9[138]
+ XtimeB[138] = _XtimeB[138]
+ XtimeD[138] = _XtimeD[138]
+ XtimeE[138] = _XtimeE[138]
+ Sbox[139] = _Sbox[139]
+ InvSbox[139] = _InvSbox[139]
+ Xtime2Sbox[139] = _Xtime2Sbox[139]
+ Xtime3Sbox[139] = _Xtime3Sbox[139]
+ Xtime2[139] = _Xtime2[139]
+ Xtime9[139] = _Xtime9[139]
+ XtimeB[139] = _XtimeB[139]
+ XtimeD[139] = _XtimeD[139]
+ XtimeE[139] = _XtimeE[139]
+ Sbox[140] = _Sbox[140]
+ InvSbox[140] = _InvSbox[140]
+ Xtime2Sbox[140] = _Xtime2Sbox[140]
+ Xtime3Sbox[140] = _Xtime3Sbox[140]
+ Xtime2[140] = _Xtime2[140]
+ Xtime9[140] = _Xtime9[140]
+ XtimeB[140] = _XtimeB[140]
+ XtimeD[140] = _XtimeD[140]
+ XtimeE[140] = _XtimeE[140]
+ Sbox[141] = _Sbox[141]
+ InvSbox[141] = _InvSbox[141]
+ Xtime2Sbox[141] = _Xtime2Sbox[141]
+ Xtime3Sbox[141] = _Xtime3Sbox[141]
+ Xtime2[141] = _Xtime2[141]
+ Xtime9[141] = _Xtime9[141]
+ XtimeB[141] = _XtimeB[141]
+ XtimeD[141] = _XtimeD[141]
+ XtimeE[141] = _XtimeE[141]
+ Sbox[142] = _Sbox[142]
+ InvSbox[142] = _InvSbox[142]
+ Xtime2Sbox[142] = _Xtime2Sbox[142]
+ Xtime3Sbox[142] = _Xtime3Sbox[142]
+ Xtime2[142] = _Xtime2[142]
+ Xtime9[142] = _Xtime9[142]
+ XtimeB[142] = _XtimeB[142]
+ XtimeD[142] = _XtimeD[142]
+ XtimeE[142] = _XtimeE[142]
+ Sbox[143] = _Sbox[143]
+ InvSbox[143] = _InvSbox[143]
+ Xtime2Sbox[143] = _Xtime2Sbox[143]
+ Xtime3Sbox[143] = _Xtime3Sbox[143]
+ Xtime2[143] = _Xtime2[143]
+ Xtime9[143] = _Xtime9[143]
+ XtimeB[143] = _XtimeB[143]
+ XtimeD[143] = _XtimeD[143]
+ XtimeE[143] = _XtimeE[143]
+ Sbox[144] = _Sbox[144]
+ InvSbox[144] = _InvSbox[144]
+ Xtime2Sbox[144] = _Xtime2Sbox[144]
+ Xtime3Sbox[144] = _Xtime3Sbox[144]
+ Xtime2[144] = _Xtime2[144]
+ Xtime9[144] = _Xtime9[144]
+ XtimeB[144] = _XtimeB[144]
+ XtimeD[144] = _XtimeD[144]
+ XtimeE[144] = _XtimeE[144]
+ Sbox[145] = _Sbox[145]
+ InvSbox[145] = _InvSbox[145]
+ Xtime2Sbox[145] = _Xtime2Sbox[145]
+ Xtime3Sbox[145] = _Xtime3Sbox[145]
+ Xtime2[145] = _Xtime2[145]
+ Xtime9[145] = _Xtime9[145]
+ XtimeB[145] = _XtimeB[145]
+ XtimeD[145] = _XtimeD[145]
+ XtimeE[145] = _XtimeE[145]
+ Sbox[146] = _Sbox[146]
+ InvSbox[146] = _InvSbox[146]
+ Xtime2Sbox[146] = _Xtime2Sbox[146]
+ Xtime3Sbox[146] = _Xtime3Sbox[146]
+ Xtime2[146] = _Xtime2[146]
+ Xtime9[146] = _Xtime9[146]
+ XtimeB[146] = _XtimeB[146]
+ XtimeD[146] = _XtimeD[146]
+ XtimeE[146] = _XtimeE[146]
+ Sbox[147] = _Sbox[147]
+ InvSbox[147] = _InvSbox[147]
+ Xtime2Sbox[147] = _Xtime2Sbox[147]
+ Xtime3Sbox[147] = _Xtime3Sbox[147]
+ Xtime2[147] = _Xtime2[147]
+ Xtime9[147] = _Xtime9[147]
+ XtimeB[147] = _XtimeB[147]
+ XtimeD[147] = _XtimeD[147]
+ XtimeE[147] = _XtimeE[147]
+ Sbox[148] = _Sbox[148]
+ InvSbox[148] = _InvSbox[148]
+ Xtime2Sbox[148] = _Xtime2Sbox[148]
+ Xtime3Sbox[148] = _Xtime3Sbox[148]
+ Xtime2[148] = _Xtime2[148]
+ Xtime9[148] = _Xtime9[148]
+ XtimeB[148] = _XtimeB[148]
+ XtimeD[148] = _XtimeD[148]
+ XtimeE[148] = _XtimeE[148]
+ Sbox[149] = _Sbox[149]
+ InvSbox[149] = _InvSbox[149]
+ Xtime2Sbox[149] = _Xtime2Sbox[149]
+ Xtime3Sbox[149] = _Xtime3Sbox[149]
+ Xtime2[149] = _Xtime2[149]
+ Xtime9[149] = _Xtime9[149]
+ XtimeB[149] = _XtimeB[149]
+ XtimeD[149] = _XtimeD[149]
+ XtimeE[149] = _XtimeE[149]
+ Sbox[150] = _Sbox[150]
+ InvSbox[150] = _InvSbox[150]
+ Xtime2Sbox[150] = _Xtime2Sbox[150]
+ Xtime3Sbox[150] = _Xtime3Sbox[150]
+ Xtime2[150] = _Xtime2[150]
+ Xtime9[150] = _Xtime9[150]
+ XtimeB[150] = _XtimeB[150]
+ XtimeD[150] = _XtimeD[150]
+ XtimeE[150] = _XtimeE[150]
+ Sbox[151] = _Sbox[151]
+ InvSbox[151] = _InvSbox[151]
+ Xtime2Sbox[151] = _Xtime2Sbox[151]
+ Xtime3Sbox[151] = _Xtime3Sbox[151]
+ Xtime2[151] = _Xtime2[151]
+ Xtime9[151] = _Xtime9[151]
+ XtimeB[151] = _XtimeB[151]
+ XtimeD[151] = _XtimeD[151]
+ XtimeE[151] = _XtimeE[151]
+ Sbox[152] = _Sbox[152]
+ InvSbox[152] = _InvSbox[152]
+ Xtime2Sbox[152] = _Xtime2Sbox[152]
+ Xtime3Sbox[152] = _Xtime3Sbox[152]
+ Xtime2[152] = _Xtime2[152]
+ Xtime9[152] = _Xtime9[152]
+ XtimeB[152] = _XtimeB[152]
+ XtimeD[152] = _XtimeD[152]
+ XtimeE[152] = _XtimeE[152]
+ Sbox[153] = _Sbox[153]
+ InvSbox[153] = _InvSbox[153]
+ Xtime2Sbox[153] = _Xtime2Sbox[153]
+ Xtime3Sbox[153] = _Xtime3Sbox[153]
+ Xtime2[153] = _Xtime2[153]
+ Xtime9[153] = _Xtime9[153]
+ XtimeB[153] = _XtimeB[153]
+ XtimeD[153] = _XtimeD[153]
+ XtimeE[153] = _XtimeE[153]
+ Sbox[154] = _Sbox[154]
+ InvSbox[154] = _InvSbox[154]
+ Xtime2Sbox[154] = _Xtime2Sbox[154]
+ Xtime3Sbox[154] = _Xtime3Sbox[154]
+ Xtime2[154] = _Xtime2[154]
+ Xtime9[154] = _Xtime9[154]
+ XtimeB[154] = _XtimeB[154]
+ XtimeD[154] = _XtimeD[154]
+ XtimeE[154] = _XtimeE[154]
+ Sbox[155] = _Sbox[155]
+ InvSbox[155] = _InvSbox[155]
+ Xtime2Sbox[155] = _Xtime2Sbox[155]
+ Xtime3Sbox[155] = _Xtime3Sbox[155]
+ Xtime2[155] = _Xtime2[155]
+ Xtime9[155] = _Xtime9[155]
+ XtimeB[155] = _XtimeB[155]
+ XtimeD[155] = _XtimeD[155]
+ XtimeE[155] = _XtimeE[155]
+ Sbox[156] = _Sbox[156]
+ InvSbox[156] = _InvSbox[156]
+ Xtime2Sbox[156] = _Xtime2Sbox[156]
+ Xtime3Sbox[156] = _Xtime3Sbox[156]
+ Xtime2[156] = _Xtime2[156]
+ Xtime9[156] = _Xtime9[156]
+ XtimeB[156] = _XtimeB[156]
+ XtimeD[156] = _XtimeD[156]
+ XtimeE[156] = _XtimeE[156]
+ Sbox[157] = _Sbox[157]
+ InvSbox[157] = _InvSbox[157]
+ Xtime2Sbox[157] = _Xtime2Sbox[157]
+ Xtime3Sbox[157] = _Xtime3Sbox[157]
+ Xtime2[157] = _Xtime2[157]
+ Xtime9[157] = _Xtime9[157]
+ XtimeB[157] = _XtimeB[157]
+ XtimeD[157] = _XtimeD[157]
+ XtimeE[157] = _XtimeE[157]
+ Sbox[158] = _Sbox[158]
+ InvSbox[158] = _InvSbox[158]
+ Xtime2Sbox[158] = _Xtime2Sbox[158]
+ Xtime3Sbox[158] = _Xtime3Sbox[158]
+ Xtime2[158] = _Xtime2[158]
+ Xtime9[158] = _Xtime9[158]
+ XtimeB[158] = _XtimeB[158]
+ XtimeD[158] = _XtimeD[158]
+ XtimeE[158] = _XtimeE[158]
+ Sbox[159] = _Sbox[159]
+ InvSbox[159] = _InvSbox[159]
+ Xtime2Sbox[159] = _Xtime2Sbox[159]
+ Xtime3Sbox[159] = _Xtime3Sbox[159]
+ Xtime2[159] = _Xtime2[159]
+ Xtime9[159] = _Xtime9[159]
+ XtimeB[159] = _XtimeB[159]
+ XtimeD[159] = _XtimeD[159]
+ XtimeE[159] = _XtimeE[159]
+ Sbox[160] = _Sbox[160]
+ InvSbox[160] = _InvSbox[160]
+ Xtime2Sbox[160] = _Xtime2Sbox[160]
+ Xtime3Sbox[160] = _Xtime3Sbox[160]
+ Xtime2[160] = _Xtime2[160]
+ Xtime9[160] = _Xtime9[160]
+ XtimeB[160] = _XtimeB[160]
+ XtimeD[160] = _XtimeD[160]
+ XtimeE[160] = _XtimeE[160]
+ Sbox[161] = _Sbox[161]
+ InvSbox[161] = _InvSbox[161]
+ Xtime2Sbox[161] = _Xtime2Sbox[161]
+ Xtime3Sbox[161] = _Xtime3Sbox[161]
+ Xtime2[161] = _Xtime2[161]
+ Xtime9[161] = _Xtime9[161]
+ XtimeB[161] = _XtimeB[161]
+ XtimeD[161] = _XtimeD[161]
+ XtimeE[161] = _XtimeE[161]
+ Sbox[162] = _Sbox[162]
+ InvSbox[162] = _InvSbox[162]
+ Xtime2Sbox[162] = _Xtime2Sbox[162]
+ Xtime3Sbox[162] = _Xtime3Sbox[162]
+ Xtime2[162] = _Xtime2[162]
+ Xtime9[162] = _Xtime9[162]
+ XtimeB[162] = _XtimeB[162]
+ XtimeD[162] = _XtimeD[162]
+ XtimeE[162] = _XtimeE[162]
+ Sbox[163] = _Sbox[163]
+ InvSbox[163] = _InvSbox[163]
+ Xtime2Sbox[163] = _Xtime2Sbox[163]
+ Xtime3Sbox[163] = _Xtime3Sbox[163]
+ Xtime2[163] = _Xtime2[163]
+ Xtime9[163] = _Xtime9[163]
+ XtimeB[163] = _XtimeB[163]
+ XtimeD[163] = _XtimeD[163]
+ XtimeE[163] = _XtimeE[163]
+ Sbox[164] = _Sbox[164]
+ InvSbox[164] = _InvSbox[164]
+ Xtime2Sbox[164] = _Xtime2Sbox[164]
+ Xtime3Sbox[164] = _Xtime3Sbox[164]
+ Xtime2[164] = _Xtime2[164]
+ Xtime9[164] = _Xtime9[164]
+ XtimeB[164] = _XtimeB[164]
+ XtimeD[164] = _XtimeD[164]
+ XtimeE[164] = _XtimeE[164]
+ Sbox[165] = _Sbox[165]
+ InvSbox[165] = _InvSbox[165]
+ Xtime2Sbox[165] = _Xtime2Sbox[165]
+ Xtime3Sbox[165] = _Xtime3Sbox[165]
+ Xtime2[165] = _Xtime2[165]
+ Xtime9[165] = _Xtime9[165]
+ XtimeB[165] = _XtimeB[165]
+ XtimeD[165] = _XtimeD[165]
+ XtimeE[165] = _XtimeE[165]
+ Sbox[166] = _Sbox[166]
+ InvSbox[166] = _InvSbox[166]
+ Xtime2Sbox[166] = _Xtime2Sbox[166]
+ Xtime3Sbox[166] = _Xtime3Sbox[166]
+ Xtime2[166] = _Xtime2[166]
+ Xtime9[166] = _Xtime9[166]
+ XtimeB[166] = _XtimeB[166]
+ XtimeD[166] = _XtimeD[166]
+ XtimeE[166] = _XtimeE[166]
+ Sbox[167] = _Sbox[167]
+ InvSbox[167] = _InvSbox[167]
+ Xtime2Sbox[167] = _Xtime2Sbox[167]
+ Xtime3Sbox[167] = _Xtime3Sbox[167]
+ Xtime2[167] = _Xtime2[167]
+ Xtime9[167] = _Xtime9[167]
+ XtimeB[167] = _XtimeB[167]
+ XtimeD[167] = _XtimeD[167]
+ XtimeE[167] = _XtimeE[167]
+ Sbox[168] = _Sbox[168]
+ InvSbox[168] = _InvSbox[168]
+ Xtime2Sbox[168] = _Xtime2Sbox[168]
+ Xtime3Sbox[168] = _Xtime3Sbox[168]
+ Xtime2[168] = _Xtime2[168]
+ Xtime9[168] = _Xtime9[168]
+ XtimeB[168] = _XtimeB[168]
+ XtimeD[168] = _XtimeD[168]
+ XtimeE[168] = _XtimeE[168]
+ Sbox[169] = _Sbox[169]
+ InvSbox[169] = _InvSbox[169]
+ Xtime2Sbox[169] = _Xtime2Sbox[169]
+ Xtime3Sbox[169] = _Xtime3Sbox[169]
+ Xtime2[169] = _Xtime2[169]
+ Xtime9[169] = _Xtime9[169]
+ XtimeB[169] = _XtimeB[169]
+ XtimeD[169] = _XtimeD[169]
+ XtimeE[169] = _XtimeE[169]
+ Sbox[170] = _Sbox[170]
+ InvSbox[170] = _InvSbox[170]
+ Xtime2Sbox[170] = _Xtime2Sbox[170]
+ Xtime3Sbox[170] = _Xtime3Sbox[170]
+ Xtime2[170] = _Xtime2[170]
+ Xtime9[170] = _Xtime9[170]
+ XtimeB[170] = _XtimeB[170]
+ XtimeD[170] = _XtimeD[170]
+ XtimeE[170] = _XtimeE[170]
+ Sbox[171] = _Sbox[171]
+ InvSbox[171] = _InvSbox[171]
+ Xtime2Sbox[171] = _Xtime2Sbox[171]
+ Xtime3Sbox[171] = _Xtime3Sbox[171]
+ Xtime2[171] = _Xtime2[171]
+ Xtime9[171] = _Xtime9[171]
+ XtimeB[171] = _XtimeB[171]
+ XtimeD[171] = _XtimeD[171]
+ XtimeE[171] = _XtimeE[171]
+ Sbox[172] = _Sbox[172]
+ InvSbox[172] = _InvSbox[172]
+ Xtime2Sbox[172] = _Xtime2Sbox[172]
+ Xtime3Sbox[172] = _Xtime3Sbox[172]
+ Xtime2[172] = _Xtime2[172]
+ Xtime9[172] = _Xtime9[172]
+ XtimeB[172] = _XtimeB[172]
+ XtimeD[172] = _XtimeD[172]
+ XtimeE[172] = _XtimeE[172]
+ Sbox[173] = _Sbox[173]
+ InvSbox[173] = _InvSbox[173]
+ Xtime2Sbox[173] = _Xtime2Sbox[173]
+ Xtime3Sbox[173] = _Xtime3Sbox[173]
+ Xtime2[173] = _Xtime2[173]
+ Xtime9[173] = _Xtime9[173]
+ XtimeB[173] = _XtimeB[173]
+ XtimeD[173] = _XtimeD[173]
+ XtimeE[173] = _XtimeE[173]
+ Sbox[174] = _Sbox[174]
+ InvSbox[174] = _InvSbox[174]
+ Xtime2Sbox[174] = _Xtime2Sbox[174]
+ Xtime3Sbox[174] = _Xtime3Sbox[174]
+ Xtime2[174] = _Xtime2[174]
+ Xtime9[174] = _Xtime9[174]
+ XtimeB[174] = _XtimeB[174]
+ XtimeD[174] = _XtimeD[174]
+ XtimeE[174] = _XtimeE[174]
+ Sbox[175] = _Sbox[175]
+ InvSbox[175] = _InvSbox[175]
+ Xtime2Sbox[175] = _Xtime2Sbox[175]
+ Xtime3Sbox[175] = _Xtime3Sbox[175]
+ Xtime2[175] = _Xtime2[175]
+ Xtime9[175] = _Xtime9[175]
+ XtimeB[175] = _XtimeB[175]
+ XtimeD[175] = _XtimeD[175]
+ XtimeE[175] = _XtimeE[175]
+ Sbox[176] = _Sbox[176]
+ InvSbox[176] = _InvSbox[176]
+ Xtime2Sbox[176] = _Xtime2Sbox[176]
+ Xtime3Sbox[176] = _Xtime3Sbox[176]
+ Xtime2[176] = _Xtime2[176]
+ Xtime9[176] = _Xtime9[176]
+ XtimeB[176] = _XtimeB[176]
+ XtimeD[176] = _XtimeD[176]
+ XtimeE[176] = _XtimeE[176]
+ Sbox[177] = _Sbox[177]
+ InvSbox[177] = _InvSbox[177]
+ Xtime2Sbox[177] = _Xtime2Sbox[177]
+ Xtime3Sbox[177] = _Xtime3Sbox[177]
+ Xtime2[177] = _Xtime2[177]
+ Xtime9[177] = _Xtime9[177]
+ XtimeB[177] = _XtimeB[177]
+ XtimeD[177] = _XtimeD[177]
+ XtimeE[177] = _XtimeE[177]
+ Sbox[178] = _Sbox[178]
+ InvSbox[178] = _InvSbox[178]
+ Xtime2Sbox[178] = _Xtime2Sbox[178]
+ Xtime3Sbox[178] = _Xtime3Sbox[178]
+ Xtime2[178] = _Xtime2[178]
+ Xtime9[178] = _Xtime9[178]
+ XtimeB[178] = _XtimeB[178]
+ XtimeD[178] = _XtimeD[178]
+ XtimeE[178] = _XtimeE[178]
+ Sbox[179] = _Sbox[179]
+ InvSbox[179] = _InvSbox[179]
+ Xtime2Sbox[179] = _Xtime2Sbox[179]
+ Xtime3Sbox[179] = _Xtime3Sbox[179]
+ Xtime2[179] = _Xtime2[179]
+ Xtime9[179] = _Xtime9[179]
+ XtimeB[179] = _XtimeB[179]
+ XtimeD[179] = _XtimeD[179]
+ XtimeE[179] = _XtimeE[179]
+ Sbox[180] = _Sbox[180]
+ InvSbox[180] = _InvSbox[180]
+ Xtime2Sbox[180] = _Xtime2Sbox[180]
+ Xtime3Sbox[180] = _Xtime3Sbox[180]
+ Xtime2[180] = _Xtime2[180]
+ Xtime9[180] = _Xtime9[180]
+ XtimeB[180] = _XtimeB[180]
+ XtimeD[180] = _XtimeD[180]
+ XtimeE[180] = _XtimeE[180]
+ Sbox[181] = _Sbox[181]
+ InvSbox[181] = _InvSbox[181]
+ Xtime2Sbox[181] = _Xtime2Sbox[181]
+ Xtime3Sbox[181] = _Xtime3Sbox[181]
+ Xtime2[181] = _Xtime2[181]
+ Xtime9[181] = _Xtime9[181]
+ XtimeB[181] = _XtimeB[181]
+ XtimeD[181] = _XtimeD[181]
+ XtimeE[181] = _XtimeE[181]
+ Sbox[182] = _Sbox[182]
+ InvSbox[182] = _InvSbox[182]
+ Xtime2Sbox[182] = _Xtime2Sbox[182]
+ Xtime3Sbox[182] = _Xtime3Sbox[182]
+ Xtime2[182] = _Xtime2[182]
+ Xtime9[182] = _Xtime9[182]
+ XtimeB[182] = _XtimeB[182]
+ XtimeD[182] = _XtimeD[182]
+ XtimeE[182] = _XtimeE[182]
+ Sbox[183] = _Sbox[183]
+ InvSbox[183] = _InvSbox[183]
+ Xtime2Sbox[183] = _Xtime2Sbox[183]
+ Xtime3Sbox[183] = _Xtime3Sbox[183]
+ Xtime2[183] = _Xtime2[183]
+ Xtime9[183] = _Xtime9[183]
+ XtimeB[183] = _XtimeB[183]
+ XtimeD[183] = _XtimeD[183]
+ XtimeE[183] = _XtimeE[183]
+ Sbox[184] = _Sbox[184]
+ InvSbox[184] = _InvSbox[184]
+ Xtime2Sbox[184] = _Xtime2Sbox[184]
+ Xtime3Sbox[184] = _Xtime3Sbox[184]
+ Xtime2[184] = _Xtime2[184]
+ Xtime9[184] = _Xtime9[184]
+ XtimeB[184] = _XtimeB[184]
+ XtimeD[184] = _XtimeD[184]
+ XtimeE[184] = _XtimeE[184]
+ Sbox[185] = _Sbox[185]
+ InvSbox[185] = _InvSbox[185]
+ Xtime2Sbox[185] = _Xtime2Sbox[185]
+ Xtime3Sbox[185] = _Xtime3Sbox[185]
+ Xtime2[185] = _Xtime2[185]
+ Xtime9[185] = _Xtime9[185]
+ XtimeB[185] = _XtimeB[185]
+ XtimeD[185] = _XtimeD[185]
+ XtimeE[185] = _XtimeE[185]
+ Sbox[186] = _Sbox[186]
+ InvSbox[186] = _InvSbox[186]
+ Xtime2Sbox[186] = _Xtime2Sbox[186]
+ Xtime3Sbox[186] = _Xtime3Sbox[186]
+ Xtime2[186] = _Xtime2[186]
+ Xtime9[186] = _Xtime9[186]
+ XtimeB[186] = _XtimeB[186]
+ XtimeD[186] = _XtimeD[186]
+ XtimeE[186] = _XtimeE[186]
+ Sbox[187] = _Sbox[187]
+ InvSbox[187] = _InvSbox[187]
+ Xtime2Sbox[187] = _Xtime2Sbox[187]
+ Xtime3Sbox[187] = _Xtime3Sbox[187]
+ Xtime2[187] = _Xtime2[187]
+ Xtime9[187] = _Xtime9[187]
+ XtimeB[187] = _XtimeB[187]
+ XtimeD[187] = _XtimeD[187]
+ XtimeE[187] = _XtimeE[187]
+ Sbox[188] = _Sbox[188]
+ InvSbox[188] = _InvSbox[188]
+ Xtime2Sbox[188] = _Xtime2Sbox[188]
+ Xtime3Sbox[188] = _Xtime3Sbox[188]
+ Xtime2[188] = _Xtime2[188]
+ Xtime9[188] = _Xtime9[188]
+ XtimeB[188] = _XtimeB[188]
+ XtimeD[188] = _XtimeD[188]
+ XtimeE[188] = _XtimeE[188]
+ Sbox[189] = _Sbox[189]
+ InvSbox[189] = _InvSbox[189]
+ Xtime2Sbox[189] = _Xtime2Sbox[189]
+ Xtime3Sbox[189] = _Xtime3Sbox[189]
+ Xtime2[189] = _Xtime2[189]
+ Xtime9[189] = _Xtime9[189]
+ XtimeB[189] = _XtimeB[189]
+ XtimeD[189] = _XtimeD[189]
+ XtimeE[189] = _XtimeE[189]
+ Sbox[190] = _Sbox[190]
+ InvSbox[190] = _InvSbox[190]
+ Xtime2Sbox[190] = _Xtime2Sbox[190]
+ Xtime3Sbox[190] = _Xtime3Sbox[190]
+ Xtime2[190] = _Xtime2[190]
+ Xtime9[190] = _Xtime9[190]
+ XtimeB[190] = _XtimeB[190]
+ XtimeD[190] = _XtimeD[190]
+ XtimeE[190] = _XtimeE[190]
+ Sbox[191] = _Sbox[191]
+ InvSbox[191] = _InvSbox[191]
+ Xtime2Sbox[191] = _Xtime2Sbox[191]
+ Xtime3Sbox[191] = _Xtime3Sbox[191]
+ Xtime2[191] = _Xtime2[191]
+ Xtime9[191] = _Xtime9[191]
+ XtimeB[191] = _XtimeB[191]
+ XtimeD[191] = _XtimeD[191]
+ XtimeE[191] = _XtimeE[191]
+ Sbox[192] = _Sbox[192]
+ InvSbox[192] = _InvSbox[192]
+ Xtime2Sbox[192] = _Xtime2Sbox[192]
+ Xtime3Sbox[192] = _Xtime3Sbox[192]
+ Xtime2[192] = _Xtime2[192]
+ Xtime9[192] = _Xtime9[192]
+ XtimeB[192] = _XtimeB[192]
+ XtimeD[192] = _XtimeD[192]
+ XtimeE[192] = _XtimeE[192]
+ Sbox[193] = _Sbox[193]
+ InvSbox[193] = _InvSbox[193]
+ Xtime2Sbox[193] = _Xtime2Sbox[193]
+ Xtime3Sbox[193] = _Xtime3Sbox[193]
+ Xtime2[193] = _Xtime2[193]
+ Xtime9[193] = _Xtime9[193]
+ XtimeB[193] = _XtimeB[193]
+ XtimeD[193] = _XtimeD[193]
+ XtimeE[193] = _XtimeE[193]
+ Sbox[194] = _Sbox[194]
+ InvSbox[194] = _InvSbox[194]
+ Xtime2Sbox[194] = _Xtime2Sbox[194]
+ Xtime3Sbox[194] = _Xtime3Sbox[194]
+ Xtime2[194] = _Xtime2[194]
+ Xtime9[194] = _Xtime9[194]
+ XtimeB[194] = _XtimeB[194]
+ XtimeD[194] = _XtimeD[194]
+ XtimeE[194] = _XtimeE[194]
+ Sbox[195] = _Sbox[195]
+ InvSbox[195] = _InvSbox[195]
+ Xtime2Sbox[195] = _Xtime2Sbox[195]
+ Xtime3Sbox[195] = _Xtime3Sbox[195]
+ Xtime2[195] = _Xtime2[195]
+ Xtime9[195] = _Xtime9[195]
+ XtimeB[195] = _XtimeB[195]
+ XtimeD[195] = _XtimeD[195]
+ XtimeE[195] = _XtimeE[195]
+ Sbox[196] = _Sbox[196]
+ InvSbox[196] = _InvSbox[196]
+ Xtime2Sbox[196] = _Xtime2Sbox[196]
+ Xtime3Sbox[196] = _Xtime3Sbox[196]
+ Xtime2[196] = _Xtime2[196]
+ Xtime9[196] = _Xtime9[196]
+ XtimeB[196] = _XtimeB[196]
+ XtimeD[196] = _XtimeD[196]
+ XtimeE[196] = _XtimeE[196]
+ Sbox[197] = _Sbox[197]
+ InvSbox[197] = _InvSbox[197]
+ Xtime2Sbox[197] = _Xtime2Sbox[197]
+ Xtime3Sbox[197] = _Xtime3Sbox[197]
+ Xtime2[197] = _Xtime2[197]
+ Xtime9[197] = _Xtime9[197]
+ XtimeB[197] = _XtimeB[197]
+ XtimeD[197] = _XtimeD[197]
+ XtimeE[197] = _XtimeE[197]
+ Sbox[198] = _Sbox[198]
+ InvSbox[198] = _InvSbox[198]
+ Xtime2Sbox[198] = _Xtime2Sbox[198]
+ Xtime3Sbox[198] = _Xtime3Sbox[198]
+ Xtime2[198] = _Xtime2[198]
+ Xtime9[198] = _Xtime9[198]
+ XtimeB[198] = _XtimeB[198]
+ XtimeD[198] = _XtimeD[198]
+ XtimeE[198] = _XtimeE[198]
+ Sbox[199] = _Sbox[199]
+ InvSbox[199] = _InvSbox[199]
+ Xtime2Sbox[199] = _Xtime2Sbox[199]
+ Xtime3Sbox[199] = _Xtime3Sbox[199]
+ Xtime2[199] = _Xtime2[199]
+ Xtime9[199] = _Xtime9[199]
+ XtimeB[199] = _XtimeB[199]
+ XtimeD[199] = _XtimeD[199]
+ XtimeE[199] = _XtimeE[199]
+ Sbox[200] = _Sbox[200]
+ InvSbox[200] = _InvSbox[200]
+ Xtime2Sbox[200] = _Xtime2Sbox[200]
+ Xtime3Sbox[200] = _Xtime3Sbox[200]
+ Xtime2[200] = _Xtime2[200]
+ Xtime9[200] = _Xtime9[200]
+ XtimeB[200] = _XtimeB[200]
+ XtimeD[200] = _XtimeD[200]
+ XtimeE[200] = _XtimeE[200]
+ Sbox[201] = _Sbox[201]
+ InvSbox[201] = _InvSbox[201]
+ Xtime2Sbox[201] = _Xtime2Sbox[201]
+ Xtime3Sbox[201] = _Xtime3Sbox[201]
+ Xtime2[201] = _Xtime2[201]
+ Xtime9[201] = _Xtime9[201]
+ XtimeB[201] = _XtimeB[201]
+ XtimeD[201] = _XtimeD[201]
+ XtimeE[201] = _XtimeE[201]
+ Sbox[202] = _Sbox[202]
+ InvSbox[202] = _InvSbox[202]
+ Xtime2Sbox[202] = _Xtime2Sbox[202]
+ Xtime3Sbox[202] = _Xtime3Sbox[202]
+ Xtime2[202] = _Xtime2[202]
+ Xtime9[202] = _Xtime9[202]
+ XtimeB[202] = _XtimeB[202]
+ XtimeD[202] = _XtimeD[202]
+ XtimeE[202] = _XtimeE[202]
+ Sbox[203] = _Sbox[203]
+ InvSbox[203] = _InvSbox[203]
+ Xtime2Sbox[203] = _Xtime2Sbox[203]
+ Xtime3Sbox[203] = _Xtime3Sbox[203]
+ Xtime2[203] = _Xtime2[203]
+ Xtime9[203] = _Xtime9[203]
+ XtimeB[203] = _XtimeB[203]
+ XtimeD[203] = _XtimeD[203]
+ XtimeE[203] = _XtimeE[203]
+ Sbox[204] = _Sbox[204]
+ InvSbox[204] = _InvSbox[204]
+ Xtime2Sbox[204] = _Xtime2Sbox[204]
+ Xtime3Sbox[204] = _Xtime3Sbox[204]
+ Xtime2[204] = _Xtime2[204]
+ Xtime9[204] = _Xtime9[204]
+ XtimeB[204] = _XtimeB[204]
+ XtimeD[204] = _XtimeD[204]
+ XtimeE[204] = _XtimeE[204]
+ Sbox[205] = _Sbox[205]
+ InvSbox[205] = _InvSbox[205]
+ Xtime2Sbox[205] = _Xtime2Sbox[205]
+ Xtime3Sbox[205] = _Xtime3Sbox[205]
+ Xtime2[205] = _Xtime2[205]
+ Xtime9[205] = _Xtime9[205]
+ XtimeB[205] = _XtimeB[205]
+ XtimeD[205] = _XtimeD[205]
+ XtimeE[205] = _XtimeE[205]
+ Sbox[206] = _Sbox[206]
+ InvSbox[206] = _InvSbox[206]
+ Xtime2Sbox[206] = _Xtime2Sbox[206]
+ Xtime3Sbox[206] = _Xtime3Sbox[206]
+ Xtime2[206] = _Xtime2[206]
+ Xtime9[206] = _Xtime9[206]
+ XtimeB[206] = _XtimeB[206]
+ XtimeD[206] = _XtimeD[206]
+ XtimeE[206] = _XtimeE[206]
+ Sbox[207] = _Sbox[207]
+ InvSbox[207] = _InvSbox[207]
+ Xtime2Sbox[207] = _Xtime2Sbox[207]
+ Xtime3Sbox[207] = _Xtime3Sbox[207]
+ Xtime2[207] = _Xtime2[207]
+ Xtime9[207] = _Xtime9[207]
+ XtimeB[207] = _XtimeB[207]
+ XtimeD[207] = _XtimeD[207]
+ XtimeE[207] = _XtimeE[207]
+ Sbox[208] = _Sbox[208]
+ InvSbox[208] = _InvSbox[208]
+ Xtime2Sbox[208] = _Xtime2Sbox[208]
+ Xtime3Sbox[208] = _Xtime3Sbox[208]
+ Xtime2[208] = _Xtime2[208]
+ Xtime9[208] = _Xtime9[208]
+ XtimeB[208] = _XtimeB[208]
+ XtimeD[208] = _XtimeD[208]
+ XtimeE[208] = _XtimeE[208]
+ Sbox[209] = _Sbox[209]
+ InvSbox[209] = _InvSbox[209]
+ Xtime2Sbox[209] = _Xtime2Sbox[209]
+ Xtime3Sbox[209] = _Xtime3Sbox[209]
+ Xtime2[209] = _Xtime2[209]
+ Xtime9[209] = _Xtime9[209]
+ XtimeB[209] = _XtimeB[209]
+ XtimeD[209] = _XtimeD[209]
+ XtimeE[209] = _XtimeE[209]
+ Sbox[210] = _Sbox[210]
+ InvSbox[210] = _InvSbox[210]
+ Xtime2Sbox[210] = _Xtime2Sbox[210]
+ Xtime3Sbox[210] = _Xtime3Sbox[210]
+ Xtime2[210] = _Xtime2[210]
+ Xtime9[210] = _Xtime9[210]
+ XtimeB[210] = _XtimeB[210]
+ XtimeD[210] = _XtimeD[210]
+ XtimeE[210] = _XtimeE[210]
+ Sbox[211] = _Sbox[211]
+ InvSbox[211] = _InvSbox[211]
+ Xtime2Sbox[211] = _Xtime2Sbox[211]
+ Xtime3Sbox[211] = _Xtime3Sbox[211]
+ Xtime2[211] = _Xtime2[211]
+ Xtime9[211] = _Xtime9[211]
+ XtimeB[211] = _XtimeB[211]
+ XtimeD[211] = _XtimeD[211]
+ XtimeE[211] = _XtimeE[211]
+ Sbox[212] = _Sbox[212]
+ InvSbox[212] = _InvSbox[212]
+ Xtime2Sbox[212] = _Xtime2Sbox[212]
+ Xtime3Sbox[212] = _Xtime3Sbox[212]
+ Xtime2[212] = _Xtime2[212]
+ Xtime9[212] = _Xtime9[212]
+ XtimeB[212] = _XtimeB[212]
+ XtimeD[212] = _XtimeD[212]
+ XtimeE[212] = _XtimeE[212]
+ Sbox[213] = _Sbox[213]
+ InvSbox[213] = _InvSbox[213]
+ Xtime2Sbox[213] = _Xtime2Sbox[213]
+ Xtime3Sbox[213] = _Xtime3Sbox[213]
+ Xtime2[213] = _Xtime2[213]
+ Xtime9[213] = _Xtime9[213]
+ XtimeB[213] = _XtimeB[213]
+ XtimeD[213] = _XtimeD[213]
+ XtimeE[213] = _XtimeE[213]
+ Sbox[214] = _Sbox[214]
+ InvSbox[214] = _InvSbox[214]
+ Xtime2Sbox[214] = _Xtime2Sbox[214]
+ Xtime3Sbox[214] = _Xtime3Sbox[214]
+ Xtime2[214] = _Xtime2[214]
+ Xtime9[214] = _Xtime9[214]
+ XtimeB[214] = _XtimeB[214]
+ XtimeD[214] = _XtimeD[214]
+ XtimeE[214] = _XtimeE[214]
+ Sbox[215] = _Sbox[215]
+ InvSbox[215] = _InvSbox[215]
+ Xtime2Sbox[215] = _Xtime2Sbox[215]
+ Xtime3Sbox[215] = _Xtime3Sbox[215]
+ Xtime2[215] = _Xtime2[215]
+ Xtime9[215] = _Xtime9[215]
+ XtimeB[215] = _XtimeB[215]
+ XtimeD[215] = _XtimeD[215]
+ XtimeE[215] = _XtimeE[215]
+ Sbox[216] = _Sbox[216]
+ InvSbox[216] = _InvSbox[216]
+ Xtime2Sbox[216] = _Xtime2Sbox[216]
+ Xtime3Sbox[216] = _Xtime3Sbox[216]
+ Xtime2[216] = _Xtime2[216]
+ Xtime9[216] = _Xtime9[216]
+ XtimeB[216] = _XtimeB[216]
+ XtimeD[216] = _XtimeD[216]
+ XtimeE[216] = _XtimeE[216]
+ Sbox[217] = _Sbox[217]
+ InvSbox[217] = _InvSbox[217]
+ Xtime2Sbox[217] = _Xtime2Sbox[217]
+ Xtime3Sbox[217] = _Xtime3Sbox[217]
+ Xtime2[217] = _Xtime2[217]
+ Xtime9[217] = _Xtime9[217]
+ XtimeB[217] = _XtimeB[217]
+ XtimeD[217] = _XtimeD[217]
+ XtimeE[217] = _XtimeE[217]
+ Sbox[218] = _Sbox[218]
+ InvSbox[218] = _InvSbox[218]
+ Xtime2Sbox[218] = _Xtime2Sbox[218]
+ Xtime3Sbox[218] = _Xtime3Sbox[218]
+ Xtime2[218] = _Xtime2[218]
+ Xtime9[218] = _Xtime9[218]
+ XtimeB[218] = _XtimeB[218]
+ XtimeD[218] = _XtimeD[218]
+ XtimeE[218] = _XtimeE[218]
+ Sbox[219] = _Sbox[219]
+ InvSbox[219] = _InvSbox[219]
+ Xtime2Sbox[219] = _Xtime2Sbox[219]
+ Xtime3Sbox[219] = _Xtime3Sbox[219]
+ Xtime2[219] = _Xtime2[219]
+ Xtime9[219] = _Xtime9[219]
+ XtimeB[219] = _XtimeB[219]
+ XtimeD[219] = _XtimeD[219]
+ XtimeE[219] = _XtimeE[219]
+ Sbox[220] = _Sbox[220]
+ InvSbox[220] = _InvSbox[220]
+ Xtime2Sbox[220] = _Xtime2Sbox[220]
+ Xtime3Sbox[220] = _Xtime3Sbox[220]
+ Xtime2[220] = _Xtime2[220]
+ Xtime9[220] = _Xtime9[220]
+ XtimeB[220] = _XtimeB[220]
+ XtimeD[220] = _XtimeD[220]
+ XtimeE[220] = _XtimeE[220]
+ Sbox[221] = _Sbox[221]
+ InvSbox[221] = _InvSbox[221]
+ Xtime2Sbox[221] = _Xtime2Sbox[221]
+ Xtime3Sbox[221] = _Xtime3Sbox[221]
+ Xtime2[221] = _Xtime2[221]
+ Xtime9[221] = _Xtime9[221]
+ XtimeB[221] = _XtimeB[221]
+ XtimeD[221] = _XtimeD[221]
+ XtimeE[221] = _XtimeE[221]
+ Sbox[222] = _Sbox[222]
+ InvSbox[222] = _InvSbox[222]
+ Xtime2Sbox[222] = _Xtime2Sbox[222]
+ Xtime3Sbox[222] = _Xtime3Sbox[222]
+ Xtime2[222] = _Xtime2[222]
+ Xtime9[222] = _Xtime9[222]
+ XtimeB[222] = _XtimeB[222]
+ XtimeD[222] = _XtimeD[222]
+ XtimeE[222] = _XtimeE[222]
+ Sbox[223] = _Sbox[223]
+ InvSbox[223] = _InvSbox[223]
+ Xtime2Sbox[223] = _Xtime2Sbox[223]
+ Xtime3Sbox[223] = _Xtime3Sbox[223]
+ Xtime2[223] = _Xtime2[223]
+ Xtime9[223] = _Xtime9[223]
+ XtimeB[223] = _XtimeB[223]
+ XtimeD[223] = _XtimeD[223]
+ XtimeE[223] = _XtimeE[223]
+ Sbox[224] = _Sbox[224]
+ InvSbox[224] = _InvSbox[224]
+ Xtime2Sbox[224] = _Xtime2Sbox[224]
+ Xtime3Sbox[224] = _Xtime3Sbox[224]
+ Xtime2[224] = _Xtime2[224]
+ Xtime9[224] = _Xtime9[224]
+ XtimeB[224] = _XtimeB[224]
+ XtimeD[224] = _XtimeD[224]
+ XtimeE[224] = _XtimeE[224]
+ Sbox[225] = _Sbox[225]
+ InvSbox[225] = _InvSbox[225]
+ Xtime2Sbox[225] = _Xtime2Sbox[225]
+ Xtime3Sbox[225] = _Xtime3Sbox[225]
+ Xtime2[225] = _Xtime2[225]
+ Xtime9[225] = _Xtime9[225]
+ XtimeB[225] = _XtimeB[225]
+ XtimeD[225] = _XtimeD[225]
+ XtimeE[225] = _XtimeE[225]
+ Sbox[226] = _Sbox[226]
+ InvSbox[226] = _InvSbox[226]
+ Xtime2Sbox[226] = _Xtime2Sbox[226]
+ Xtime3Sbox[226] = _Xtime3Sbox[226]
+ Xtime2[226] = _Xtime2[226]
+ Xtime9[226] = _Xtime9[226]
+ XtimeB[226] = _XtimeB[226]
+ XtimeD[226] = _XtimeD[226]
+ XtimeE[226] = _XtimeE[226]
+ Sbox[227] = _Sbox[227]
+ InvSbox[227] = _InvSbox[227]
+ Xtime2Sbox[227] = _Xtime2Sbox[227]
+ Xtime3Sbox[227] = _Xtime3Sbox[227]
+ Xtime2[227] = _Xtime2[227]
+ Xtime9[227] = _Xtime9[227]
+ XtimeB[227] = _XtimeB[227]
+ XtimeD[227] = _XtimeD[227]
+ XtimeE[227] = _XtimeE[227]
+ Sbox[228] = _Sbox[228]
+ InvSbox[228] = _InvSbox[228]
+ Xtime2Sbox[228] = _Xtime2Sbox[228]
+ Xtime3Sbox[228] = _Xtime3Sbox[228]
+ Xtime2[228] = _Xtime2[228]
+ Xtime9[228] = _Xtime9[228]
+ XtimeB[228] = _XtimeB[228]
+ XtimeD[228] = _XtimeD[228]
+ XtimeE[228] = _XtimeE[228]
+ Sbox[229] = _Sbox[229]
+ InvSbox[229] = _InvSbox[229]
+ Xtime2Sbox[229] = _Xtime2Sbox[229]
+ Xtime3Sbox[229] = _Xtime3Sbox[229]
+ Xtime2[229] = _Xtime2[229]
+ Xtime9[229] = _Xtime9[229]
+ XtimeB[229] = _XtimeB[229]
+ XtimeD[229] = _XtimeD[229]
+ XtimeE[229] = _XtimeE[229]
+ Sbox[230] = _Sbox[230]
+ InvSbox[230] = _InvSbox[230]
+ Xtime2Sbox[230] = _Xtime2Sbox[230]
+ Xtime3Sbox[230] = _Xtime3Sbox[230]
+ Xtime2[230] = _Xtime2[230]
+ Xtime9[230] = _Xtime9[230]
+ XtimeB[230] = _XtimeB[230]
+ XtimeD[230] = _XtimeD[230]
+ XtimeE[230] = _XtimeE[230]
+ Sbox[231] = _Sbox[231]
+ InvSbox[231] = _InvSbox[231]
+ Xtime2Sbox[231] = _Xtime2Sbox[231]
+ Xtime3Sbox[231] = _Xtime3Sbox[231]
+ Xtime2[231] = _Xtime2[231]
+ Xtime9[231] = _Xtime9[231]
+ XtimeB[231] = _XtimeB[231]
+ XtimeD[231] = _XtimeD[231]
+ XtimeE[231] = _XtimeE[231]
+ Sbox[232] = _Sbox[232]
+ InvSbox[232] = _InvSbox[232]
+ Xtime2Sbox[232] = _Xtime2Sbox[232]
+ Xtime3Sbox[232] = _Xtime3Sbox[232]
+ Xtime2[232] = _Xtime2[232]
+ Xtime9[232] = _Xtime9[232]
+ XtimeB[232] = _XtimeB[232]
+ XtimeD[232] = _XtimeD[232]
+ XtimeE[232] = _XtimeE[232]
+ Sbox[233] = _Sbox[233]
+ InvSbox[233] = _InvSbox[233]
+ Xtime2Sbox[233] = _Xtime2Sbox[233]
+ Xtime3Sbox[233] = _Xtime3Sbox[233]
+ Xtime2[233] = _Xtime2[233]
+ Xtime9[233] = _Xtime9[233]
+ XtimeB[233] = _XtimeB[233]
+ XtimeD[233] = _XtimeD[233]
+ XtimeE[233] = _XtimeE[233]
+ Sbox[234] = _Sbox[234]
+ InvSbox[234] = _InvSbox[234]
+ Xtime2Sbox[234] = _Xtime2Sbox[234]
+ Xtime3Sbox[234] = _Xtime3Sbox[234]
+ Xtime2[234] = _Xtime2[234]
+ Xtime9[234] = _Xtime9[234]
+ XtimeB[234] = _XtimeB[234]
+ XtimeD[234] = _XtimeD[234]
+ XtimeE[234] = _XtimeE[234]
+ Sbox[235] = _Sbox[235]
+ InvSbox[235] = _InvSbox[235]
+ Xtime2Sbox[235] = _Xtime2Sbox[235]
+ Xtime3Sbox[235] = _Xtime3Sbox[235]
+ Xtime2[235] = _Xtime2[235]
+ Xtime9[235] = _Xtime9[235]
+ XtimeB[235] = _XtimeB[235]
+ XtimeD[235] = _XtimeD[235]
+ XtimeE[235] = _XtimeE[235]
+ Sbox[236] = _Sbox[236]
+ InvSbox[236] = _InvSbox[236]
+ Xtime2Sbox[236] = _Xtime2Sbox[236]
+ Xtime3Sbox[236] = _Xtime3Sbox[236]
+ Xtime2[236] = _Xtime2[236]
+ Xtime9[236] = _Xtime9[236]
+ XtimeB[236] = _XtimeB[236]
+ XtimeD[236] = _XtimeD[236]
+ XtimeE[236] = _XtimeE[236]
+ Sbox[237] = _Sbox[237]
+ InvSbox[237] = _InvSbox[237]
+ Xtime2Sbox[237] = _Xtime2Sbox[237]
+ Xtime3Sbox[237] = _Xtime3Sbox[237]
+ Xtime2[237] = _Xtime2[237]
+ Xtime9[237] = _Xtime9[237]
+ XtimeB[237] = _XtimeB[237]
+ XtimeD[237] = _XtimeD[237]
+ XtimeE[237] = _XtimeE[237]
+ Sbox[238] = _Sbox[238]
+ InvSbox[238] = _InvSbox[238]
+ Xtime2Sbox[238] = _Xtime2Sbox[238]
+ Xtime3Sbox[238] = _Xtime3Sbox[238]
+ Xtime2[238] = _Xtime2[238]
+ Xtime9[238] = _Xtime9[238]
+ XtimeB[238] = _XtimeB[238]
+ XtimeD[238] = _XtimeD[238]
+ XtimeE[238] = _XtimeE[238]
+ Sbox[239] = _Sbox[239]
+ InvSbox[239] = _InvSbox[239]
+ Xtime2Sbox[239] = _Xtime2Sbox[239]
+ Xtime3Sbox[239] = _Xtime3Sbox[239]
+ Xtime2[239] = _Xtime2[239]
+ Xtime9[239] = _Xtime9[239]
+ XtimeB[239] = _XtimeB[239]
+ XtimeD[239] = _XtimeD[239]
+ XtimeE[239] = _XtimeE[239]
+ Sbox[240] = _Sbox[240]
+ InvSbox[240] = _InvSbox[240]
+ Xtime2Sbox[240] = _Xtime2Sbox[240]
+ Xtime3Sbox[240] = _Xtime3Sbox[240]
+ Xtime2[240] = _Xtime2[240]
+ Xtime9[240] = _Xtime9[240]
+ XtimeB[240] = _XtimeB[240]
+ XtimeD[240] = _XtimeD[240]
+ XtimeE[240] = _XtimeE[240]
+ Sbox[241] = _Sbox[241]
+ InvSbox[241] = _InvSbox[241]
+ Xtime2Sbox[241] = _Xtime2Sbox[241]
+ Xtime3Sbox[241] = _Xtime3Sbox[241]
+ Xtime2[241] = _Xtime2[241]
+ Xtime9[241] = _Xtime9[241]
+ XtimeB[241] = _XtimeB[241]
+ XtimeD[241] = _XtimeD[241]
+ XtimeE[241] = _XtimeE[241]
+ Sbox[242] = _Sbox[242]
+ InvSbox[242] = _InvSbox[242]
+ Xtime2Sbox[242] = _Xtime2Sbox[242]
+ Xtime3Sbox[242] = _Xtime3Sbox[242]
+ Xtime2[242] = _Xtime2[242]
+ Xtime9[242] = _Xtime9[242]
+ XtimeB[242] = _XtimeB[242]
+ XtimeD[242] = _XtimeD[242]
+ XtimeE[242] = _XtimeE[242]
+ Sbox[243] = _Sbox[243]
+ InvSbox[243] = _InvSbox[243]
+ Xtime2Sbox[243] = _Xtime2Sbox[243]
+ Xtime3Sbox[243] = _Xtime3Sbox[243]
+ Xtime2[243] = _Xtime2[243]
+ Xtime9[243] = _Xtime9[243]
+ XtimeB[243] = _XtimeB[243]
+ XtimeD[243] = _XtimeD[243]
+ XtimeE[243] = _XtimeE[243]
+ Sbox[244] = _Sbox[244]
+ InvSbox[244] = _InvSbox[244]
+ Xtime2Sbox[244] = _Xtime2Sbox[244]
+ Xtime3Sbox[244] = _Xtime3Sbox[244]
+ Xtime2[244] = _Xtime2[244]
+ Xtime9[244] = _Xtime9[244]
+ XtimeB[244] = _XtimeB[244]
+ XtimeD[244] = _XtimeD[244]
+ XtimeE[244] = _XtimeE[244]
+ Sbox[245] = _Sbox[245]
+ InvSbox[245] = _InvSbox[245]
+ Xtime2Sbox[245] = _Xtime2Sbox[245]
+ Xtime3Sbox[245] = _Xtime3Sbox[245]
+ Xtime2[245] = _Xtime2[245]
+ Xtime9[245] = _Xtime9[245]
+ XtimeB[245] = _XtimeB[245]
+ XtimeD[245] = _XtimeD[245]
+ XtimeE[245] = _XtimeE[245]
+ Sbox[246] = _Sbox[246]
+ InvSbox[246] = _InvSbox[246]
+ Xtime2Sbox[246] = _Xtime2Sbox[246]
+ Xtime3Sbox[246] = _Xtime3Sbox[246]
+ Xtime2[246] = _Xtime2[246]
+ Xtime9[246] = _Xtime9[246]
+ XtimeB[246] = _XtimeB[246]
+ XtimeD[246] = _XtimeD[246]
+ XtimeE[246] = _XtimeE[246]
+ Sbox[247] = _Sbox[247]
+ InvSbox[247] = _InvSbox[247]
+ Xtime2Sbox[247] = _Xtime2Sbox[247]
+ Xtime3Sbox[247] = _Xtime3Sbox[247]
+ Xtime2[247] = _Xtime2[247]
+ Xtime9[247] = _Xtime9[247]
+ XtimeB[247] = _XtimeB[247]
+ XtimeD[247] = _XtimeD[247]
+ XtimeE[247] = _XtimeE[247]
+ Sbox[248] = _Sbox[248]
+ InvSbox[248] = _InvSbox[248]
+ Xtime2Sbox[248] = _Xtime2Sbox[248]
+ Xtime3Sbox[248] = _Xtime3Sbox[248]
+ Xtime2[248] = _Xtime2[248]
+ Xtime9[248] = _Xtime9[248]
+ XtimeB[248] = _XtimeB[248]
+ XtimeD[248] = _XtimeD[248]
+ XtimeE[248] = _XtimeE[248]
+ Sbox[249] = _Sbox[249]
+ InvSbox[249] = _InvSbox[249]
+ Xtime2Sbox[249] = _Xtime2Sbox[249]
+ Xtime3Sbox[249] = _Xtime3Sbox[249]
+ Xtime2[249] = _Xtime2[249]
+ Xtime9[249] = _Xtime9[249]
+ XtimeB[249] = _XtimeB[249]
+ XtimeD[249] = _XtimeD[249]
+ XtimeE[249] = _XtimeE[249]
+ Sbox[250] = _Sbox[250]
+ InvSbox[250] = _InvSbox[250]
+ Xtime2Sbox[250] = _Xtime2Sbox[250]
+ Xtime3Sbox[250] = _Xtime3Sbox[250]
+ Xtime2[250] = _Xtime2[250]
+ Xtime9[250] = _Xtime9[250]
+ XtimeB[250] = _XtimeB[250]
+ XtimeD[250] = _XtimeD[250]
+ XtimeE[250] = _XtimeE[250]
+ Sbox[251] = _Sbox[251]
+ InvSbox[251] = _InvSbox[251]
+ Xtime2Sbox[251] = _Xtime2Sbox[251]
+ Xtime3Sbox[251] = _Xtime3Sbox[251]
+ Xtime2[251] = _Xtime2[251]
+ Xtime9[251] = _Xtime9[251]
+ XtimeB[251] = _XtimeB[251]
+ XtimeD[251] = _XtimeD[251]
+ XtimeE[251] = _XtimeE[251]
+ Sbox[252] = _Sbox[252]
+ InvSbox[252] = _InvSbox[252]
+ Xtime2Sbox[252] = _Xtime2Sbox[252]
+ Xtime3Sbox[252] = _Xtime3Sbox[252]
+ Xtime2[252] = _Xtime2[252]
+ Xtime9[252] = _Xtime9[252]
+ XtimeB[252] = _XtimeB[252]
+ XtimeD[252] = _XtimeD[252]
+ XtimeE[252] = _XtimeE[252]
+ Sbox[253] = _Sbox[253]
+ InvSbox[253] = _InvSbox[253]
+ Xtime2Sbox[253] = _Xtime2Sbox[253]
+ Xtime3Sbox[253] = _Xtime3Sbox[253]
+ Xtime2[253] = _Xtime2[253]
+ Xtime9[253] = _Xtime9[253]
+ XtimeB[253] = _XtimeB[253]
+ XtimeD[253] = _XtimeD[253]
+ XtimeE[253] = _XtimeE[253]
+ Sbox[254] = _Sbox[254]
+ InvSbox[254] = _InvSbox[254]
+ Xtime2Sbox[254] = _Xtime2Sbox[254]
+ Xtime3Sbox[254] = _Xtime3Sbox[254]
+ Xtime2[254] = _Xtime2[254]
+ Xtime9[254] = _Xtime9[254]
+ XtimeB[254] = _XtimeB[254]
+ XtimeD[254] = _XtimeD[254]
+ XtimeE[254] = _XtimeE[254]
+ Sbox[255] = _Sbox[255]
+ InvSbox[255] = _InvSbox[255]
+ Xtime2Sbox[255] = _Xtime2Sbox[255]
+ Xtime3Sbox[255] = _Xtime3Sbox[255]
+ Xtime2[255] = _Xtime2[255]
+ Xtime9[255] = _Xtime9[255]
+ XtimeB[255] = _XtimeB[255]
+ XtimeD[255] = _XtimeD[255]
+ XtimeE[255] = _XtimeE[255]
+ Rcon = new ByteArray;
+ /*
+ for (i=0;i<_Rcon.length;i++) {
+ Rcon[i] = _Rcon[i];
+ }
+ */
+ Rcon[0] = _Rcon[0];
+ Rcon[1] = _Rcon[1];
+ Rcon[2] = _Rcon[2];
+ Rcon[3] = _Rcon[3];
+ Rcon[4] = _Rcon[4];
+ Rcon[5] = _Rcon[5];
+ Rcon[6] = _Rcon[6];
+ Rcon[7] = _Rcon[7];
+ Rcon[8] = _Rcon[8];
+ Rcon[9] = _Rcon[9];
+ Rcon[10] = _Rcon[10];
+ Rcon[11] = _Rcon[11];
+ }
+
+ private var key:ByteArray;
+ private var keyLength:uint;
+ private var Nr:uint;
+ private var state:ByteArray;
+ private var tmp:ByteArray;
+
+ public function AESKey(key:ByteArray) {
+ tmp = new ByteArray;
+ state = new ByteArray;
+ keyLength = key.length;
+ this.key = new ByteArray;
+ this.key.writeBytes(key);
+ expandKey();
+ }
+
+ // produce Nb bytes for each round
+ private function expandKey():void {
+ var tmp0:uint, tmp1:uint, tmp2:uint, tmp3:uint, tmp4:uint;
+ var idx:uint;
+ var Nk:uint = key.length/4;
+ Nr = Nk+6;
+
+ for( idx = Nk; idx < Nb * (Nr + 1); idx++ ) {
+ tmp0 = key[4*idx - 4];
+ tmp1 = key[4*idx - 3];
+ tmp2 = key[4*idx - 2];
+ tmp3 = key[4*idx - 1];
+ if( !(idx % Nk) ) {
+ tmp4 = tmp3;
+ tmp3 = Sbox[tmp0];
+ tmp0 = Sbox[tmp1] ^ Rcon[idx/Nk];
+ tmp1 = Sbox[tmp2];
+ tmp2 = Sbox[tmp4];
+ } else if( Nk > 6 && idx % Nk == 4 ) {
+ tmp0 = Sbox[tmp0];
+ tmp1 = Sbox[tmp1];
+ tmp2 = Sbox[tmp2];
+ tmp3 = Sbox[tmp3];
+ }
+
+ key[4*idx+0] = key[4*idx - 4*Nk + 0] ^ tmp0;
+ key[4*idx+1] = key[4*idx - 4*Nk + 1] ^ tmp1;
+ key[4*idx+2] = key[4*idx - 4*Nk + 2] ^ tmp2;
+ key[4*idx+3] = key[4*idx - 4*Nk + 3] ^ tmp3;
+ }
+ }
+
+
+ public function getBlockSize():uint
+ {
+ return 16;
+ }
+
+ // encrypt one 128 bit block
+ public function encrypt(block:ByteArray, index:uint=0):void
+ {
+ var round:uint;
+ state.position=0;
+ state.writeBytes(block, index, Nb*4);
+
+ addRoundKey(key, 0);
+ for ( round = 1; round < Nr + 1; round++ ) {
+ if (round < Nr) {
+ mixSubColumns();
+ } else {
+ shiftRows();
+ }
+ addRoundKey(key, round * Nb * 4);
+ }
+
+ block.position=index;
+ block.writeBytes(state);
+ }
+
+ public function decrypt(block:ByteArray, index:uint=0):void
+ {
+ var round:uint;
+ state.position=0;
+ state.writeBytes(block, index, Nb*4);
+
+ addRoundKey(key, Nr*Nb*4);
+ invShiftRows();
+ for( round = Nr; round--; )
+ {
+ addRoundKey( key, round*Nb*4);
+ if (round) {
+ invMixSubColumns();
+ }
+ }
+
+ block.position=index;
+ block.writeBytes(state);
+ }
+
+ public function dispose():void {
+ var i:uint;
+ var r:Random = new Random;
+ for (i=0;i<key.length;i++) {
+ key[i] = r.nextByte();
+ }
+ Nr = r.nextByte();
+ for (i=0;i<state.length;i++) {
+ state[i] = r.nextByte();
+ }
+ for (i=0;i<tmp.length;i++) {
+ tmp[i] = r.nextByte();
+ }
+ key.length=0;
+ keyLength=0;
+ state.length=0;
+ tmp.length=0;
+ key = null;
+ state = null;
+ tmp = null;
+ Nr = 0;
+ Memory.gc();
+ }
+
+ // exchanges columns in each of 4 rows
+ // row0 - unchanged, row1- shifted left 1,
+ // row2 - shifted left 2 and row3 - shifted left 3
+ protected function shiftRows():void
+ {
+ var tmp:uint;
+
+ // just substitute row 0
+ state[0] = Sbox[state[0]]; state[4] = Sbox[state[4]];
+ state[8] = Sbox[state[8]]; state[12] = Sbox[state[12]];
+
+ // rotate row 1
+ tmp = Sbox[state[1]]; state[1] = Sbox[state[5]];
+ state[5] = Sbox[state[9]]; state[9] = Sbox[state[13]]; state[13] = tmp;
+
+ // rotate row 2
+ tmp = Sbox[state[2]]; state[2] = Sbox[state[10]]; state[10] = tmp;
+ tmp = Sbox[state[6]]; state[6] = Sbox[state[14]]; state[14] = tmp;
+
+ // rotate row 3
+ tmp = Sbox[state[15]]; state[15] = Sbox[state[11]];
+ state[11] = Sbox[state[7]]; state[7] = Sbox[state[3]]; state[3] = tmp;
+ }
+
+ // restores columns in each of 4 rows
+ // row0 - unchanged, row1- shifted right 1,
+ // row2 - shifted right 2 and row3 - shifted right 3
+ protected function invShiftRows ():void
+ {
+ var tmp:uint;
+
+ // restore row 0
+ state[0] = InvSbox[state[0]]; state[4] = InvSbox[state[4]];
+ state[8] = InvSbox[state[8]]; state[12] = InvSbox[state[12]];
+
+ // restore row 1
+ tmp = InvSbox[state[13]]; state[13] = InvSbox[state[9]];
+ state[9] = InvSbox[state[5]]; state[5] = InvSbox[state[1]]; state[1] = tmp;
+
+ // restore row 2
+ tmp = InvSbox[state[2]]; state[2] = InvSbox[state[10]]; state[10] = tmp;
+ tmp = InvSbox[state[6]]; state[6] = InvSbox[state[14]]; state[14] = tmp;
+
+ // restore row 3
+ tmp = InvSbox[state[3]]; state[3] = InvSbox[state[7]];
+ state[7] = InvSbox[state[11]]; state[11] = InvSbox[state[15]]; state[15] = tmp;
+ }
+
+ // recombine and mix each row in a column
+ protected function mixSubColumns ():void
+ {
+ tmp.length=0;
+
+ // mixing column 0
+ tmp[0] = Xtime2Sbox[state[0]] ^ Xtime3Sbox[state[5]] ^ Sbox[state[10]] ^ Sbox[state[15]];
+ tmp[1] = Sbox[state[0]] ^ Xtime2Sbox[state[5]] ^ Xtime3Sbox[state[10]] ^ Sbox[state[15]];
+ tmp[2] = Sbox[state[0]] ^ Sbox[state[5]] ^ Xtime2Sbox[state[10]] ^ Xtime3Sbox[state[15]];
+ tmp[3] = Xtime3Sbox[state[0]] ^ Sbox[state[5]] ^ Sbox[state[10]] ^ Xtime2Sbox[state[15]];
+
+ // mixing column 1
+ tmp[4] = Xtime2Sbox[state[4]] ^ Xtime3Sbox[state[9]] ^ Sbox[state[14]] ^ Sbox[state[3]];
+ tmp[5] = Sbox[state[4]] ^ Xtime2Sbox[state[9]] ^ Xtime3Sbox[state[14]] ^ Sbox[state[3]];
+ tmp[6] = Sbox[state[4]] ^ Sbox[state[9]] ^ Xtime2Sbox[state[14]] ^ Xtime3Sbox[state[3]];
+ tmp[7] = Xtime3Sbox[state[4]] ^ Sbox[state[9]] ^ Sbox[state[14]] ^ Xtime2Sbox[state[3]];
+
+ // mixing column 2
+ tmp[8] = Xtime2Sbox[state[8]] ^ Xtime3Sbox[state[13]] ^ Sbox[state[2]] ^ Sbox[state[7]];
+ tmp[9] = Sbox[state[8]] ^ Xtime2Sbox[state[13]] ^ Xtime3Sbox[state[2]] ^ Sbox[state[7]];
+ tmp[10] = Sbox[state[8]] ^ Sbox[state[13]] ^ Xtime2Sbox[state[2]] ^ Xtime3Sbox[state[7]];
+ tmp[11] = Xtime3Sbox[state[8]] ^ Sbox[state[13]] ^ Sbox[state[2]] ^ Xtime2Sbox[state[7]];
+
+ // mixing column 3
+ tmp[12] = Xtime2Sbox[state[12]] ^ Xtime3Sbox[state[1]] ^ Sbox[state[6]] ^ Sbox[state[11]];
+ tmp[13] = Sbox[state[12]] ^ Xtime2Sbox[state[1]] ^ Xtime3Sbox[state[6]] ^ Sbox[state[11]];
+ tmp[14] = Sbox[state[12]] ^ Sbox[state[1]] ^ Xtime2Sbox[state[6]] ^ Xtime3Sbox[state[11]];
+ tmp[15] = Xtime3Sbox[state[12]] ^ Sbox[state[1]] ^ Sbox[state[6]] ^ Xtime2Sbox[state[11]];
+
+ state.position=0;
+ state.writeBytes(tmp, 0, Nb*4);
+ }
+
+ // restore and un-mix each row in a column
+ protected function invMixSubColumns ():void
+ {
+ tmp.length=0;
+ var i:uint;
+
+ // restore column 0
+ tmp[0] = XtimeE[state[0]] ^ XtimeB[state[1]] ^ XtimeD[state[2]] ^ Xtime9[state[3]];
+ tmp[5] = Xtime9[state[0]] ^ XtimeE[state[1]] ^ XtimeB[state[2]] ^ XtimeD[state[3]];
+ tmp[10] = XtimeD[state[0]] ^ Xtime9[state[1]] ^ XtimeE[state[2]] ^ XtimeB[state[3]];
+ tmp[15] = XtimeB[state[0]] ^ XtimeD[state[1]] ^ Xtime9[state[2]] ^ XtimeE[state[3]];
+
+ // restore column 1
+ tmp[4] = XtimeE[state[4]] ^ XtimeB[state[5]] ^ XtimeD[state[6]] ^ Xtime9[state[7]];
+ tmp[9] = Xtime9[state[4]] ^ XtimeE[state[5]] ^ XtimeB[state[6]] ^ XtimeD[state[7]];
+ tmp[14] = XtimeD[state[4]] ^ Xtime9[state[5]] ^ XtimeE[state[6]] ^ XtimeB[state[7]];
+ tmp[3] = XtimeB[state[4]] ^ XtimeD[state[5]] ^ Xtime9[state[6]] ^ XtimeE[state[7]];
+
+ // restore column 2
+ tmp[8] = XtimeE[state[8]] ^ XtimeB[state[9]] ^ XtimeD[state[10]] ^ Xtime9[state[11]];
+ tmp[13] = Xtime9[state[8]] ^ XtimeE[state[9]] ^ XtimeB[state[10]] ^ XtimeD[state[11]];
+ tmp[2] = XtimeD[state[8]] ^ Xtime9[state[9]] ^ XtimeE[state[10]] ^ XtimeB[state[11]];
+ tmp[7] = XtimeB[state[8]] ^ XtimeD[state[9]] ^ Xtime9[state[10]] ^ XtimeE[state[11]];
+
+ // restore column 3
+ tmp[12] = XtimeE[state[12]] ^ XtimeB[state[13]] ^ XtimeD[state[14]] ^ Xtime9[state[15]];
+ tmp[1] = Xtime9[state[12]] ^ XtimeE[state[13]] ^ XtimeB[state[14]] ^ XtimeD[state[15]];
+ tmp[6] = XtimeD[state[12]] ^ Xtime9[state[13]] ^ XtimeE[state[14]] ^ XtimeB[state[15]];
+ tmp[11] = XtimeB[state[12]] ^ XtimeD[state[13]] ^ Xtime9[state[14]] ^ XtimeE[state[15]];
+
+ for( i=0; i < 4 * Nb; i++ )
+ state[i] = InvSbox[tmp[i]];
+ }
+
+ // encrypt/decrypt columns of the key
+ protected function addRoundKey (key:ByteArray, offset:uint):void
+ {
+ var idx:uint;
+
+ for( idx = 0; idx < 16; idx++ )
+ state[idx] ^= key[idx+offset];
+ }
+
+ public function toString():String {
+ return "aes"+(8*keyLength);
+ }
+ }
+}
diff --git a/flash-src/third-party/com/hurlant/crypto/symmetric/BlowFishKey.as b/flash-src/third-party/com/hurlant/crypto/symmetric/BlowFishKey.as new file mode 100644 index 0000000..c3350cb --- /dev/null +++ b/flash-src/third-party/com/hurlant/crypto/symmetric/BlowFishKey.as @@ -0,0 +1,375 @@ +/**
+ * BlowFishKey
+ *
+ * An Actionscript 3 implementation of the BlowFish encryption algorithm,
+ * as documented at http://www.schneier.com/blowfish.html
+ * Copyright (c) 2007 Henri Torgemane
+ *
+ * Derived from:
+ * The Bouncy Castle Crypto package,
+ * Copyright (c) 2000-2004 The Legion Of The Bouncy Castle
+ * (http://www.bouncycastle.org)
+ *
+ * See LICENSE.txt for full license information.
+ */
+package com.hurlant.crypto.symmetric
+{
+ import flash.utils.ByteArray;
+ import com.hurlant.util.Memory;
+
+ public class BlowFishKey implements ISymmetricKey
+ {
+
+ private static const KP:Array = [ 0x243F6A88, 0x85A308D3, 0x13198A2E, 0x03707344, 0xA4093822, 0x299F31D0,
+ 0x082EFA98, 0xEC4E6C89, 0x452821E6, 0x38D01377, 0xBE5466CF, 0x34E90C6C, 0xC0AC29B7, 0xC97C50DD, 0x3F84D5B5,
+ 0xB5470917, 0x9216D5D9, 0x8979FB1B ];
+
+ private static const KS0:Array = [ 0xD1310BA6, 0x98DFB5AC, 0x2FFD72DB, 0xD01ADFB7, 0xB8E1AFED, 0x6A267E96, 0xBA7C9045, 0xF12C7F99, 0x24A19947,
+ 0xB3916CF7, 0x0801F2E2, 0x858EFC16, 0x636920D8, 0x71574E69, 0xA458FEA3, 0xF4933D7E, 0x0D95748F, 0x728EB658,
+ 0x718BCD58, 0x82154AEE, 0x7B54A41D, 0xC25A59B5, 0x9C30D539, 0x2AF26013, 0xC5D1B023, 0x286085F0, 0xCA417918,
+ 0xB8DB38EF, 0x8E79DCB0, 0x603A180E, 0x6C9E0E8B, 0xB01E8A3E, 0xD71577C1, 0xBD314B27, 0x78AF2FDA, 0x55605C60,
+ 0xE65525F3, 0xAA55AB94, 0x57489862, 0x63E81440, 0x55CA396A, 0x2AAB10B6, 0xB4CC5C34, 0x1141E8CE, 0xA15486AF,
+ 0x7C72E993, 0xB3EE1411, 0x636FBC2A, 0x2BA9C55D, 0x741831F6, 0xCE5C3E16, 0x9B87931E, 0xAFD6BA33, 0x6C24CF5C,
+ 0x7A325381, 0x28958677, 0x3B8F4898, 0x6B4BB9AF, 0xC4BFE81B, 0x66282193, 0x61D809CC, 0xFB21A991, 0x487CAC60,
+ 0x5DEC8032, 0xEF845D5D, 0xE98575B1, 0xDC262302, 0xEB651B88, 0x23893E81, 0xD396ACC5, 0x0F6D6FF3, 0x83F44239,
+ 0x2E0B4482, 0xA4842004, 0x69C8F04A, 0x9E1F9B5E, 0x21C66842, 0xF6E96C9A, 0x670C9C61, 0xABD388F0, 0x6A51A0D2,
+ 0xD8542F68, 0x960FA728, 0xAB5133A3, 0x6EEF0B6C, 0x137A3BE4, 0xBA3BF050, 0x7EFB2A98, 0xA1F1651D, 0x39AF0176,
+ 0x66CA593E, 0x82430E88, 0x8CEE8619, 0x456F9FB4, 0x7D84A5C3, 0x3B8B5EBE, 0xE06F75D8, 0x85C12073, 0x401A449F,
+ 0x56C16AA6, 0x4ED3AA62, 0x363F7706, 0x1BFEDF72, 0x429B023D, 0x37D0D724, 0xD00A1248, 0xDB0FEAD3, 0x49F1C09B,
+ 0x075372C9, 0x80991B7B, 0x25D479D8, 0xF6E8DEF7, 0xE3FE501A, 0xB6794C3B, 0x976CE0BD, 0x04C006BA, 0xC1A94FB6,
+ 0x409F60C4, 0x5E5C9EC2, 0x196A2463, 0x68FB6FAF, 0x3E6C53B5, 0x1339B2EB, 0x3B52EC6F, 0x6DFC511F, 0x9B30952C,
+ 0xCC814544, 0xAF5EBD09, 0xBEE3D004, 0xDE334AFD, 0x660F2807, 0x192E4BB3, 0xC0CBA857, 0x45C8740F, 0xD20B5F39,
+ 0xB9D3FBDB, 0x5579C0BD, 0x1A60320A, 0xD6A100C6, 0x402C7279, 0x679F25FE, 0xFB1FA3CC, 0x8EA5E9F8, 0xDB3222F8,
+ 0x3C7516DF, 0xFD616B15, 0x2F501EC8, 0xAD0552AB, 0x323DB5FA, 0xFD238760, 0x53317B48, 0x3E00DF82, 0x9E5C57BB,
+ 0xCA6F8CA0, 0x1A87562E, 0xDF1769DB, 0xD542A8F6, 0x287EFFC3, 0xAC6732C6, 0x8C4F5573, 0x695B27B0, 0xBBCA58C8,
+ 0xE1FFA35D, 0xB8F011A0, 0x10FA3D98, 0xFD2183B8, 0x4AFCB56C, 0x2DD1D35B, 0x9A53E479, 0xB6F84565, 0xD28E49BC,
+ 0x4BFB9790, 0xE1DDF2DA, 0xA4CB7E33, 0x62FB1341, 0xCEE4C6E8, 0xEF20CADA, 0x36774C01, 0xD07E9EFE, 0x2BF11FB4,
+ 0x95DBDA4D, 0xAE909198, 0xEAAD8E71, 0x6B93D5A0, 0xD08ED1D0, 0xAFC725E0, 0x8E3C5B2F, 0x8E7594B7, 0x8FF6E2FB,
+ 0xF2122B64, 0x8888B812, 0x900DF01C, 0x4FAD5EA0, 0x688FC31C, 0xD1CFF191, 0xB3A8C1AD, 0x2F2F2218, 0xBE0E1777,
+ 0xEA752DFE, 0x8B021FA1, 0xE5A0CC0F, 0xB56F74E8, 0x18ACF3D6, 0xCE89E299, 0xB4A84FE0, 0xFD13E0B7, 0x7CC43B81,
+ 0xD2ADA8D9, 0x165FA266, 0x80957705, 0x93CC7314, 0x211A1477, 0xE6AD2065, 0x77B5FA86, 0xC75442F5, 0xFB9D35CF,
+ 0xEBCDAF0C, 0x7B3E89A0, 0xD6411BD3, 0xAE1E7E49, 0x00250E2D, 0x2071B35E, 0x226800BB, 0x57B8E0AF, 0x2464369B,
+ 0xF009B91E, 0x5563911D, 0x59DFA6AA, 0x78C14389, 0xD95A537F, 0x207D5BA2, 0x02E5B9C5, 0x83260376, 0x6295CFA9,
+ 0x11C81968, 0x4E734A41, 0xB3472DCA, 0x7B14A94A, 0x1B510052, 0x9A532915, 0xD60F573F, 0xBC9BC6E4, 0x2B60A476,
+ 0x81E67400, 0x08BA6FB5, 0x571BE91F, 0xF296EC6B, 0x2A0DD915, 0xB6636521, 0xE7B9F9B6, 0xFF34052E, 0xC5855664,
+ 0x53B02D5D, 0xA99F8FA1, 0x08BA4799, 0x6E85076A ];
+
+ private static const KS1:Array = [ 0x4B7A70E9, 0xB5B32944, 0xDB75092E, 0xC4192623, 0xAD6EA6B0, 0x49A7DF7D, 0x9CEE60B8, 0x8FEDB266, 0xECAA8C71,
+ 0x699A17FF, 0x5664526C, 0xC2B19EE1, 0x193602A5, 0x75094C29, 0xA0591340, 0xE4183A3E, 0x3F54989A, 0x5B429D65,
+ 0x6B8FE4D6, 0x99F73FD6, 0xA1D29C07, 0xEFE830F5, 0x4D2D38E6, 0xF0255DC1, 0x4CDD2086, 0x8470EB26, 0x6382E9C6,
+ 0x021ECC5E, 0x09686B3F, 0x3EBAEFC9, 0x3C971814, 0x6B6A70A1, 0x687F3584, 0x52A0E286, 0xB79C5305, 0xAA500737,
+ 0x3E07841C, 0x7FDEAE5C, 0x8E7D44EC, 0x5716F2B8, 0xB03ADA37, 0xF0500C0D, 0xF01C1F04, 0x0200B3FF, 0xAE0CF51A,
+ 0x3CB574B2, 0x25837A58, 0xDC0921BD, 0xD19113F9, 0x7CA92FF6, 0x94324773, 0x22F54701, 0x3AE5E581, 0x37C2DADC,
+ 0xC8B57634, 0x9AF3DDA7, 0xA9446146, 0x0FD0030E, 0xECC8C73E, 0xA4751E41, 0xE238CD99, 0x3BEA0E2F, 0x3280BBA1,
+ 0x183EB331, 0x4E548B38, 0x4F6DB908, 0x6F420D03, 0xF60A04BF, 0x2CB81290, 0x24977C79, 0x5679B072, 0xBCAF89AF,
+ 0xDE9A771F, 0xD9930810, 0xB38BAE12, 0xDCCF3F2E, 0x5512721F, 0x2E6B7124, 0x501ADDE6, 0x9F84CD87, 0x7A584718,
+ 0x7408DA17, 0xBC9F9ABC, 0xE94B7D8C, 0xEC7AEC3A, 0xDB851DFA, 0x63094366, 0xC464C3D2, 0xEF1C1847, 0x3215D908,
+ 0xDD433B37, 0x24C2BA16, 0x12A14D43, 0x2A65C451, 0x50940002, 0x133AE4DD, 0x71DFF89E, 0x10314E55, 0x81AC77D6,
+ 0x5F11199B, 0x043556F1, 0xD7A3C76B, 0x3C11183B, 0x5924A509, 0xF28FE6ED, 0x97F1FBFA, 0x9EBABF2C, 0x1E153C6E,
+ 0x86E34570, 0xEAE96FB1, 0x860E5E0A, 0x5A3E2AB3, 0x771FE71C, 0x4E3D06FA, 0x2965DCB9, 0x99E71D0F, 0x803E89D6,
+ 0x5266C825, 0x2E4CC978, 0x9C10B36A, 0xC6150EBA, 0x94E2EA78, 0xA5FC3C53, 0x1E0A2DF4, 0xF2F74EA7, 0x361D2B3D,
+ 0x1939260F, 0x19C27960, 0x5223A708, 0xF71312B6, 0xEBADFE6E, 0xEAC31F66, 0xE3BC4595, 0xA67BC883, 0xB17F37D1,
+ 0x018CFF28, 0xC332DDEF, 0xBE6C5AA5, 0x65582185, 0x68AB9802, 0xEECEA50F, 0xDB2F953B, 0x2AEF7DAD, 0x5B6E2F84,
+ 0x1521B628, 0x29076170, 0xECDD4775, 0x619F1510, 0x13CCA830, 0xEB61BD96, 0x0334FE1E, 0xAA0363CF, 0xB5735C90,
+ 0x4C70A239, 0xD59E9E0B, 0xCBAADE14, 0xEECC86BC, 0x60622CA7, 0x9CAB5CAB, 0xB2F3846E, 0x648B1EAF, 0x19BDF0CA,
+ 0xA02369B9, 0x655ABB50, 0x40685A32, 0x3C2AB4B3, 0x319EE9D5, 0xC021B8F7, 0x9B540B19, 0x875FA099, 0x95F7997E,
+ 0x623D7DA8, 0xF837889A, 0x97E32D77, 0x11ED935F, 0x16681281, 0x0E358829, 0xC7E61FD6, 0x96DEDFA1, 0x7858BA99,
+ 0x57F584A5, 0x1B227263, 0x9B83C3FF, 0x1AC24696, 0xCDB30AEB, 0x532E3054, 0x8FD948E4, 0x6DBC3128, 0x58EBF2EF,
+ 0x34C6FFEA, 0xFE28ED61, 0xEE7C3C73, 0x5D4A14D9, 0xE864B7E3, 0x42105D14, 0x203E13E0, 0x45EEE2B6, 0xA3AAABEA,
+ 0xDB6C4F15, 0xFACB4FD0, 0xC742F442, 0xEF6ABBB5, 0x654F3B1D, 0x41CD2105, 0xD81E799E, 0x86854DC7, 0xE44B476A,
+ 0x3D816250, 0xCF62A1F2, 0x5B8D2646, 0xFC8883A0, 0xC1C7B6A3, 0x7F1524C3, 0x69CB7492, 0x47848A0B, 0x5692B285,
+ 0x095BBF00, 0xAD19489D, 0x1462B174, 0x23820E00, 0x58428D2A, 0x0C55F5EA, 0x1DADF43E, 0x233F7061, 0x3372F092,
+ 0x8D937E41, 0xD65FECF1, 0x6C223BDB, 0x7CDE3759, 0xCBEE7460, 0x4085F2A7, 0xCE77326E, 0xA6078084, 0x19F8509E,
+ 0xE8EFD855, 0x61D99735, 0xA969A7AA, 0xC50C06C2, 0x5A04ABFC, 0x800BCADC, 0x9E447A2E, 0xC3453484, 0xFDD56705,
+ 0x0E1E9EC9, 0xDB73DBD3, 0x105588CD, 0x675FDA79, 0xE3674340, 0xC5C43465, 0x713E38D8, 0x3D28F89E, 0xF16DFF20,
+ 0x153E21E7, 0x8FB03D4A, 0xE6E39F2B, 0xDB83ADF7 ];
+
+ private static const KS2:Array = [ 0xE93D5A68, 0x948140F7, 0xF64C261C, 0x94692934, 0x411520F7, 0x7602D4F7, 0xBCF46B2E, 0xD4A20068, 0xD4082471,
+ 0x3320F46A, 0x43B7D4B7, 0x500061AF, 0x1E39F62E, 0x97244546, 0x14214F74, 0xBF8B8840, 0x4D95FC1D, 0x96B591AF,
+ 0x70F4DDD3, 0x66A02F45, 0xBFBC09EC, 0x03BD9785, 0x7FAC6DD0, 0x31CB8504, 0x96EB27B3, 0x55FD3941, 0xDA2547E6,
+ 0xABCA0A9A, 0x28507825, 0x530429F4, 0x0A2C86DA, 0xE9B66DFB, 0x68DC1462, 0xD7486900, 0x680EC0A4, 0x27A18DEE,
+ 0x4F3FFEA2, 0xE887AD8C, 0xB58CE006, 0x7AF4D6B6, 0xAACE1E7C, 0xD3375FEC, 0xCE78A399, 0x406B2A42, 0x20FE9E35,
+ 0xD9F385B9, 0xEE39D7AB, 0x3B124E8B, 0x1DC9FAF7, 0x4B6D1856, 0x26A36631, 0xEAE397B2, 0x3A6EFA74, 0xDD5B4332,
+ 0x6841E7F7, 0xCA7820FB, 0xFB0AF54E, 0xD8FEB397, 0x454056AC, 0xBA489527, 0x55533A3A, 0x20838D87, 0xFE6BA9B7,
+ 0xD096954B, 0x55A867BC, 0xA1159A58, 0xCCA92963, 0x99E1DB33, 0xA62A4A56, 0x3F3125F9, 0x5EF47E1C, 0x9029317C,
+ 0xFDF8E802, 0x04272F70, 0x80BB155C, 0x05282CE3, 0x95C11548, 0xE4C66D22, 0x48C1133F, 0xC70F86DC, 0x07F9C9EE,
+ 0x41041F0F, 0x404779A4, 0x5D886E17, 0x325F51EB, 0xD59BC0D1, 0xF2BCC18F, 0x41113564, 0x257B7834, 0x602A9C60,
+ 0xDFF8E8A3, 0x1F636C1B, 0x0E12B4C2, 0x02E1329E, 0xAF664FD1, 0xCAD18115, 0x6B2395E0, 0x333E92E1, 0x3B240B62,
+ 0xEEBEB922, 0x85B2A20E, 0xE6BA0D99, 0xDE720C8C, 0x2DA2F728, 0xD0127845, 0x95B794FD, 0x647D0862, 0xE7CCF5F0,
+ 0x5449A36F, 0x877D48FA, 0xC39DFD27, 0xF33E8D1E, 0x0A476341, 0x992EFF74, 0x3A6F6EAB, 0xF4F8FD37, 0xA812DC60,
+ 0xA1EBDDF8, 0x991BE14C, 0xDB6E6B0D, 0xC67B5510, 0x6D672C37, 0x2765D43B, 0xDCD0E804, 0xF1290DC7, 0xCC00FFA3,
+ 0xB5390F92, 0x690FED0B, 0x667B9FFB, 0xCEDB7D9C, 0xA091CF0B, 0xD9155EA3, 0xBB132F88, 0x515BAD24, 0x7B9479BF,
+ 0x763BD6EB, 0x37392EB3, 0xCC115979, 0x8026E297, 0xF42E312D, 0x6842ADA7, 0xC66A2B3B, 0x12754CCC, 0x782EF11C,
+ 0x6A124237, 0xB79251E7, 0x06A1BBE6, 0x4BFB6350, 0x1A6B1018, 0x11CAEDFA, 0x3D25BDD8, 0xE2E1C3C9, 0x44421659,
+ 0x0A121386, 0xD90CEC6E, 0xD5ABEA2A, 0x64AF674E, 0xDA86A85F, 0xBEBFE988, 0x64E4C3FE, 0x9DBC8057, 0xF0F7C086,
+ 0x60787BF8, 0x6003604D, 0xD1FD8346, 0xF6381FB0, 0x7745AE04, 0xD736FCCC, 0x83426B33, 0xF01EAB71, 0xB0804187,
+ 0x3C005E5F, 0x77A057BE, 0xBDE8AE24, 0x55464299, 0xBF582E61, 0x4E58F48F, 0xF2DDFDA2, 0xF474EF38, 0x8789BDC2,
+ 0x5366F9C3, 0xC8B38E74, 0xB475F255, 0x46FCD9B9, 0x7AEB2661, 0x8B1DDF84, 0x846A0E79, 0x915F95E2, 0x466E598E,
+ 0x20B45770, 0x8CD55591, 0xC902DE4C, 0xB90BACE1, 0xBB8205D0, 0x11A86248, 0x7574A99E, 0xB77F19B6, 0xE0A9DC09,
+ 0x662D09A1, 0xC4324633, 0xE85A1F02, 0x09F0BE8C, 0x4A99A025, 0x1D6EFE10, 0x1AB93D1D, 0x0BA5A4DF, 0xA186F20F,
+ 0x2868F169, 0xDCB7DA83, 0x573906FE, 0xA1E2CE9B, 0x4FCD7F52, 0x50115E01, 0xA70683FA, 0xA002B5C4, 0x0DE6D027,
+ 0x9AF88C27, 0x773F8641, 0xC3604C06, 0x61A806B5, 0xF0177A28, 0xC0F586E0, 0x006058AA, 0x30DC7D62, 0x11E69ED7,
+ 0x2338EA63, 0x53C2DD94, 0xC2C21634, 0xBBCBEE56, 0x90BCB6DE, 0xEBFC7DA1, 0xCE591D76, 0x6F05E409, 0x4B7C0188,
+ 0x39720A3D, 0x7C927C24, 0x86E3725F, 0x724D9DB9, 0x1AC15BB4, 0xD39EB8FC, 0xED545578, 0x08FCA5B5, 0xD83D7CD3,
+ 0x4DAD0FC4, 0x1E50EF5E, 0xB161E6F8, 0xA28514D9, 0x6C51133C, 0x6FD5C7E7, 0x56E14EC4, 0x362ABFCE, 0xDDC6C837,
+ 0xD79A3234, 0x92638212, 0x670EFA8E, 0x406000E0 ];
+
+ private static const KS3:Array = [ 0x3A39CE37, 0xD3FAF5CF, 0xABC27737, 0x5AC52D1B, 0x5CB0679E, 0x4FA33742, 0xD3822740, 0x99BC9BBE, 0xD5118E9D,
+ 0xBF0F7315, 0xD62D1C7E, 0xC700C47B, 0xB78C1B6B, 0x21A19045, 0xB26EB1BE, 0x6A366EB4, 0x5748AB2F, 0xBC946E79,
+ 0xC6A376D2, 0x6549C2C8, 0x530FF8EE, 0x468DDE7D, 0xD5730A1D, 0x4CD04DC6, 0x2939BBDB, 0xA9BA4650, 0xAC9526E8,
+ 0xBE5EE304, 0xA1FAD5F0, 0x6A2D519A, 0x63EF8CE2, 0x9A86EE22, 0xC089C2B8, 0x43242EF6, 0xA51E03AA, 0x9CF2D0A4,
+ 0x83C061BA, 0x9BE96A4D, 0x8FE51550, 0xBA645BD6, 0x2826A2F9, 0xA73A3AE1, 0x4BA99586, 0xEF5562E9, 0xC72FEFD3,
+ 0xF752F7DA, 0x3F046F69, 0x77FA0A59, 0x80E4A915, 0x87B08601, 0x9B09E6AD, 0x3B3EE593, 0xE990FD5A, 0x9E34D797,
+ 0x2CF0B7D9, 0x022B8B51, 0x96D5AC3A, 0x017DA67D, 0xD1CF3ED6, 0x7C7D2D28, 0x1F9F25CF, 0xADF2B89B, 0x5AD6B472,
+ 0x5A88F54C, 0xE029AC71, 0xE019A5E6, 0x47B0ACFD, 0xED93FA9B, 0xE8D3C48D, 0x283B57CC, 0xF8D56629, 0x79132E28,
+ 0x785F0191, 0xED756055, 0xF7960E44, 0xE3D35E8C, 0x15056DD4, 0x88F46DBA, 0x03A16125, 0x0564F0BD, 0xC3EB9E15,
+ 0x3C9057A2, 0x97271AEC, 0xA93A072A, 0x1B3F6D9B, 0x1E6321F5, 0xF59C66FB, 0x26DCF319, 0x7533D928, 0xB155FDF5,
+ 0x03563482, 0x8ABA3CBB, 0x28517711, 0xC20AD9F8, 0xABCC5167, 0xCCAD925F, 0x4DE81751, 0x3830DC8E, 0x379D5862,
+ 0x9320F991, 0xEA7A90C2, 0xFB3E7BCE, 0x5121CE64, 0x774FBE32, 0xA8B6E37E, 0xC3293D46, 0x48DE5369, 0x6413E680,
+ 0xA2AE0810, 0xDD6DB224, 0x69852DFD, 0x09072166, 0xB39A460A, 0x6445C0DD, 0x586CDECF, 0x1C20C8AE, 0x5BBEF7DD,
+ 0x1B588D40, 0xCCD2017F, 0x6BB4E3BB, 0xDDA26A7E, 0x3A59FF45, 0x3E350A44, 0xBCB4CDD5, 0x72EACEA8, 0xFA6484BB,
+ 0x8D6612AE, 0xBF3C6F47, 0xD29BE463, 0x542F5D9E, 0xAEC2771B, 0xF64E6370, 0x740E0D8D, 0xE75B1357, 0xF8721671,
+ 0xAF537D5D, 0x4040CB08, 0x4EB4E2CC, 0x34D2466A, 0x0115AF84, 0xE1B00428, 0x95983A1D, 0x06B89FB4, 0xCE6EA048,
+ 0x6F3F3B82, 0x3520AB82, 0x011A1D4B, 0x277227F8, 0x611560B1, 0xE7933FDC, 0xBB3A792B, 0x344525BD, 0xA08839E1,
+ 0x51CE794B, 0x2F32C9B7, 0xA01FBAC9, 0xE01CC87E, 0xBCC7D1F6, 0xCF0111C3, 0xA1E8AAC7, 0x1A908749, 0xD44FBD9A,
+ 0xD0DADECB, 0xD50ADA38, 0x0339C32A, 0xC6913667, 0x8DF9317C, 0xE0B12B4F, 0xF79E59B7, 0x43F5BB3A, 0xF2D519FF,
+ 0x27D9459C, 0xBF97222C, 0x15E6FC2A, 0x0F91FC71, 0x9B941525, 0xFAE59361, 0xCEB69CEB, 0xC2A86459, 0x12BAA8D1,
+ 0xB6C1075E, 0xE3056A0C, 0x10D25065, 0xCB03A442, 0xE0EC6E0E, 0x1698DB3B, 0x4C98A0BE, 0x3278E964, 0x9F1F9532,
+ 0xE0D392DF, 0xD3A0342B, 0x8971F21E, 0x1B0A7441, 0x4BA3348C, 0xC5BE7120, 0xC37632D8, 0xDF359F8D, 0x9B992F2E,
+ 0xE60B6F47, 0x0FE3F11D, 0xE54CDA54, 0x1EDAD891, 0xCE6279CF, 0xCD3E7E6F, 0x1618B166, 0xFD2C1D05, 0x848FD2C5,
+ 0xF6FB2299, 0xF523F357, 0xA6327623, 0x93A83531, 0x56CCCD02, 0xACF08162, 0x5A75EBB5, 0x6E163697, 0x88D273CC,
+ 0xDE966292, 0x81B949D0, 0x4C50901B, 0x71C65614, 0xE6C6C7BD, 0x327A140A, 0x45E1D006, 0xC3F27B9A, 0xC9AA53FD,
+ 0x62A80F00, 0xBB25BFE2, 0x35BDD2F6, 0x71126905, 0xB2040222, 0xB6CBCF7C, 0xCD769C2B, 0x53113EC0, 0x1640E3D3,
+ 0x38ABBD60, 0x2547ADF0, 0xBA38209C, 0xF746CE76, 0x77AFA1C5, 0x20756060, 0x85CBFE4E, 0x8AE88DD8, 0x7AAAF9B0,
+ 0x4CF9AA7E, 0x1948C25C, 0x02FB8A8C, 0x01C36AE4, 0xD6EBE1F9, 0x90D4F869, 0xA65CDEA0, 0x3F09252D, 0xC208E69F,
+ 0xB74E6132, 0xCE77E25B, 0x578FDFE3, 0x3AC372E6 ];
+
+ // ====================================
+ // Useful constants
+ // ====================================
+
+ private static const ROUNDS:uint = 16;
+ private static const BLOCK_SIZE:uint = 8; // bytes = 64 bits
+ private static const SBOX_SK:uint = 256;
+ private static const P_SZ:uint = ROUNDS + 2;
+
+ private var S0:Array;
+ private var S1:Array;
+ private var S2:Array;
+ private var S3:Array; // the s-boxes
+ private var P:Array; // the p-array
+
+ private var key:ByteArray = null;
+
+ public function BlowFishKey(key:ByteArray) {
+ this.key = key;
+ setKey(key);
+ }
+
+ public function getBlockSize():uint
+ {
+ return BLOCK_SIZE;
+ }
+
+ public function decrypt(block:ByteArray, index:uint=0):void
+ {
+ decryptBlock(block, index, block, index);
+ }
+
+ public function dispose():void
+ {
+ var i:uint=0;
+ for (i=0;i<S0.length;i++) { S0[i]=0; }
+ for (i=0;i<S1.length;i++) { S1[i]=0; }
+ for (i=0;i<S2.length;i++) { S2[i]=0; }
+ for (i=0;i<S3.length;i++) { S3[i]=0; }
+ for (i=0;i<P.length;i++) { P[i]=0; }
+ S0 = null;
+ S1 = null;
+ S2 = null;
+ S3 = null;
+ P = null;
+ for (i=0;i<key.length;i++) {
+ key[i]=0;
+ }
+ key.length = 0;
+ key = null;
+ Memory.gc();
+ }
+
+ public function encrypt(block:ByteArray, index:uint=0):void
+ {
+ encryptBlock(block, index, block, index);
+ }
+
+ // ==================================
+ // Private Implementation
+ // ==================================
+
+ private function F(x:uint):uint
+ {
+ return (((S0[(x >>> 24)] + S1[(x >>> 16) & 0xff]) ^ S2[(x >>> 8) & 0xff]) + S3[x & 0xff]);
+ }
+
+ /**
+ * apply the encryption cycle to each value pair in the table.
+ */
+ private function processTable(xl:uint, xr:uint, table:Array):void
+ {
+ var size:uint = table.length;
+
+ for (var s:uint = 0; s < size; s += 2)
+ {
+ xl ^= P[0];
+
+ for (var i:uint = 1; i < ROUNDS; i += 2)
+ {
+ xr ^= F(xl) ^ P[i];
+ xl ^= F(xr) ^ P[i + 1];
+ }
+
+ xr ^= P[ROUNDS + 1];
+
+ table[s] = xr;
+ table[s + 1] = xl;
+
+ xr = xl; // end of cycle swap
+ xl = table[s];
+ }
+ }
+
+ private function setKey(key:ByteArray):void
+ {
+ /*
+ * - comments are from _Applied Crypto_, Schneier, p338 please be
+ * careful comparing the two, AC numbers the arrays from 1, the enclosed
+ * code from 0.
+ *
+ * (1) Initialise the S-boxes and the P-array, with a fixed string This
+ * string contains the hexadecimal digits of pi (3.141...)
+ */
+ S0 = KS0.concat();
+ S1 = KS1.concat();
+ S2 = KS2.concat();
+ S3 = KS3.concat();
+ P = KP.concat();
+
+ /*
+ * (2) Now, XOR P[0] with the first 32 bits of the key, XOR P[1] with
+ * the second 32-bits of the key, and so on for all bits of the key (up
+ * to P[17]). Repeatedly cycle through the key bits until the entire
+ * P-array has been XOR-ed with the key bits
+ */
+ var keyLength:uint= key.length;
+ var keyIndex:uint = 0;
+
+ for (var i:uint = 0; i < P_SZ; i++)
+ {
+ // get the 32 bits of the key, in 4 * 8 bit chunks
+ var data:uint = 0x0000000;
+ for (var j:uint = 0; j < 4; j++)
+ {
+ // create a 32 bit block
+ data = (data << 8) | (key[keyIndex++] & 0xff);
+
+ // wrap when we get to the end of the key
+ if (keyIndex >= keyLength)
+ {
+ keyIndex = 0;
+ }
+ }
+ // XOR the newly created 32 bit chunk onto the P-array
+ P[i] ^= data;
+ }
+
+ /*
+ * (3) Encrypt the all-zero string with the Blowfish algorithm, using
+ * the subkeys described in (1) and (2)
+ *
+ * (4) Replace P1 and P2 with the output of step (3)
+ *
+ * (5) Encrypt the output of step(3) using the Blowfish algorithm, with
+ * the modified subkeys.
+ *
+ * (6) Replace P3 and P4 with the output of step (5)
+ *
+ * (7) Continue the process, replacing all elements of the P-array and
+ * then all four S-boxes in order, with the output of the continuously
+ * changing Blowfish algorithm
+ */
+
+ processTable(0, 0, P);
+ processTable(P[P_SZ - 2], P[P_SZ - 1], S0);
+ processTable(S0[SBOX_SK - 2], S0[SBOX_SK - 1], S1);
+ processTable(S1[SBOX_SK - 2], S1[SBOX_SK - 1], S2);
+ processTable(S2[SBOX_SK - 2], S2[SBOX_SK - 1], S3);
+ }
+
+ /**
+ * Encrypt the given input starting at the given offset and place the result
+ * in the provided buffer starting at the given offset. The input will be an
+ * exact multiple of our blocksize.
+ */
+ private function encryptBlock(src:ByteArray, srcIndex:uint, dst:ByteArray, dstIndex:uint):void
+ {
+ var xl:uint = BytesTo32bits(src, srcIndex);
+ var xr:uint = BytesTo32bits(src, srcIndex + 4);
+
+ xl ^= P[0];
+
+ for (var i:uint = 1; i < ROUNDS; i += 2)
+ {
+ xr ^= F(xl) ^ P[i];
+ xl ^= F(xr) ^ P[i + 1];
+ }
+
+ xr ^= P[ROUNDS + 1];
+
+ Bits32ToBytes(xr, dst, dstIndex);
+ Bits32ToBytes(xl, dst, dstIndex + 4);
+ }
+
+ /**
+ * Decrypt the given input starting at the given offset and place the result
+ * in the provided buffer starting at the given offset. The input will be an
+ * exact multiple of our blocksize.
+ */
+ private function decryptBlock(src:ByteArray, srcIndex:uint, dst:ByteArray, dstIndex:uint):void
+ {
+ var xl:uint = BytesTo32bits(src, srcIndex);
+ var xr:uint = BytesTo32bits(src, srcIndex + 4);
+
+ xl ^= P[ROUNDS + 1];
+
+ for (var i:uint = ROUNDS; i > 0; i -= 2)
+ {
+ xr ^= F(xl) ^ P[i];
+ xl ^= F(xr) ^ P[i - 1];
+ }
+
+ xr ^= P[0];
+
+ Bits32ToBytes(xr, dst, dstIndex);
+ Bits32ToBytes(xl, dst, dstIndex + 4);
+ }
+
+ private function BytesTo32bits(b:ByteArray, i:uint):uint
+ {
+ return ((b[i] & 0xff) << 24) | ((b[i + 1] & 0xff) << 16) | ((b[i + 2] & 0xff) << 8) | ((b[i + 3] & 0xff));
+ }
+
+ private function Bits32ToBytes(i:uint, b:ByteArray, offset:uint):void
+ {
+ b[offset + 3] = i;
+ b[offset + 2] = (i >> 8);
+ b[offset + 1] = (i >> 16);
+ b[offset] = (i >> 24);
+ }
+
+ public function toString():String {
+ return "blowfish";
+ }
+
+ }
+
+}
diff --git a/flash-src/third-party/com/hurlant/crypto/symmetric/CBCMode.as b/flash-src/third-party/com/hurlant/crypto/symmetric/CBCMode.as new file mode 100644 index 0000000..e3781be --- /dev/null +++ b/flash-src/third-party/com/hurlant/crypto/symmetric/CBCMode.as @@ -0,0 +1,55 @@ +/**
+ * CBCMode
+ *
+ * An ActionScript 3 implementation of the CBC confidentiality mode
+ * Copyright (c) 2007 Henri Torgemane
+ *
+ * See LICENSE.txt for full license information.
+ */
+package com.hurlant.crypto.symmetric
+{
+ import flash.utils.ByteArray;
+
+ /**
+ * CBC confidentiality mode. why not.
+ */
+ public class CBCMode extends IVMode implements IMode
+ {
+
+ public function CBCMode(key:ISymmetricKey, padding:IPad = null) {
+ super(key, padding);
+ }
+
+ public function encrypt(src:ByteArray):void {
+ padding.pad(src);
+ var vector:ByteArray = getIV4e();
+ for (var i:uint=0;i<src.length;i+=blockSize) {
+ for (var j:uint=0;j<blockSize;j++) {
+ src[i+j] ^= vector[j];
+ }
+ key.encrypt(src, i);
+ vector.position=0;
+ vector.writeBytes(src, i, blockSize);
+ }
+ }
+ public function decrypt(src:ByteArray):void {
+ var vector:ByteArray = getIV4d();
+ var tmp:ByteArray = new ByteArray;
+ for (var i:uint=0;i<src.length;i+=blockSize) {
+ tmp.position=0;
+ tmp.writeBytes(src, i, blockSize);
+ key.decrypt(src, i);
+ for (var j:uint=0;j<blockSize;j++) {
+ src[i+j] ^= vector[j];
+ }
+ vector.position=0;
+ vector.writeBytes(tmp, 0, blockSize);
+ }
+ padding.unpad(src);
+ }
+
+ public function toString():String {
+ return key.toString()+"-cbc";
+ }
+ }
+}
diff --git a/flash-src/third-party/com/hurlant/crypto/symmetric/CFB8Mode.as b/flash-src/third-party/com/hurlant/crypto/symmetric/CFB8Mode.as new file mode 100644 index 0000000..9baa284 --- /dev/null +++ b/flash-src/third-party/com/hurlant/crypto/symmetric/CFB8Mode.as @@ -0,0 +1,61 @@ +/**
+ * CFB8Mode
+ *
+ * An ActionScript 3 implementation of the CFB-8 confidentiality mode
+ * Copyright (c) 2007 Henri Torgemane
+ *
+ * See LICENSE.txt for full license information.
+ */
+package com.hurlant.crypto.symmetric
+{
+ import com.hurlant.crypto.tests.TestCase;
+ import flash.utils.ByteArray;
+
+ /**
+ *
+ * Note: The constructor accepts an optional padding argument, but ignores it otherwise.
+ */
+ public class CFB8Mode extends IVMode implements IMode
+ {
+ public function CFB8Mode(key:ISymmetricKey, padding:IPad = null) {
+ super(key, null);
+ }
+
+ public function encrypt(src:ByteArray):void {
+ var vector:ByteArray = getIV4e();
+ var tmp:ByteArray = new ByteArray;
+ for (var i:uint=0;i<src.length;i++) {
+ tmp.position = 0;
+ tmp.writeBytes(vector);
+ key.encrypt(vector);
+ src[i] ^= vector[0];
+ // rotate
+ for (var j:uint=0;j<blockSize-1;j++) {
+ vector[j] = tmp[j+1];
+ }
+ vector[blockSize-1] = src[i];
+ }
+ }
+
+ public function decrypt(src:ByteArray):void {
+ var vector:ByteArray = getIV4d();
+ var tmp:ByteArray = new ByteArray;
+ for (var i:uint=0;i<src.length;i++) {
+ var c:uint = src[i];
+ tmp.position = 0;
+ tmp.writeBytes(vector); // I <- tmp
+ key.encrypt(vector); // O <- vector
+ src[i] ^= vector[0];
+ // rotate
+ for (var j:uint=0;j<blockSize-1;j++) {
+ vector[j] = tmp[j+1];
+ }
+ vector[blockSize-1] = c;
+ }
+
+ }
+ public function toString():String {
+ return key.toString()+"-cfb8";
+ }
+ }
+}
\ No newline at end of file diff --git a/flash-src/third-party/com/hurlant/crypto/symmetric/CFBMode.as b/flash-src/third-party/com/hurlant/crypto/symmetric/CFBMode.as new file mode 100644 index 0000000..7b748b9 --- /dev/null +++ b/flash-src/third-party/com/hurlant/crypto/symmetric/CFBMode.as @@ -0,0 +1,64 @@ +/**
+ * CFBMode
+ *
+ * An ActionScript 3 implementation of the CFB confidentiality mode
+ * Copyright (c) 2007 Henri Torgemane
+ *
+ * See LICENSE.txt for full license information.
+ */
+package com.hurlant.crypto.symmetric
+{
+ import flash.utils.ByteArray;
+
+ /**
+ * This is the "full" CFB.
+ * CFB1 and CFB8 are hiding somewhere else.
+ *
+ * Note: The constructor accepts an optional padding argument, but ignores it otherwise.
+ */
+ public class CFBMode extends IVMode implements IMode
+ {
+
+ public function CFBMode(key:ISymmetricKey, padding:IPad = null) {
+ super(key,null);
+ }
+
+ public function encrypt(src:ByteArray):void
+ {
+ var l:uint = src.length;
+ var vector:ByteArray = getIV4e();
+ for (var i:uint=0;i<src.length;i+=blockSize) {
+ key.encrypt(vector);
+ var chunk:uint = (i+blockSize<l)?blockSize:l-i;
+ for (var j:uint=0;j<chunk;j++) {
+ src[i+j] ^= vector[j];
+ }
+ vector.position=0;
+ vector.writeBytes(src, i, chunk);
+ }
+ }
+
+ public function decrypt(src:ByteArray):void
+ {
+ var l:uint = src.length;
+ var vector:ByteArray = getIV4d();
+ var tmp:ByteArray = new ByteArray;
+ for (var i:uint=0;i<src.length;i+=blockSize) {
+ key.encrypt(vector);
+ var chunk:uint = (i+blockSize<l)?blockSize:l-i;
+ tmp.position=0;
+ tmp.writeBytes(src, i, chunk);
+ for (var j:uint=0;j<chunk;j++) {
+ src[i+j] ^= vector[j];
+ }
+ vector.position=0;
+ vector.writeBytes(tmp);
+ }
+ }
+
+ public function toString():String {
+ return key.toString()+"-cfb";
+ }
+
+ }
+}
\ No newline at end of file diff --git a/flash-src/third-party/com/hurlant/crypto/symmetric/CTRMode.as b/flash-src/third-party/com/hurlant/crypto/symmetric/CTRMode.as new file mode 100644 index 0000000..fcd1284 --- /dev/null +++ b/flash-src/third-party/com/hurlant/crypto/symmetric/CTRMode.as @@ -0,0 +1,58 @@ +/**
+ * CTRMode
+ *
+ * An ActionScript 3 implementation of the counter confidentiality mode
+ * Copyright (c) 2007 Henri Torgemane
+ *
+ * See LICENSE.txt for full license information.
+ */
+package com.hurlant.crypto.symmetric
+{
+ import flash.utils.ByteArray;
+
+ public class CTRMode extends IVMode implements IMode
+ {
+
+ public function CTRMode(key:ISymmetricKey, padding:IPad = null) {
+ super(key, padding);
+ }
+
+ public function encrypt(src:ByteArray):void
+ {
+ padding.pad(src);
+ var vector:ByteArray = getIV4e();
+ core(src, vector);
+ }
+
+ public function decrypt(src:ByteArray):void
+ {
+ var vector:ByteArray = getIV4d();
+ core(src, vector);
+ padding.unpad(src);
+ }
+
+ private function core(src:ByteArray, iv:ByteArray):void {
+ var X:ByteArray = new ByteArray;
+ var Xenc:ByteArray = new ByteArray;
+ X.writeBytes(iv);
+ for (var i:uint=0;i<src.length;i+=blockSize) {
+ Xenc.position=0;
+ Xenc.writeBytes(X);
+ key.encrypt(Xenc);
+ for (var j:uint=0;j<blockSize;j++) {
+ src[i+j] ^= Xenc[j];
+ }
+
+ for (j=blockSize-1;j>=0;--j) {
+ X[j]++;
+ if (X[j]!=0)
+ break;
+ }
+ }
+ }
+ public function toString():String {
+ return key.toString()+"-ctr";
+ }
+
+ }
+}
\ No newline at end of file diff --git a/flash-src/third-party/com/hurlant/crypto/symmetric/DESKey.as b/flash-src/third-party/com/hurlant/crypto/symmetric/DESKey.as new file mode 100644 index 0000000..4a0b755 --- /dev/null +++ b/flash-src/third-party/com/hurlant/crypto/symmetric/DESKey.as @@ -0,0 +1,365 @@ +/**
+ * DESKey
+ *
+ * An Actionscript 3 implementation of the Data Encryption Standard (DES)
+ * Copyright (c) 2007 Henri Torgemane
+ *
+ * Derived from:
+ * The Bouncy Castle Crypto package,
+ * Copyright (c) 2000-2004 The Legion Of The Bouncy Castle
+ * (http://www.bouncycastle.org)
+ *
+ * See LICENSE.txt for full license information.
+ */
+package com.hurlant.crypto.symmetric
+{
+ import flash.utils.ByteArray;
+ import com.hurlant.util.Hex;
+ import com.hurlant.util.Memory;
+
+ public class DESKey implements ISymmetricKey
+ {
+ /**
+ * what follows is mainly taken from "Applied Cryptography", by Bruce
+ * Schneier, however it also bears great resemblance to Richard
+ * Outerbridge's D3DES...
+ */
+
+ private static const Df_Key:Array = [ 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32,
+ 0x10, 0x89, 0xab, 0xcd, 0xef, 0x01, 0x23, 0x45, 0x67 ];
+
+ private static const bytebit:Array = [ 128, 64, 32, 16, 8, 4, 2, 1 ];
+
+ private static const bigbyte:Array = [ 0x800000, 0x400000, 0x200000, 0x100000, 0x80000, 0x40000, 0x20000, 0x10000, 0x8000,
+ 0x4000, 0x2000, 0x1000, 0x800, 0x400, 0x200, 0x100, 0x80, 0x40, 0x20, 0x10, 0x8, 0x4, 0x2, 0x1 ];
+
+ /*
+ * Use the key schedule specified in the Standard (ANSI X3.92-1981).
+ */
+
+ private static const pc1:Array = [ 56, 48, 40, 32, 24, 16, 8, 0, 57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18, 10, 2,
+ 59, 51, 43, 35, 62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 60, 52, 44, 36, 28, 20, 12,
+ 4, 27, 19, 11, 3 ];
+
+ private static const totrot:Array = [ 1, 2, 4, 6, 8, 10, 12, 14, 15, 17, 19, 21, 23, 25, 27, 28 ];
+
+ private static const pc2:Array = [ 13, 16, 10, 23, 0, 4, 2, 27, 14, 5, 20, 9, 22, 18, 11, 3, 25, 7, 15, 6, 26, 19, 12, 1, 40,
+ 51, 30, 36, 46, 54, 29, 39, 50, 44, 32, 47, 43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31 ];
+
+ private static const SP1:Array = [ 0x01010400, 0x00000000, 0x00010000, 0x01010404, 0x01010004, 0x00010404, 0x00000004,
+ 0x00010000, 0x00000400, 0x01010400, 0x01010404, 0x00000400, 0x01000404, 0x01010004, 0x01000000, 0x00000004,
+ 0x00000404, 0x01000400, 0x01000400, 0x00010400, 0x00010400, 0x01010000, 0x01010000, 0x01000404, 0x00010004,
+ 0x01000004, 0x01000004, 0x00010004, 0x00000000, 0x00000404, 0x00010404, 0x01000000, 0x00010000, 0x01010404,
+ 0x00000004, 0x01010000, 0x01010400, 0x01000000, 0x01000000, 0x00000400, 0x01010004, 0x00010000, 0x00010400,
+ 0x01000004, 0x00000400, 0x00000004, 0x01000404, 0x00010404, 0x01010404, 0x00010004, 0x01010000, 0x01000404,
+ 0x01000004, 0x00000404, 0x00010404, 0x01010400, 0x00000404, 0x01000400, 0x01000400, 0x00000000, 0x00010004,
+ 0x00010400, 0x00000000, 0x01010004 ];
+
+ private static const SP2:Array = [ 0x80108020, 0x80008000, 0x00008000, 0x00108020, 0x00100000, 0x00000020, 0x80100020,
+ 0x80008020, 0x80000020, 0x80108020, 0x80108000, 0x80000000, 0x80008000, 0x00100000, 0x00000020, 0x80100020,
+ 0x00108000, 0x00100020, 0x80008020, 0x00000000, 0x80000000, 0x00008000, 0x00108020, 0x80100000, 0x00100020,
+ 0x80000020, 0x00000000, 0x00108000, 0x00008020, 0x80108000, 0x80100000, 0x00008020, 0x00000000, 0x00108020,
+ 0x80100020, 0x00100000, 0x80008020, 0x80100000, 0x80108000, 0x00008000, 0x80100000, 0x80008000, 0x00000020,
+ 0x80108020, 0x00108020, 0x00000020, 0x00008000, 0x80000000, 0x00008020, 0x80108000, 0x00100000, 0x80000020,
+ 0x00100020, 0x80008020, 0x80000020, 0x00100020, 0x00108000, 0x00000000, 0x80008000, 0x00008020, 0x80000000,
+ 0x80100020, 0x80108020, 0x00108000 ];
+
+ private static const SP3:Array = [ 0x00000208, 0x08020200, 0x00000000, 0x08020008, 0x08000200, 0x00000000, 0x00020208,
+ 0x08000200, 0x00020008, 0x08000008, 0x08000008, 0x00020000, 0x08020208, 0x00020008, 0x08020000, 0x00000208,
+ 0x08000000, 0x00000008, 0x08020200, 0x00000200, 0x00020200, 0x08020000, 0x08020008, 0x00020208, 0x08000208,
+ 0x00020200, 0x00020000, 0x08000208, 0x00000008, 0x08020208, 0x00000200, 0x08000000, 0x08020200, 0x08000000,
+ 0x00020008, 0x00000208, 0x00020000, 0x08020200, 0x08000200, 0x00000000, 0x00000200, 0x00020008, 0x08020208,
+ 0x08000200, 0x08000008, 0x00000200, 0x00000000, 0x08020008, 0x08000208, 0x00020000, 0x08000000, 0x08020208,
+ 0x00000008, 0x00020208, 0x00020200, 0x08000008, 0x08020000, 0x08000208, 0x00000208, 0x08020000, 0x00020208,
+ 0x00000008, 0x08020008, 0x00020200 ];
+
+ private static const SP4:Array = [ 0x00802001, 0x00002081, 0x00002081, 0x00000080, 0x00802080, 0x00800081, 0x00800001,
+ 0x00002001, 0x00000000, 0x00802000, 0x00802000, 0x00802081, 0x00000081, 0x00000000, 0x00800080, 0x00800001,
+ 0x00000001, 0x00002000, 0x00800000, 0x00802001, 0x00000080, 0x00800000, 0x00002001, 0x00002080, 0x00800081,
+ 0x00000001, 0x00002080, 0x00800080, 0x00002000, 0x00802080, 0x00802081, 0x00000081, 0x00800080, 0x00800001,
+ 0x00802000, 0x00802081, 0x00000081, 0x00000000, 0x00000000, 0x00802000, 0x00002080, 0x00800080, 0x00800081,
+ 0x00000001, 0x00802001, 0x00002081, 0x00002081, 0x00000080, 0x00802081, 0x00000081, 0x00000001, 0x00002000,
+ 0x00800001, 0x00002001, 0x00802080, 0x00800081, 0x00002001, 0x00002080, 0x00800000, 0x00802001, 0x00000080,
+ 0x00800000, 0x00002000, 0x00802080 ];
+
+ private static const SP5:Array = [ 0x00000100, 0x02080100, 0x02080000, 0x42000100, 0x00080000, 0x00000100, 0x40000000,
+ 0x02080000, 0x40080100, 0x00080000, 0x02000100, 0x40080100, 0x42000100, 0x42080000, 0x00080100, 0x40000000,
+ 0x02000000, 0x40080000, 0x40080000, 0x00000000, 0x40000100, 0x42080100, 0x42080100, 0x02000100, 0x42080000,
+ 0x40000100, 0x00000000, 0x42000000, 0x02080100, 0x02000000, 0x42000000, 0x00080100, 0x00080000, 0x42000100,
+ 0x00000100, 0x02000000, 0x40000000, 0x02080000, 0x42000100, 0x40080100, 0x02000100, 0x40000000, 0x42080000,
+ 0x02080100, 0x40080100, 0x00000100, 0x02000000, 0x42080000, 0x42080100, 0x00080100, 0x42000000, 0x42080100,
+ 0x02080000, 0x00000000, 0x40080000, 0x42000000, 0x00080100, 0x02000100, 0x40000100, 0x00080000, 0x00000000,
+ 0x40080000, 0x02080100, 0x40000100 ];
+
+ private static const SP6:Array = [ 0x20000010, 0x20400000, 0x00004000, 0x20404010, 0x20400000, 0x00000010, 0x20404010,
+ 0x00400000, 0x20004000, 0x00404010, 0x00400000, 0x20000010, 0x00400010, 0x20004000, 0x20000000, 0x00004010,
+ 0x00000000, 0x00400010, 0x20004010, 0x00004000, 0x00404000, 0x20004010, 0x00000010, 0x20400010, 0x20400010,
+ 0x00000000, 0x00404010, 0x20404000, 0x00004010, 0x00404000, 0x20404000, 0x20000000, 0x20004000, 0x00000010,
+ 0x20400010, 0x00404000, 0x20404010, 0x00400000, 0x00004010, 0x20000010, 0x00400000, 0x20004000, 0x20000000,
+ 0x00004010, 0x20000010, 0x20404010, 0x00404000, 0x20400000, 0x00404010, 0x20404000, 0x00000000, 0x20400010,
+ 0x00000010, 0x00004000, 0x20400000, 0x00404010, 0x00004000, 0x00400010, 0x20004010, 0x00000000, 0x20404000,
+ 0x20000000, 0x00400010, 0x20004010 ];
+
+ private static const SP7:Array = [ 0x00200000, 0x04200002, 0x04000802, 0x00000000, 0x00000800, 0x04000802, 0x00200802,
+ 0x04200800, 0x04200802, 0x00200000, 0x00000000, 0x04000002, 0x00000002, 0x04000000, 0x04200002, 0x00000802,
+ 0x04000800, 0x00200802, 0x00200002, 0x04000800, 0x04000002, 0x04200000, 0x04200800, 0x00200002, 0x04200000,
+ 0x00000800, 0x00000802, 0x04200802, 0x00200800, 0x00000002, 0x04000000, 0x00200800, 0x04000000, 0x00200800,
+ 0x00200000, 0x04000802, 0x04000802, 0x04200002, 0x04200002, 0x00000002, 0x00200002, 0x04000000, 0x04000800,
+ 0x00200000, 0x04200800, 0x00000802, 0x00200802, 0x04200800, 0x00000802, 0x04000002, 0x04200802, 0x04200000,
+ 0x00200800, 0x00000000, 0x00000002, 0x04200802, 0x00000000, 0x00200802, 0x04200000, 0x00000800, 0x04000002,
+ 0x04000800, 0x00000800, 0x00200002 ];
+
+ private static const SP8:Array = [ 0x10001040, 0x00001000, 0x00040000, 0x10041040, 0x10000000, 0x10001040, 0x00000040,
+ 0x10000000, 0x00040040, 0x10040000, 0x10041040, 0x00041000, 0x10041000, 0x00041040, 0x00001000, 0x00000040,
+ 0x10040000, 0x10000040, 0x10001000, 0x00001040, 0x00041000, 0x00040040, 0x10040040, 0x10041000, 0x00001040,
+ 0x00000000, 0x00000000, 0x10040040, 0x10000040, 0x10001000, 0x00041040, 0x00040000, 0x00041040, 0x00040000,
+ 0x10041000, 0x00001000, 0x00000040, 0x10040040, 0x00001000, 0x00041040, 0x10001000, 0x00000040, 0x10000040,
+ 0x10040000, 0x10040040, 0x10000000, 0x00040000, 0x10001040, 0x00000000, 0x10041040, 0x00040040, 0x10000040,
+ 0x10040000, 0x10001000, 0x10001040, 0x00000000, 0x10041040, 0x00041000, 0x00041000, 0x00001040, 0x00001040,
+ 0x00040040, 0x10000000, 0x10041000 ];
+
+
+ protected var key:ByteArray;
+ protected var encKey:Array;
+ protected var decKey:Array;
+
+
+ public function DESKey(key:ByteArray) {
+ this.key = key;
+ this.encKey = generateWorkingKey(true, key, 0);
+ this.decKey = generateWorkingKey(false, key, 0);
+ }
+
+ public function getBlockSize():uint
+ {
+ return 8;
+ }
+
+ public function decrypt(block:ByteArray, index:uint=0):void
+ {
+ desFunc(decKey, block, index, block, index);
+ }
+
+ public function dispose():void
+ {
+ var i:uint=0;
+ for (i=0;i<encKey.length;i++) { encKey[i]=0; }
+ for (i=0;i<decKey.length;i++) { decKey[i]=0; }
+ encKey=null;
+ decKey=null;
+ for (i=0;i<key.length;i++) { key[i]=0; }
+ key.length = 0;
+ key = null;
+ Memory.gc();
+ }
+
+ public function encrypt(block:ByteArray, index:uint=0):void
+ {
+ desFunc(encKey, block, index, block, index);
+ }
+
+
+ /**
+ * generate an integer based working key based on our secret key and what we
+ * processing we are planning to do.
+ *
+ * Acknowledgements for this routine go to James Gillogly & Phil Karn.
+ */
+ protected function generateWorkingKey(encrypting:Boolean, key:ByteArray, off:uint):Array
+ {
+ //int[] newKey = new int[32];
+ var newKey:Array = [];
+ //boolean[] pc1m = new boolean[56], pcr = new boolean[56];
+ var pc1m:ByteArray = new ByteArray;
+ var pcr:ByteArray = new ByteArray;
+
+ var l:uint;
+
+ for (var j:uint = 0; j < 56; j++)
+ {
+ l = pc1[j];
+
+ pc1m[j] = ((key[off + (l >>> 3)] & bytebit[l & 07]) != 0);
+ }
+
+ for (var i:uint = 0; i < 16; i++)
+ {
+ var m:uint;
+ var n:uint;
+
+ if (encrypting)
+ {
+ m = i << 1;
+ }
+ else
+ {
+ m = (15 - i) << 1;
+ }
+
+ n = m + 1;
+ newKey[m] = newKey[n] = 0;
+
+ for (j = 0; j < 28; j++)
+ {
+ l = j + totrot[i];
+ if (l < 28)
+ {
+ pcr[j] = pc1m[l];
+ }
+ else
+ {
+ pcr[j] = pc1m[l - 28];
+ }
+ }
+
+ for (j = 28; j < 56; j++)
+ {
+ l = j + totrot[i];
+ if (l < 56)
+ {
+ pcr[j] = pc1m[l];
+ }
+ else
+ {
+ pcr[j] = pc1m[l - 28];
+ }
+ }
+
+ for (j = 0; j < 24; j++)
+ {
+ if (pcr[pc2[j]])
+ {
+ newKey[m] |= bigbyte[j];
+ }
+
+ if (pcr[pc2[j + 24]])
+ {
+ newKey[n] |= bigbyte[j];
+ }
+ }
+ }
+
+ //
+ // store the processed key
+ //
+ for (i = 0; i != 32; i += 2)
+ {
+ var i1:uint;
+ var i2:uint;
+
+ i1 = newKey[i];
+ i2 = newKey[i + 1];
+
+ newKey[i] = ((i1 & 0x00fc0000) << 6) | ((i1 & 0x00000fc0) << 10) | ((i2 & 0x00fc0000) >>> 10)
+ | ((i2 & 0x00000fc0) >>> 6);
+
+ newKey[i + 1] = ((i1 & 0x0003f000) << 12) | ((i1 & 0x0000003f) << 16) | ((i2 & 0x0003f000) >>> 4)
+ | (i2 & 0x0000003f);
+ }
+ return newKey;
+ }
+
+ /**
+ * the DES engine.
+ */
+ protected function desFunc(wKey:Array, inp:ByteArray, inOff:uint, out:ByteArray, outOff:uint):void
+ {
+ var work:uint;
+ var right:uint;
+ var left:uint;
+
+ left = (inp[inOff + 0] & 0xff) << 24;
+ left |= (inp[inOff + 1] & 0xff) << 16;
+ left |= (inp[inOff + 2] & 0xff) << 8;
+ left |= (inp[inOff + 3] & 0xff);
+
+ right = (inp[inOff + 4] & 0xff) << 24;
+ right |= (inp[inOff + 5] & 0xff) << 16;
+ right |= (inp[inOff + 6] & 0xff) << 8;
+ right |= (inp[inOff + 7] & 0xff);
+
+ work = ((left >>> 4) ^ right) & 0x0f0f0f0f;
+ right ^= work;
+ left ^= (work << 4);
+ work = ((left >>> 16) ^ right) & 0x0000ffff;
+ right ^= work;
+ left ^= (work << 16);
+ work = ((right >>> 2) ^ left) & 0x33333333;
+ left ^= work;
+ right ^= (work << 2);
+ work = ((right >>> 8) ^ left) & 0x00ff00ff;
+ left ^= work;
+ right ^= (work << 8);
+ right = ((right << 1) | ((right >>> 31) & 1)) & 0xffffffff;
+ work = (left ^ right) & 0xaaaaaaaa;
+ left ^= work;
+ right ^= work;
+ left = ((left << 1) | ((left >>> 31) & 1)) & 0xffffffff;
+
+ for (var round:uint = 0; round < 8; round++)
+ {
+ var fval:uint;
+
+ work = (right << 28) | (right >>> 4);
+ work ^= wKey[round * 4 + 0];
+ fval = SP7[work & 0x3f];
+ fval |= SP5[(work >>> 8) & 0x3f];
+ fval |= SP3[(work >>> 16) & 0x3f];
+ fval |= SP1[(work >>> 24) & 0x3f];
+ work = right ^ wKey[round * 4 + 1];
+ fval |= SP8[work & 0x3f];
+ fval |= SP6[(work >>> 8) & 0x3f];
+ fval |= SP4[(work >>> 16) & 0x3f];
+ fval |= SP2[(work >>> 24) & 0x3f];
+ left ^= fval;
+ work = (left << 28) | (left >>> 4);
+ work ^= wKey[round * 4 + 2];
+ fval = SP7[work & 0x3f];
+ fval |= SP5[(work >>> 8) & 0x3f];
+ fval |= SP3[(work >>> 16) & 0x3f];
+ fval |= SP1[(work >>> 24) & 0x3f];
+ work = left ^ wKey[round * 4 + 3];
+ fval |= SP8[work & 0x3f];
+ fval |= SP6[(work >>> 8) & 0x3f];
+ fval |= SP4[(work >>> 16) & 0x3f];
+ fval |= SP2[(work >>> 24) & 0x3f];
+ right ^= fval;
+ }
+
+ right = (right << 31) | (right >>> 1);
+ work = (left ^ right) & 0xaaaaaaaa;
+ left ^= work;
+ right ^= work;
+ left = (left << 31) | (left >>> 1);
+ work = ((left >>> 8) ^ right) & 0x00ff00ff;
+ right ^= work;
+ left ^= (work << 8);
+ work = ((left >>> 2) ^ right) & 0x33333333;
+ right ^= work;
+ left ^= (work << 2);
+ work = ((right >>> 16) ^ left) & 0x0000ffff;
+ left ^= work;
+ right ^= (work << 16);
+ work = ((right >>> 4) ^ left) & 0x0f0f0f0f;
+ left ^= work;
+ right ^= (work << 4);
+
+ out[outOff + 0] = ((right >>> 24) & 0xff);
+ out[outOff + 1] = ((right >>> 16) & 0xff);
+ out[outOff + 2] = ((right >>> 8) & 0xff);
+ out[outOff + 3] = (right & 0xff);
+ out[outOff + 4] = ((left >>> 24) & 0xff);
+ out[outOff + 5] = ((left >>> 16) & 0xff);
+ out[outOff + 6] = ((left >>> 8) & 0xff);
+ out[outOff + 7] = (left & 0xff);
+ }
+
+
+ public function toString():String {
+ return "des";
+ }
+
+
+
+ }
+}
\ No newline at end of file diff --git a/flash-src/third-party/com/hurlant/crypto/symmetric/ECBMode.as b/flash-src/third-party/com/hurlant/crypto/symmetric/ECBMode.as new file mode 100644 index 0000000..b2a7b77 --- /dev/null +++ b/flash-src/third-party/com/hurlant/crypto/symmetric/ECBMode.as @@ -0,0 +1,86 @@ +/**
+ * ECBMode
+ *
+ * An ActionScript 3 implementation of the ECB confidentiality mode
+ * Copyright (c) 2007 Henri Torgemane
+ *
+ * See LICENSE.txt for full license information.
+ */
+package com.hurlant.crypto.symmetric
+{
+ import flash.utils.ByteArray;
+ import com.hurlant.util.Memory;
+ import com.hurlant.util.Hex;
+
+ /**
+ * ECB mode.
+ * This uses a padding and a symmetric key.
+ * If no padding is given, PKCS#5 is used.
+ */
+ public class ECBMode implements IMode, ICipher
+ {
+ private var key:ISymmetricKey;
+ private var padding:IPad;
+
+ public function ECBMode(key:ISymmetricKey, padding:IPad = null) {
+ this.key = key;
+ if (padding == null) {
+ padding = new PKCS5(key.getBlockSize());
+ } else {
+ padding.setBlockSize(key.getBlockSize());
+ }
+ this.padding = padding;
+ }
+
+ public function getBlockSize():uint {
+ return key.getBlockSize();
+ }
+
+ public function encrypt(src:ByteArray):void {
+ padding.pad(src);
+ src.position = 0;
+ var blockSize:uint = key.getBlockSize();
+ var tmp:ByteArray = new ByteArray;
+ var dst:ByteArray = new ByteArray;
+ for (var i:uint=0;i<src.length;i+=blockSize) {
+ tmp.length=0;
+ src.readBytes(tmp, 0, blockSize);
+ key.encrypt(tmp);
+ dst.writeBytes(tmp);
+ }
+ src.length=0;
+ src.writeBytes(dst);
+ }
+ public function decrypt(src:ByteArray):void {
+ src.position = 0;
+ var blockSize:uint = key.getBlockSize();
+
+ // sanity check.
+ if (src.length%blockSize!=0) {
+ throw new Error("ECB mode cipher length must be a multiple of blocksize "+blockSize);
+ }
+
+ var tmp:ByteArray = new ByteArray;
+ var dst:ByteArray = new ByteArray;
+ for (var i:uint=0;i<src.length;i+=blockSize) {
+ tmp.length=0;
+ src.readBytes(tmp, 0, blockSize);
+
+ key.decrypt(tmp);
+ dst.writeBytes(tmp);
+ }
+ padding.unpad(dst);
+ src.length=0;
+ src.writeBytes(dst);
+ }
+ public function dispose():void {
+ key.dispose();
+ key = null;
+ padding = null;
+ Memory.gc();
+ }
+ public function toString():String {
+ return key.toString()+"-ecb";
+ }
+ }
+}
\ No newline at end of file diff --git a/flash-src/third-party/com/hurlant/crypto/symmetric/ICipher.as b/flash-src/third-party/com/hurlant/crypto/symmetric/ICipher.as new file mode 100644 index 0000000..328c024 --- /dev/null +++ b/flash-src/third-party/com/hurlant/crypto/symmetric/ICipher.as @@ -0,0 +1,21 @@ +/**
+ * ICipher
+ *
+ * A generic interface to use symmetric ciphers
+ * Copyright (c) 2007 Henri Torgemane
+ *
+ * See LICENSE.txt for full license information.
+ */
+package com.hurlant.crypto.symmetric
+{
+ import flash.utils.ByteArray;
+
+ public interface ICipher
+ {
+ function getBlockSize():uint;
+ function encrypt(src:ByteArray):void;
+ function decrypt(src:ByteArray):void;
+ function dispose():void;
+ function toString():String;
+ }
+}
\ No newline at end of file diff --git a/flash-src/third-party/com/hurlant/crypto/symmetric/IMode.as b/flash-src/third-party/com/hurlant/crypto/symmetric/IMode.as new file mode 100644 index 0000000..8a99b06 --- /dev/null +++ b/flash-src/third-party/com/hurlant/crypto/symmetric/IMode.as @@ -0,0 +1,15 @@ +/**
+ * IMode
+ *
+ * An interface for confidentiality modes to implement
+ * This could become deprecated at some point.
+ * Copyright (c) 2007 Henri Torgemane
+ *
+ * See LICENSE.txt for full license information.
+ */
+package com.hurlant.crypto.symmetric
+{
+ public interface IMode extends ICipher
+ {
+ }
+}
\ No newline at end of file diff --git a/flash-src/third-party/com/hurlant/crypto/symmetric/IPad.as b/flash-src/third-party/com/hurlant/crypto/symmetric/IPad.as new file mode 100644 index 0000000..c686e26 --- /dev/null +++ b/flash-src/third-party/com/hurlant/crypto/symmetric/IPad.as @@ -0,0 +1,32 @@ +/**
+ * IPad
+ *
+ * An interface for padding mechanisms to implement.
+ * Copyright (c) 2007 Henri Torgemane
+ *
+ * See LICENSE.txt for full license information.
+ */
+package com.hurlant.crypto.symmetric
+{
+ import flash.utils.ByteArray;
+
+ /**
+ * Tiny interface that represents a padding mechanism.
+ */
+ public interface IPad
+ {
+ /**
+ * Add padding to the array
+ */
+ function pad(a:ByteArray):void;
+ /**
+ * Remove padding from the array.
+ * @throws Error if the padding is invalid.
+ */
+ function unpad(a:ByteArray):void;
+ /**
+ * Set the blockSize to work on
+ */
+ function setBlockSize(bs:uint):void;
+ }
+}
\ No newline at end of file diff --git a/flash-src/third-party/com/hurlant/crypto/symmetric/IStreamCipher.as b/flash-src/third-party/com/hurlant/crypto/symmetric/IStreamCipher.as new file mode 100644 index 0000000..fbcbf24 --- /dev/null +++ b/flash-src/third-party/com/hurlant/crypto/symmetric/IStreamCipher.as @@ -0,0 +1,21 @@ +/**
+ * IStreamCipher
+ *
+ * A "marker" interface for stream ciphers.
+ * Copyright (c) 2007 Henri Torgemane
+ *
+ * See LICENSE.txt for full license information.
+ */
+package com.hurlant.crypto.symmetric {
+
+ /**
+ * A marker to indicate how this cipher works.
+ * A stream cipher:
+ * - does not use initialization vector
+ * - keeps some internal state between calls to encrypt() and decrypt()
+ *
+ */
+ public interface IStreamCipher extends ICipher {
+
+ }
+}
\ No newline at end of file diff --git a/flash-src/third-party/com/hurlant/crypto/symmetric/ISymmetricKey.as b/flash-src/third-party/com/hurlant/crypto/symmetric/ISymmetricKey.as new file mode 100644 index 0000000..1699db5 --- /dev/null +++ b/flash-src/third-party/com/hurlant/crypto/symmetric/ISymmetricKey.as @@ -0,0 +1,35 @@ +/**
+ * ISymmetricKey
+ *
+ * An interface for symmetric encryption keys to implement.
+ * Copyright (c) 2007 Henri Torgemane
+ *
+ * See LICENSE.txt for full license information.
+ */
+package com.hurlant.crypto.symmetric
+{
+ import flash.utils.ByteArray;
+
+ public interface ISymmetricKey
+ {
+ /**
+ * Returns the block size used by this particular encryption algorithm
+ */
+ function getBlockSize():uint;
+ /**
+ * Encrypt one block of data in "block", starting at "index", of length "getBlockSize()"
+ */
+ function encrypt(block:ByteArray, index:uint=0):void;
+ /**
+ * Decrypt one block of data in "block", starting at "index", of length "getBlockSize()"
+ */
+ function decrypt(block:ByteArray, index:uint=0):void;
+ /**
+ * Attempts to destroy sensitive information from memory, such as encryption keys.
+ * Note: This is not guaranteed to work given the Flash sandbox model.
+ */
+ function dispose():void;
+
+ function toString():String;
+ }
+}
\ No newline at end of file diff --git a/flash-src/third-party/com/hurlant/crypto/symmetric/IVMode.as b/flash-src/third-party/com/hurlant/crypto/symmetric/IVMode.as new file mode 100644 index 0000000..100041a --- /dev/null +++ b/flash-src/third-party/com/hurlant/crypto/symmetric/IVMode.as @@ -0,0 +1,110 @@ +/**
+ * IVMode
+ *
+ * An abstract class for confidentialy modes that rely on an initialization vector.
+ * Copyright (c) 2007 Henri Torgemane
+ *
+ * See LICENSE.txt for full license information.
+ */
+package com.hurlant.crypto.symmetric
+{
+ import com.hurlant.crypto.prng.Random;
+ import com.hurlant.crypto.tests.TestCase;
+ import com.hurlant.util.Memory;
+
+ import flash.utils.ByteArray;
+
+ /**
+ * An "abtract" class to avoid redundant code in subclasses
+ */
+ public class IVMode
+ {
+ protected var key:ISymmetricKey;
+ protected var padding:IPad;
+ // random generator used to generate IVs
+ protected var prng:Random;
+ // optional static IV. used for testing only.
+ protected var iv:ByteArray;
+ // generated IV is stored here.
+ protected var lastIV:ByteArray;
+ protected var blockSize:uint;
+
+
+ public function IVMode(key:ISymmetricKey, padding:IPad = null) {
+ this.key = key;
+ blockSize = key.getBlockSize();
+ if (padding == null) {
+ padding = new PKCS5(blockSize);
+ } else {
+ padding.setBlockSize(blockSize);
+ }
+ this.padding = padding;
+
+ prng = new Random;
+ iv = null;
+ lastIV = new ByteArray;
+ }
+
+ public function getBlockSize():uint {
+ return key.getBlockSize();
+ }
+ public function dispose():void {
+ var i:uint;
+ if (iv != null) {
+ for (i=0;i<iv.length;i++) {
+ iv[i] = prng.nextByte();
+ }
+ iv.length=0;
+ iv = null;
+ }
+ if (lastIV != null) {
+ for (i=0;i<iv.length;i++) {
+ lastIV[i] = prng.nextByte();
+ }
+ lastIV.length=0;
+ lastIV=null;
+ }
+ key.dispose();
+ key = null;
+ padding = null;
+ prng.dispose();
+ prng = null;
+ Memory.gc();
+ }
+ /**
+ * Optional function to force the IV value.
+ * Normally, an IV gets generated randomly at every encrypt() call.
+ * Also, use this to set the IV before calling decrypt()
+ * (if not set before decrypt(), the IV is read from the beginning of the stream.)
+ */
+ public function set IV(value:ByteArray):void {
+ iv = value;
+ lastIV.length=0;
+ lastIV.writeBytes(iv);
+ }
+ public function get IV():ByteArray {
+ return lastIV;
+ }
+
+ protected function getIV4e():ByteArray {
+ var vec:ByteArray = new ByteArray;
+ if (iv) {
+ vec.writeBytes(iv);
+ } else {
+ prng.nextBytes(vec, blockSize);
+ }
+ lastIV.length=0;
+ lastIV.writeBytes(vec);
+ return vec;
+ }
+ protected function getIV4d():ByteArray {
+ var vec:ByteArray = new ByteArray;
+ if (iv) {
+ vec.writeBytes(iv);
+ } else {
+ throw new Error("an IV must be set before calling decrypt()");
+ }
+ return vec;
+ }
+ }
+}
\ No newline at end of file diff --git a/flash-src/third-party/com/hurlant/crypto/symmetric/NullPad.as b/flash-src/third-party/com/hurlant/crypto/symmetric/NullPad.as new file mode 100644 index 0000000..25f8c04 --- /dev/null +++ b/flash-src/third-party/com/hurlant/crypto/symmetric/NullPad.as @@ -0,0 +1,34 @@ +/**
+ * NullPad
+ *
+ * A padding class that doesn't pad.
+ * Copyright (c) 2007 Henri Torgemane
+ *
+ * See LICENSE.txt for full license information.
+ */
+package com.hurlant.crypto.symmetric
+{
+ import flash.utils.ByteArray;
+
+ /**
+ * A pad that does nothing.
+ * Useful when you don't want padding in your Mode.
+ */
+ public class NullPad implements IPad
+ {
+ public function unpad(a:ByteArray):void
+ {
+ return;
+ }
+
+ public function pad(a:ByteArray):void
+ {
+ return;
+ }
+
+ public function setBlockSize(bs:uint):void {
+ return;
+ }
+
+ }
+}
\ No newline at end of file diff --git a/flash-src/third-party/com/hurlant/crypto/symmetric/OFBMode.as b/flash-src/third-party/com/hurlant/crypto/symmetric/OFBMode.as new file mode 100644 index 0000000..8b41736 --- /dev/null +++ b/flash-src/third-party/com/hurlant/crypto/symmetric/OFBMode.as @@ -0,0 +1,52 @@ +/**
+ * OFBMode
+ *
+ * An ActionScript 3 implementation of the OFB confidentiality mode
+ * Copyright (c) 2007 Henri Torgemane
+ *
+ * See LICENSE.txt for full license information.
+ */
+package com.hurlant.crypto.symmetric
+{
+ import flash.utils.ByteArray;
+
+ public class OFBMode extends IVMode implements IMode
+ {
+ public function OFBMode(key:ISymmetricKey, padding:IPad=null)
+ {
+ super(key, null);
+ }
+
+ public function encrypt(src:ByteArray):void
+ {
+ var vector:ByteArray = getIV4e();
+ core(src, vector);
+ }
+
+ public function decrypt(src:ByteArray):void
+ {
+ var vector:ByteArray = getIV4d();
+ core(src, vector);
+ }
+
+ private function core(src:ByteArray, iv:ByteArray):void {
+ var l:uint = src.length;
+ var tmp:ByteArray = new ByteArray;
+ for (var i:uint=0;i<src.length;i+=blockSize) {
+ key.encrypt(iv);
+ tmp.position=0;
+ tmp.writeBytes(iv);
+ var chunk:uint = (i+blockSize<l)?blockSize:l-i;
+ for (var j:uint=0;j<chunk;j++) {
+ src[i+j] ^= iv[j];
+ }
+ iv.position=0;
+ iv.writeBytes(tmp);
+ }
+ }
+ public function toString():String {
+ return key.toString()+"-ofb";
+ }
+
+ }
+}
\ No newline at end of file diff --git a/flash-src/third-party/com/hurlant/crypto/symmetric/PKCS5.as b/flash-src/third-party/com/hurlant/crypto/symmetric/PKCS5.as new file mode 100644 index 0000000..598daa0 --- /dev/null +++ b/flash-src/third-party/com/hurlant/crypto/symmetric/PKCS5.as @@ -0,0 +1,44 @@ +/**
+ * PKCS5
+ *
+ * A padding implementation of PKCS5.
+ * Copyright (c) 2007 Henri Torgemane
+ *
+ * See LICENSE.txt for full license information.
+ */
+package com.hurlant.crypto.symmetric
+{
+ import flash.utils.ByteArray;
+
+ public class PKCS5 implements IPad
+ {
+ private var blockSize:uint;
+
+ public function PKCS5(blockSize:uint=0) {
+ this.blockSize = blockSize;
+ }
+
+ public function pad(a:ByteArray):void {
+ var c:uint = blockSize-a.length%blockSize;
+ for (var i:uint=0;i<c;i++){
+ a[a.length] = c;
+ }
+ }
+ public function unpad(a:ByteArray):void {
+ var c:uint = a.length%blockSize;
+ if (c!=0) throw new Error("PKCS#5::unpad: ByteArray.length isn't a multiple of the blockSize");
+ c = a[a.length-1];
+ for (var i:uint=c;i>0;i--) {
+ var v:uint = a[a.length-1];
+ a.length--;
+ if (c!=v) throw new Error("PKCS#5:unpad: Invalid padding value. expected ["+c+"], found ["+v+"]");
+ }
+ // that is all.
+ }
+
+ public function setBlockSize(bs:uint):void {
+ blockSize = bs;
+ }
+
+ }
+}
\ No newline at end of file diff --git a/flash-src/third-party/com/hurlant/crypto/symmetric/SSLPad.as b/flash-src/third-party/com/hurlant/crypto/symmetric/SSLPad.as new file mode 100755 index 0000000..8dd1324 --- /dev/null +++ b/flash-src/third-party/com/hurlant/crypto/symmetric/SSLPad.as @@ -0,0 +1,44 @@ +/** + * TLSPad + * + * A padding implementation used by TLS + * Copyright (c) 2007 Henri Torgemane + * + * See LICENSE.txt for full license information. + */ +package com.hurlant.crypto.symmetric { + import flash.utils.ByteArray; + import com.hurlant.util.Hex; + import com.hurlant.crypto.tls.TLSError; + + public class SSLPad implements IPad { + private var blockSize:uint; + + public function SSLPad(blockSize:uint=0) { + this.blockSize = blockSize; + } + public function pad(a:ByteArray):void { + var c:uint = blockSize - (a.length+1)%blockSize; + for (var i:uint=0;i<=c;i++) { + a[a.length] = c; + } + + } + public function unpad(a:ByteArray):void { + var c:uint = a.length%blockSize; + if (c!=0) throw new TLSError("SSLPad::unpad: ByteArray.length isn't a multiple of the blockSize", TLSError.bad_record_mac); + c = a[a.length-1]; + for (var i:uint=c;i>0;i--) { + var v:uint = a[a.length-1]; + a.length--; + // But LOOK! SSL 3.0 doesn't care about this, bytes are arbitrary! + // if (c!=v) throw new TLSError("SSLPad:unpad: Invalid padding value. expected ["+c+"], found ["+v+"]", TLSError.bad_record_mac); + } + a.length--; + + } + public function setBlockSize(bs:uint):void { + blockSize = bs; + } + } +}
\ No newline at end of file diff --git a/flash-src/third-party/com/hurlant/crypto/symmetric/SimpleIVMode.as b/flash-src/third-party/com/hurlant/crypto/symmetric/SimpleIVMode.as new file mode 100644 index 0000000..590f0df --- /dev/null +++ b/flash-src/third-party/com/hurlant/crypto/symmetric/SimpleIVMode.as @@ -0,0 +1,60 @@ +/**
+ * SimpleIVMode
+ *
+ * A convenience class that automatically places the IV
+ * at the beginning of the encrypted stream, so it doesn't have to
+ * be handled explicitely.
+ * Copyright (c) 2007 Henri Torgemane
+ *
+ * See LICENSE.txt for full license information.
+ */
+package com.hurlant.crypto.symmetric
+{
+ import flash.utils.ByteArray;
+ import com.hurlant.util.Memory;
+
+ public class SimpleIVMode implements IMode, ICipher
+ {
+ protected var mode:IVMode;
+ protected var cipher:ICipher;
+
+ public function SimpleIVMode(mode:IVMode) {
+ this.mode = mode;
+ cipher = mode as ICipher;
+ }
+
+ public function getBlockSize():uint {
+ return mode.getBlockSize();
+ }
+
+ public function dispose():void {
+ mode.dispose();
+ mode = null;
+ cipher = null;
+ Memory.gc();
+ }
+
+ public function encrypt(src:ByteArray):void {
+ cipher.encrypt(src);
+ var tmp:ByteArray = new ByteArray;
+ tmp.writeBytes(mode.IV);
+ tmp.writeBytes(src);
+ src.position=0;
+ src.writeBytes(tmp);
+ }
+
+ public function decrypt(src:ByteArray):void {
+ var tmp:ByteArray = new ByteArray;
+ tmp.writeBytes(src, 0, getBlockSize());
+ mode.IV = tmp;
+ tmp = new ByteArray;
+ tmp.writeBytes(src, getBlockSize());
+ cipher.decrypt(tmp);
+ src.length=0;
+ src.writeBytes(tmp);
+ }
+ public function toString():String {
+ return "simple-"+cipher.toString();
+ }
+ }
+}
\ No newline at end of file diff --git a/flash-src/third-party/com/hurlant/crypto/symmetric/TLSPad.as b/flash-src/third-party/com/hurlant/crypto/symmetric/TLSPad.as new file mode 100644 index 0000000..f3b6182 --- /dev/null +++ b/flash-src/third-party/com/hurlant/crypto/symmetric/TLSPad.as @@ -0,0 +1,42 @@ +/**
+ * TLSPad
+ *
+ * A padding implementation used by TLS
+ * Copyright (c) 2007 Henri Torgemane
+ *
+ * See LICENSE.txt for full license information.
+ */
+package com.hurlant.crypto.symmetric {
+ import flash.utils.ByteArray;
+ import com.hurlant.util.Hex;
+ import com.hurlant.crypto.tls.TLSError;
+
+ public class TLSPad implements IPad {
+ private var blockSize:uint;
+
+ public function TLSPad(blockSize:uint=0) {
+ this.blockSize = blockSize;
+ }
+ public function pad(a:ByteArray):void {
+ var c:uint = blockSize - (a.length+1)%blockSize;
+ for (var i:uint=0;i<=c;i++) {
+ a[a.length] = c;
+ }
+ }
+ public function unpad(a:ByteArray):void {
+ var c:uint = a.length%blockSize;
+ if (c!=0) throw new TLSError("TLSPad::unpad: ByteArray.length isn't a multiple of the blockSize", TLSError.bad_record_mac);
+ c = a[a.length-1];
+ for (var i:uint=c;i>0;i--) {
+ var v:uint = a[a.length-1];
+ a.length--;
+ if (c!=v) throw new TLSError("TLSPad:unpad: Invalid padding value. expected ["+c+"], found ["+v+"]", TLSError.bad_record_mac);
+ }
+ a.length--;
+ // mostly ripped off from PKCS5.as, but with subtle differences
+ }
+ public function setBlockSize(bs:uint):void {
+ blockSize = bs;
+ }
+ }
+}
\ No newline at end of file diff --git a/flash-src/third-party/com/hurlant/crypto/symmetric/TripleDESKey.as b/flash-src/third-party/com/hurlant/crypto/symmetric/TripleDESKey.as new file mode 100644 index 0000000..1e75011 --- /dev/null +++ b/flash-src/third-party/com/hurlant/crypto/symmetric/TripleDESKey.as @@ -0,0 +1,88 @@ +/**
+ * TripleDESKey
+ *
+ * An Actionscript 3 implementation of Triple DES
+ * Copyright (c) 2007 Henri Torgemane
+ *
+ * Derived from:
+ * The Bouncy Castle Crypto package,
+ * Copyright (c) 2000-2004 The Legion Of The Bouncy Castle
+ * (http://www.bouncycastle.org)
+ *
+ * See LICENSE.txt for full license information.
+ */
+package com.hurlant.crypto.symmetric
+{
+ import flash.utils.ByteArray;
+ import com.hurlant.util.Memory;
+ import com.hurlant.util.Hex;
+
+ public class TripleDESKey extends DESKey
+ {
+ protected var encKey2:Array;
+ protected var encKey3:Array;
+ protected var decKey2:Array;
+ protected var decKey3:Array;
+
+ /**
+ * This supports 2TDES and 3TDES.
+ * If the key passed is 128 bits, 2TDES is used.
+ * If the key has 192 bits, 3TDES is used.
+ * Other key lengths give "undefined" results.
+ */
+ public function TripleDESKey(key:ByteArray)
+ {
+ super(key);
+ encKey2 = generateWorkingKey(false, key, 8);
+ decKey2 = generateWorkingKey(true, key, 8);
+ if (key.length>16) {
+ encKey3 = generateWorkingKey(true, key, 16);
+ decKey3 = generateWorkingKey(false, key, 16);
+ } else {
+ encKey3 = encKey;
+ decKey3 = decKey;
+ }
+ }
+
+ public override function dispose():void
+ {
+ super.dispose();
+ var i:uint = 0;
+ if (encKey2!=null) {
+ for (i=0;i<encKey2.length;i++) { encKey2[i]=0; }
+ encKey2=null;
+ }
+ if (encKey3!=null) {
+ for (i=0;i<encKey3.length;i++) { encKey3[i]=0; }
+ encKey3=null;
+ }
+ if (decKey2!=null) {
+ for (i=0;i<decKey2.length;i++) { decKey2[i]=0; }
+ decKey2=null
+ }
+ if (decKey3!=null) {
+ for (i=0;i<decKey3.length;i++) { decKey3[i]=0; }
+ decKey3=null;
+ }
+ Memory.gc();
+ }
+
+ public override function encrypt(block:ByteArray, index:uint=0):void
+ {
+ desFunc(encKey, block,index, block,index);
+ desFunc(encKey2, block,index, block,index);
+ desFunc(encKey3, block,index, block,index);
+ }
+
+ public override function decrypt(block:ByteArray, index:uint=0):void
+ {
+ desFunc(decKey3, block, index, block, index);
+ desFunc(decKey2, block, index, block, index);
+ desFunc(decKey, block, index, block, index);
+ }
+
+ public override function toString():String {
+ return "3des";
+ }
+ }
+}
\ No newline at end of file diff --git a/flash-src/third-party/com/hurlant/crypto/symmetric/XTeaKey.as b/flash-src/third-party/com/hurlant/crypto/symmetric/XTeaKey.as new file mode 100644 index 0000000..9d140dd --- /dev/null +++ b/flash-src/third-party/com/hurlant/crypto/symmetric/XTeaKey.as @@ -0,0 +1,94 @@ +/**
+ * XTeaKey
+ *
+ * An ActionScript 3 implementation of the XTea algorithm
+ * Copyright (c) 2007 Henri Torgemane
+ *
+ * See LICENSE.txt for full license information.
+ */
+package com.hurlant.crypto.symmetric
+{
+ import com.hurlant.crypto.prng.Random;
+ import com.hurlant.util.Memory;
+
+ import flash.utils.ByteArray;
+
+
+ public class XTeaKey implements ISymmetricKey
+ {
+ public const NUM_ROUNDS:uint = 64;
+ private var k:Array;
+
+ public function XTeaKey(a:ByteArray) {
+ a.position=0;
+ k = [a.readUnsignedInt(),a.readUnsignedInt(),a.readUnsignedInt(),a.readUnsignedInt()];
+ }
+ /**
+ * K is an hex string with 32 digits.
+ */
+ public static function parseKey(K:String):XTeaKey {
+ var a:ByteArray = new ByteArray;
+ a.writeUnsignedInt(parseInt(K.substr(0,8),16));
+ a.writeUnsignedInt(parseInt(K.substr(8,8),16));
+ a.writeUnsignedInt(parseInt(K.substr(16,8),16));
+ a.writeUnsignedInt(parseInt(K.substr(24,8),16));
+ a.position = 0;
+ return new XTeaKey(a);
+ }
+
+ public function getBlockSize():uint {
+ return 8;
+ }
+
+ public function encrypt(block:ByteArray, index:uint=0):void {
+ block.position = index;
+ var v0:uint = block.readUnsignedInt();
+ var v1:uint = block.readUnsignedInt();
+ var i:uint;
+ var sum:uint =0;
+ var delta:uint = 0x9E3779B9;
+ for (i=0; i<NUM_ROUNDS; i++) {
+ v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + k[sum & 3]);
+ sum += delta;
+ v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + k[(sum>>11) & 3]);
+ }
+ block.position-=8;
+ block.writeUnsignedInt(v0);
+ block.writeUnsignedInt(v1);
+ }
+
+ public function decrypt(block:ByteArray, index:uint=0):void {
+ block.position = index;
+ var v0:uint = block.readUnsignedInt();
+ var v1:uint = block.readUnsignedInt();
+ var i:uint;
+ var delta:uint = 0x9E3779B9;
+ var sum:uint = delta*NUM_ROUNDS;
+ for (i=0; i<NUM_ROUNDS; i++) {
+ v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + k[(sum>>11) & 3]);
+ sum -= delta;
+ v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + k[sum & 3]);
+ }
+ block.position-=8;
+ block.writeUnsignedInt(v0);
+ block.writeUnsignedInt(v1);
+ }
+
+ public function dispose():void {
+ //private var k:Array;
+ var r:Random = new Random;
+ for (var i:uint=0;i<k.length;i++) {
+ k[i] = r.nextByte();
+ delete k[i];
+ }
+ k = null;
+ Memory.gc();
+ }
+
+ public function toString():String {
+ return "xtea";
+ }
+ }
+
+
+}
\ No newline at end of file diff --git a/flash-src/third-party/com/hurlant/crypto/symmetric/aeskey.pl b/flash-src/third-party/com/hurlant/crypto/symmetric/aeskey.pl new file mode 100644 index 0000000..b8f58fd --- /dev/null +++ b/flash-src/third-party/com/hurlant/crypto/symmetric/aeskey.pl @@ -0,0 +1,29 @@ +#!/usr/bin/perl +use strict; +use warnings; + +sub say { + my $w = shift; + print $w; + print "\n"; +} + +sub dump { + my $i = shift; + &say(sprintf("Sbox[%d] = _Sbox[%d]", $i, $i)); + &say(sprintf("InvSbox[%d] = _InvSbox[%d]", $i, $i)); + &say(sprintf("Xtime2Sbox[%d] = _Xtime2Sbox[%d]", $i, $i)); + &say(sprintf("Xtime3Sbox[%d] = _Xtime3Sbox[%d]", $i, $i)); + &say(sprintf("Xtime2[%d] = _Xtime2[%d]", $i, $i)); + &say(sprintf("Xtime9[%d] = _Xtime9[%d]", $i, $i)); + &say(sprintf("XtimeB[%d] = _XtimeB[%d]", $i, $i)); + &say(sprintf("XtimeD[%d] = _XtimeD[%d]", $i, $i)); + &say(sprintf("XtimeE[%d] = _XtimeE[%d]", $i, $i)); +} + +for (my $i=0;$i<256;$i++) { + &dump($i); +} + + + diff --git a/flash-src/third-party/com/hurlant/crypto/symmetric/dump.txt b/flash-src/third-party/com/hurlant/crypto/symmetric/dump.txt new file mode 100644 index 0000000..6206701 --- /dev/null +++ b/flash-src/third-party/com/hurlant/crypto/symmetric/dump.txt @@ -0,0 +1,2304 @@ +Sbox[0] = _Sbox[0] +InvSbox[0] = _InvSbox[0] +Xtime2Sbox[0] = _Xtime2Sbox[0] +Xtime3Sbox[0] = _Xtime3Sbox[0] +Xtime2[0] = _Xtime2[0] +Xtime9[0] = _Xtime9[0] +XtimeB[0] = _XtimeB[0] +XtimeD[0] = _XtimeD[0] +XtimeE[0] = _XtimeE[0] +Sbox[1] = _Sbox[1] +InvSbox[1] = _InvSbox[1] +Xtime2Sbox[1] = _Xtime2Sbox[1] +Xtime3Sbox[1] = _Xtime3Sbox[1] +Xtime2[1] = _Xtime2[1] +Xtime9[1] = _Xtime9[1] +XtimeB[1] = _XtimeB[1] +XtimeD[1] = _XtimeD[1] +XtimeE[1] = _XtimeE[1] +Sbox[2] = _Sbox[2] +InvSbox[2] = _InvSbox[2] +Xtime2Sbox[2] = _Xtime2Sbox[2] +Xtime3Sbox[2] = _Xtime3Sbox[2] +Xtime2[2] = _Xtime2[2] +Xtime9[2] = _Xtime9[2] +XtimeB[2] = _XtimeB[2] +XtimeD[2] = _XtimeD[2] +XtimeE[2] = _XtimeE[2] +Sbox[3] = _Sbox[3] +InvSbox[3] = _InvSbox[3] +Xtime2Sbox[3] = _Xtime2Sbox[3] +Xtime3Sbox[3] = _Xtime3Sbox[3] +Xtime2[3] = _Xtime2[3] +Xtime9[3] = _Xtime9[3] +XtimeB[3] = _XtimeB[3] +XtimeD[3] = _XtimeD[3] +XtimeE[3] = _XtimeE[3] +Sbox[4] = _Sbox[4] +InvSbox[4] = _InvSbox[4] +Xtime2Sbox[4] = _Xtime2Sbox[4] +Xtime3Sbox[4] = _Xtime3Sbox[4] +Xtime2[4] = _Xtime2[4] +Xtime9[4] = _Xtime9[4] +XtimeB[4] = _XtimeB[4] +XtimeD[4] = _XtimeD[4] +XtimeE[4] = _XtimeE[4] +Sbox[5] = _Sbox[5] +InvSbox[5] = _InvSbox[5] +Xtime2Sbox[5] = _Xtime2Sbox[5] +Xtime3Sbox[5] = _Xtime3Sbox[5] +Xtime2[5] = _Xtime2[5] +Xtime9[5] = _Xtime9[5] +XtimeB[5] = _XtimeB[5] +XtimeD[5] = _XtimeD[5] +XtimeE[5] = _XtimeE[5] +Sbox[6] = _Sbox[6] +InvSbox[6] = _InvSbox[6] +Xtime2Sbox[6] = _Xtime2Sbox[6] +Xtime3Sbox[6] = _Xtime3Sbox[6] +Xtime2[6] = _Xtime2[6] +Xtime9[6] = _Xtime9[6] +XtimeB[6] = _XtimeB[6] +XtimeD[6] = _XtimeD[6] +XtimeE[6] = _XtimeE[6] +Sbox[7] = _Sbox[7] +InvSbox[7] = _InvSbox[7] +Xtime2Sbox[7] = _Xtime2Sbox[7] +Xtime3Sbox[7] = _Xtime3Sbox[7] +Xtime2[7] = _Xtime2[7] +Xtime9[7] = _Xtime9[7] +XtimeB[7] = _XtimeB[7] +XtimeD[7] = _XtimeD[7] +XtimeE[7] = _XtimeE[7] +Sbox[8] = _Sbox[8] +InvSbox[8] = _InvSbox[8] +Xtime2Sbox[8] = _Xtime2Sbox[8] +Xtime3Sbox[8] = _Xtime3Sbox[8] +Xtime2[8] = _Xtime2[8] +Xtime9[8] = _Xtime9[8] +XtimeB[8] = _XtimeB[8] +XtimeD[8] = _XtimeD[8] +XtimeE[8] = _XtimeE[8] +Sbox[9] = _Sbox[9] +InvSbox[9] = _InvSbox[9] +Xtime2Sbox[9] = _Xtime2Sbox[9] +Xtime3Sbox[9] = _Xtime3Sbox[9] +Xtime2[9] = _Xtime2[9] +Xtime9[9] = _Xtime9[9] +XtimeB[9] = _XtimeB[9] +XtimeD[9] = _XtimeD[9] +XtimeE[9] = _XtimeE[9] +Sbox[10] = _Sbox[10] +InvSbox[10] = _InvSbox[10] +Xtime2Sbox[10] = _Xtime2Sbox[10] +Xtime3Sbox[10] = _Xtime3Sbox[10] +Xtime2[10] = _Xtime2[10] +Xtime9[10] = _Xtime9[10] +XtimeB[10] = _XtimeB[10] +XtimeD[10] = _XtimeD[10] +XtimeE[10] = _XtimeE[10] +Sbox[11] = _Sbox[11] +InvSbox[11] = _InvSbox[11] +Xtime2Sbox[11] = _Xtime2Sbox[11] +Xtime3Sbox[11] = _Xtime3Sbox[11] +Xtime2[11] = _Xtime2[11] +Xtime9[11] = _Xtime9[11] +XtimeB[11] = _XtimeB[11] +XtimeD[11] = _XtimeD[11] +XtimeE[11] = _XtimeE[11] +Sbox[12] = _Sbox[12] +InvSbox[12] = _InvSbox[12] +Xtime2Sbox[12] = _Xtime2Sbox[12] +Xtime3Sbox[12] = _Xtime3Sbox[12] +Xtime2[12] = _Xtime2[12] +Xtime9[12] = _Xtime9[12] +XtimeB[12] = _XtimeB[12] +XtimeD[12] = _XtimeD[12] +XtimeE[12] = _XtimeE[12] +Sbox[13] = _Sbox[13] +InvSbox[13] = _InvSbox[13] +Xtime2Sbox[13] = _Xtime2Sbox[13] +Xtime3Sbox[13] = _Xtime3Sbox[13] +Xtime2[13] = _Xtime2[13] +Xtime9[13] = _Xtime9[13] +XtimeB[13] = _XtimeB[13] +XtimeD[13] = _XtimeD[13] +XtimeE[13] = _XtimeE[13] +Sbox[14] = _Sbox[14] +InvSbox[14] = _InvSbox[14] +Xtime2Sbox[14] = _Xtime2Sbox[14] +Xtime3Sbox[14] = _Xtime3Sbox[14] +Xtime2[14] = _Xtime2[14] +Xtime9[14] = _Xtime9[14] +XtimeB[14] = _XtimeB[14] +XtimeD[14] = _XtimeD[14] +XtimeE[14] = _XtimeE[14] +Sbox[15] = _Sbox[15] +InvSbox[15] = _InvSbox[15] +Xtime2Sbox[15] = _Xtime2Sbox[15] +Xtime3Sbox[15] = _Xtime3Sbox[15] +Xtime2[15] = _Xtime2[15] +Xtime9[15] = _Xtime9[15] +XtimeB[15] = _XtimeB[15] +XtimeD[15] = _XtimeD[15] +XtimeE[15] = _XtimeE[15] +Sbox[16] = _Sbox[16] +InvSbox[16] = _InvSbox[16] +Xtime2Sbox[16] = _Xtime2Sbox[16] +Xtime3Sbox[16] = _Xtime3Sbox[16] +Xtime2[16] = _Xtime2[16] +Xtime9[16] = _Xtime9[16] +XtimeB[16] = _XtimeB[16] +XtimeD[16] = _XtimeD[16] +XtimeE[16] = _XtimeE[16] +Sbox[17] = _Sbox[17] +InvSbox[17] = _InvSbox[17] +Xtime2Sbox[17] = _Xtime2Sbox[17] +Xtime3Sbox[17] = _Xtime3Sbox[17] +Xtime2[17] = _Xtime2[17] +Xtime9[17] = _Xtime9[17] +XtimeB[17] = _XtimeB[17] +XtimeD[17] = _XtimeD[17] +XtimeE[17] = _XtimeE[17] +Sbox[18] = _Sbox[18] +InvSbox[18] = _InvSbox[18] +Xtime2Sbox[18] = _Xtime2Sbox[18] +Xtime3Sbox[18] = _Xtime3Sbox[18] +Xtime2[18] = _Xtime2[18] +Xtime9[18] = _Xtime9[18] +XtimeB[18] = _XtimeB[18] +XtimeD[18] = _XtimeD[18] +XtimeE[18] = _XtimeE[18] +Sbox[19] = _Sbox[19] +InvSbox[19] = _InvSbox[19] +Xtime2Sbox[19] = _Xtime2Sbox[19] +Xtime3Sbox[19] = _Xtime3Sbox[19] +Xtime2[19] = _Xtime2[19] +Xtime9[19] = _Xtime9[19] +XtimeB[19] = _XtimeB[19] +XtimeD[19] = _XtimeD[19] +XtimeE[19] = _XtimeE[19] +Sbox[20] = _Sbox[20] +InvSbox[20] = _InvSbox[20] +Xtime2Sbox[20] = _Xtime2Sbox[20] +Xtime3Sbox[20] = _Xtime3Sbox[20] +Xtime2[20] = _Xtime2[20] +Xtime9[20] = _Xtime9[20] +XtimeB[20] = _XtimeB[20] +XtimeD[20] = _XtimeD[20] +XtimeE[20] = _XtimeE[20] +Sbox[21] = _Sbox[21] +InvSbox[21] = _InvSbox[21] +Xtime2Sbox[21] = _Xtime2Sbox[21] +Xtime3Sbox[21] = _Xtime3Sbox[21] +Xtime2[21] = _Xtime2[21] +Xtime9[21] = _Xtime9[21] +XtimeB[21] = _XtimeB[21] +XtimeD[21] = _XtimeD[21] +XtimeE[21] = _XtimeE[21] +Sbox[22] = _Sbox[22] +InvSbox[22] = _InvSbox[22] +Xtime2Sbox[22] = _Xtime2Sbox[22] +Xtime3Sbox[22] = _Xtime3Sbox[22] +Xtime2[22] = _Xtime2[22] +Xtime9[22] = _Xtime9[22] +XtimeB[22] = _XtimeB[22] +XtimeD[22] = _XtimeD[22] +XtimeE[22] = _XtimeE[22] +Sbox[23] = _Sbox[23] +InvSbox[23] = _InvSbox[23] +Xtime2Sbox[23] = _Xtime2Sbox[23] +Xtime3Sbox[23] = _Xtime3Sbox[23] +Xtime2[23] = _Xtime2[23] +Xtime9[23] = _Xtime9[23] +XtimeB[23] = _XtimeB[23] +XtimeD[23] = _XtimeD[23] +XtimeE[23] = _XtimeE[23] +Sbox[24] = _Sbox[24] +InvSbox[24] = _InvSbox[24] +Xtime2Sbox[24] = _Xtime2Sbox[24] +Xtime3Sbox[24] = _Xtime3Sbox[24] +Xtime2[24] = _Xtime2[24] +Xtime9[24] = _Xtime9[24] +XtimeB[24] = _XtimeB[24] +XtimeD[24] = _XtimeD[24] +XtimeE[24] = _XtimeE[24] +Sbox[25] = _Sbox[25] +InvSbox[25] = _InvSbox[25] +Xtime2Sbox[25] = _Xtime2Sbox[25] +Xtime3Sbox[25] = _Xtime3Sbox[25] +Xtime2[25] = _Xtime2[25] +Xtime9[25] = _Xtime9[25] +XtimeB[25] = _XtimeB[25] +XtimeD[25] = _XtimeD[25] +XtimeE[25] = _XtimeE[25] +Sbox[26] = _Sbox[26] +InvSbox[26] = _InvSbox[26] +Xtime2Sbox[26] = _Xtime2Sbox[26] +Xtime3Sbox[26] = _Xtime3Sbox[26] +Xtime2[26] = _Xtime2[26] +Xtime9[26] = _Xtime9[26] +XtimeB[26] = _XtimeB[26] +XtimeD[26] = _XtimeD[26] +XtimeE[26] = _XtimeE[26] +Sbox[27] = _Sbox[27] +InvSbox[27] = _InvSbox[27] +Xtime2Sbox[27] = _Xtime2Sbox[27] +Xtime3Sbox[27] = _Xtime3Sbox[27] +Xtime2[27] = _Xtime2[27] +Xtime9[27] = _Xtime9[27] +XtimeB[27] = _XtimeB[27] +XtimeD[27] = _XtimeD[27] +XtimeE[27] = _XtimeE[27] +Sbox[28] = _Sbox[28] +InvSbox[28] = _InvSbox[28] +Xtime2Sbox[28] = _Xtime2Sbox[28] +Xtime3Sbox[28] = _Xtime3Sbox[28] +Xtime2[28] = _Xtime2[28] +Xtime9[28] = _Xtime9[28] +XtimeB[28] = _XtimeB[28] +XtimeD[28] = _XtimeD[28] +XtimeE[28] = _XtimeE[28] +Sbox[29] = _Sbox[29] +InvSbox[29] = _InvSbox[29] +Xtime2Sbox[29] = _Xtime2Sbox[29] +Xtime3Sbox[29] = _Xtime3Sbox[29] +Xtime2[29] = _Xtime2[29] +Xtime9[29] = _Xtime9[29] +XtimeB[29] = _XtimeB[29] +XtimeD[29] = _XtimeD[29] +XtimeE[29] = _XtimeE[29] +Sbox[30] = _Sbox[30] +InvSbox[30] = _InvSbox[30] +Xtime2Sbox[30] = _Xtime2Sbox[30] +Xtime3Sbox[30] = _Xtime3Sbox[30] +Xtime2[30] = _Xtime2[30] +Xtime9[30] = _Xtime9[30] +XtimeB[30] = _XtimeB[30] +XtimeD[30] = _XtimeD[30] +XtimeE[30] = _XtimeE[30] +Sbox[31] = _Sbox[31] +InvSbox[31] = _InvSbox[31] +Xtime2Sbox[31] = _Xtime2Sbox[31] +Xtime3Sbox[31] = _Xtime3Sbox[31] +Xtime2[31] = _Xtime2[31] +Xtime9[31] = _Xtime9[31] +XtimeB[31] = _XtimeB[31] +XtimeD[31] = _XtimeD[31] +XtimeE[31] = _XtimeE[31] +Sbox[32] = _Sbox[32] +InvSbox[32] = _InvSbox[32] +Xtime2Sbox[32] = _Xtime2Sbox[32] +Xtime3Sbox[32] = _Xtime3Sbox[32] +Xtime2[32] = _Xtime2[32] +Xtime9[32] = _Xtime9[32] +XtimeB[32] = _XtimeB[32] +XtimeD[32] = _XtimeD[32] +XtimeE[32] = _XtimeE[32] +Sbox[33] = _Sbox[33] +InvSbox[33] = _InvSbox[33] +Xtime2Sbox[33] = _Xtime2Sbox[33] +Xtime3Sbox[33] = _Xtime3Sbox[33] +Xtime2[33] = _Xtime2[33] +Xtime9[33] = _Xtime9[33] +XtimeB[33] = _XtimeB[33] +XtimeD[33] = _XtimeD[33] +XtimeE[33] = _XtimeE[33] +Sbox[34] = _Sbox[34] +InvSbox[34] = _InvSbox[34] +Xtime2Sbox[34] = _Xtime2Sbox[34] +Xtime3Sbox[34] = _Xtime3Sbox[34] +Xtime2[34] = _Xtime2[34] +Xtime9[34] = _Xtime9[34] +XtimeB[34] = _XtimeB[34] +XtimeD[34] = _XtimeD[34] +XtimeE[34] = _XtimeE[34] +Sbox[35] = _Sbox[35] +InvSbox[35] = _InvSbox[35] +Xtime2Sbox[35] = _Xtime2Sbox[35] +Xtime3Sbox[35] = _Xtime3Sbox[35] +Xtime2[35] = _Xtime2[35] +Xtime9[35] = _Xtime9[35] +XtimeB[35] = _XtimeB[35] +XtimeD[35] = _XtimeD[35] +XtimeE[35] = _XtimeE[35] +Sbox[36] = _Sbox[36] +InvSbox[36] = _InvSbox[36] +Xtime2Sbox[36] = _Xtime2Sbox[36] +Xtime3Sbox[36] = _Xtime3Sbox[36] +Xtime2[36] = _Xtime2[36] +Xtime9[36] = _Xtime9[36] +XtimeB[36] = _XtimeB[36] +XtimeD[36] = _XtimeD[36] +XtimeE[36] = _XtimeE[36] +Sbox[37] = _Sbox[37] +InvSbox[37] = _InvSbox[37] +Xtime2Sbox[37] = _Xtime2Sbox[37] +Xtime3Sbox[37] = _Xtime3Sbox[37] +Xtime2[37] = _Xtime2[37] +Xtime9[37] = _Xtime9[37] +XtimeB[37] = _XtimeB[37] +XtimeD[37] = _XtimeD[37] +XtimeE[37] = _XtimeE[37] +Sbox[38] = _Sbox[38] +InvSbox[38] = _InvSbox[38] +Xtime2Sbox[38] = _Xtime2Sbox[38] +Xtime3Sbox[38] = _Xtime3Sbox[38] +Xtime2[38] = _Xtime2[38] +Xtime9[38] = _Xtime9[38] +XtimeB[38] = _XtimeB[38] +XtimeD[38] = _XtimeD[38] +XtimeE[38] = _XtimeE[38] +Sbox[39] = _Sbox[39] +InvSbox[39] = _InvSbox[39] +Xtime2Sbox[39] = _Xtime2Sbox[39] +Xtime3Sbox[39] = _Xtime3Sbox[39] +Xtime2[39] = _Xtime2[39] +Xtime9[39] = _Xtime9[39] +XtimeB[39] = _XtimeB[39] +XtimeD[39] = _XtimeD[39] +XtimeE[39] = _XtimeE[39] +Sbox[40] = _Sbox[40] +InvSbox[40] = _InvSbox[40] +Xtime2Sbox[40] = _Xtime2Sbox[40] +Xtime3Sbox[40] = _Xtime3Sbox[40] +Xtime2[40] = _Xtime2[40] +Xtime9[40] = _Xtime9[40] +XtimeB[40] = _XtimeB[40] +XtimeD[40] = _XtimeD[40] +XtimeE[40] = _XtimeE[40] +Sbox[41] = _Sbox[41] +InvSbox[41] = _InvSbox[41] +Xtime2Sbox[41] = _Xtime2Sbox[41] +Xtime3Sbox[41] = _Xtime3Sbox[41] +Xtime2[41] = _Xtime2[41] +Xtime9[41] = _Xtime9[41] +XtimeB[41] = _XtimeB[41] +XtimeD[41] = _XtimeD[41] +XtimeE[41] = _XtimeE[41] +Sbox[42] = _Sbox[42] +InvSbox[42] = _InvSbox[42] +Xtime2Sbox[42] = _Xtime2Sbox[42] +Xtime3Sbox[42] = _Xtime3Sbox[42] +Xtime2[42] = _Xtime2[42] +Xtime9[42] = _Xtime9[42] +XtimeB[42] = _XtimeB[42] +XtimeD[42] = _XtimeD[42] +XtimeE[42] = _XtimeE[42] +Sbox[43] = _Sbox[43] +InvSbox[43] = _InvSbox[43] +Xtime2Sbox[43] = _Xtime2Sbox[43] +Xtime3Sbox[43] = _Xtime3Sbox[43] +Xtime2[43] = _Xtime2[43] +Xtime9[43] = _Xtime9[43] +XtimeB[43] = _XtimeB[43] +XtimeD[43] = _XtimeD[43] +XtimeE[43] = _XtimeE[43] +Sbox[44] = _Sbox[44] +InvSbox[44] = _InvSbox[44] +Xtime2Sbox[44] = _Xtime2Sbox[44] +Xtime3Sbox[44] = _Xtime3Sbox[44] +Xtime2[44] = _Xtime2[44] +Xtime9[44] = _Xtime9[44] +XtimeB[44] = _XtimeB[44] +XtimeD[44] = _XtimeD[44] +XtimeE[44] = _XtimeE[44] +Sbox[45] = _Sbox[45] +InvSbox[45] = _InvSbox[45] +Xtime2Sbox[45] = _Xtime2Sbox[45] +Xtime3Sbox[45] = _Xtime3Sbox[45] +Xtime2[45] = _Xtime2[45] +Xtime9[45] = _Xtime9[45] +XtimeB[45] = _XtimeB[45] +XtimeD[45] = _XtimeD[45] +XtimeE[45] = _XtimeE[45] +Sbox[46] = _Sbox[46] +InvSbox[46] = _InvSbox[46] +Xtime2Sbox[46] = _Xtime2Sbox[46] +Xtime3Sbox[46] = _Xtime3Sbox[46] +Xtime2[46] = _Xtime2[46] +Xtime9[46] = _Xtime9[46] +XtimeB[46] = _XtimeB[46] +XtimeD[46] = _XtimeD[46] +XtimeE[46] = _XtimeE[46] +Sbox[47] = _Sbox[47] +InvSbox[47] = _InvSbox[47] +Xtime2Sbox[47] = _Xtime2Sbox[47] +Xtime3Sbox[47] = _Xtime3Sbox[47] +Xtime2[47] = _Xtime2[47] +Xtime9[47] = _Xtime9[47] +XtimeB[47] = _XtimeB[47] +XtimeD[47] = _XtimeD[47] +XtimeE[47] = _XtimeE[47] +Sbox[48] = _Sbox[48] +InvSbox[48] = _InvSbox[48] +Xtime2Sbox[48] = _Xtime2Sbox[48] +Xtime3Sbox[48] = _Xtime3Sbox[48] +Xtime2[48] = _Xtime2[48] +Xtime9[48] = _Xtime9[48] +XtimeB[48] = _XtimeB[48] +XtimeD[48] = _XtimeD[48] +XtimeE[48] = _XtimeE[48] +Sbox[49] = _Sbox[49] +InvSbox[49] = _InvSbox[49] +Xtime2Sbox[49] = _Xtime2Sbox[49] +Xtime3Sbox[49] = _Xtime3Sbox[49] +Xtime2[49] = _Xtime2[49] +Xtime9[49] = _Xtime9[49] +XtimeB[49] = _XtimeB[49] +XtimeD[49] = _XtimeD[49] +XtimeE[49] = _XtimeE[49] +Sbox[50] = _Sbox[50] +InvSbox[50] = _InvSbox[50] +Xtime2Sbox[50] = _Xtime2Sbox[50] +Xtime3Sbox[50] = _Xtime3Sbox[50] +Xtime2[50] = _Xtime2[50] +Xtime9[50] = _Xtime9[50] +XtimeB[50] = _XtimeB[50] +XtimeD[50] = _XtimeD[50] +XtimeE[50] = _XtimeE[50] +Sbox[51] = _Sbox[51] +InvSbox[51] = _InvSbox[51] +Xtime2Sbox[51] = _Xtime2Sbox[51] +Xtime3Sbox[51] = _Xtime3Sbox[51] +Xtime2[51] = _Xtime2[51] +Xtime9[51] = _Xtime9[51] +XtimeB[51] = _XtimeB[51] +XtimeD[51] = _XtimeD[51] +XtimeE[51] = _XtimeE[51] +Sbox[52] = _Sbox[52] +InvSbox[52] = _InvSbox[52] +Xtime2Sbox[52] = _Xtime2Sbox[52] +Xtime3Sbox[52] = _Xtime3Sbox[52] +Xtime2[52] = _Xtime2[52] +Xtime9[52] = _Xtime9[52] +XtimeB[52] = _XtimeB[52] +XtimeD[52] = _XtimeD[52] +XtimeE[52] = _XtimeE[52] +Sbox[53] = _Sbox[53] +InvSbox[53] = _InvSbox[53] +Xtime2Sbox[53] = _Xtime2Sbox[53] +Xtime3Sbox[53] = _Xtime3Sbox[53] +Xtime2[53] = _Xtime2[53] +Xtime9[53] = _Xtime9[53] +XtimeB[53] = _XtimeB[53] +XtimeD[53] = _XtimeD[53] +XtimeE[53] = _XtimeE[53] +Sbox[54] = _Sbox[54] +InvSbox[54] = _InvSbox[54] +Xtime2Sbox[54] = _Xtime2Sbox[54] +Xtime3Sbox[54] = _Xtime3Sbox[54] +Xtime2[54] = _Xtime2[54] +Xtime9[54] = _Xtime9[54] +XtimeB[54] = _XtimeB[54] +XtimeD[54] = _XtimeD[54] +XtimeE[54] = _XtimeE[54] +Sbox[55] = _Sbox[55] +InvSbox[55] = _InvSbox[55] +Xtime2Sbox[55] = _Xtime2Sbox[55] +Xtime3Sbox[55] = _Xtime3Sbox[55] +Xtime2[55] = _Xtime2[55] +Xtime9[55] = _Xtime9[55] +XtimeB[55] = _XtimeB[55] +XtimeD[55] = _XtimeD[55] +XtimeE[55] = _XtimeE[55] +Sbox[56] = _Sbox[56] +InvSbox[56] = _InvSbox[56] +Xtime2Sbox[56] = _Xtime2Sbox[56] +Xtime3Sbox[56] = _Xtime3Sbox[56] +Xtime2[56] = _Xtime2[56] +Xtime9[56] = _Xtime9[56] +XtimeB[56] = _XtimeB[56] +XtimeD[56] = _XtimeD[56] +XtimeE[56] = _XtimeE[56] +Sbox[57] = _Sbox[57] +InvSbox[57] = _InvSbox[57] +Xtime2Sbox[57] = _Xtime2Sbox[57] +Xtime3Sbox[57] = _Xtime3Sbox[57] +Xtime2[57] = _Xtime2[57] +Xtime9[57] = _Xtime9[57] +XtimeB[57] = _XtimeB[57] +XtimeD[57] = _XtimeD[57] +XtimeE[57] = _XtimeE[57] +Sbox[58] = _Sbox[58] +InvSbox[58] = _InvSbox[58] +Xtime2Sbox[58] = _Xtime2Sbox[58] +Xtime3Sbox[58] = _Xtime3Sbox[58] +Xtime2[58] = _Xtime2[58] +Xtime9[58] = _Xtime9[58] +XtimeB[58] = _XtimeB[58] +XtimeD[58] = _XtimeD[58] +XtimeE[58] = _XtimeE[58] +Sbox[59] = _Sbox[59] +InvSbox[59] = _InvSbox[59] +Xtime2Sbox[59] = _Xtime2Sbox[59] +Xtime3Sbox[59] = _Xtime3Sbox[59] +Xtime2[59] = _Xtime2[59] +Xtime9[59] = _Xtime9[59] +XtimeB[59] = _XtimeB[59] +XtimeD[59] = _XtimeD[59] +XtimeE[59] = _XtimeE[59] +Sbox[60] = _Sbox[60] +InvSbox[60] = _InvSbox[60] +Xtime2Sbox[60] = _Xtime2Sbox[60] +Xtime3Sbox[60] = _Xtime3Sbox[60] +Xtime2[60] = _Xtime2[60] +Xtime9[60] = _Xtime9[60] +XtimeB[60] = _XtimeB[60] +XtimeD[60] = _XtimeD[60] +XtimeE[60] = _XtimeE[60] +Sbox[61] = _Sbox[61] +InvSbox[61] = _InvSbox[61] +Xtime2Sbox[61] = _Xtime2Sbox[61] +Xtime3Sbox[61] = _Xtime3Sbox[61] +Xtime2[61] = _Xtime2[61] +Xtime9[61] = _Xtime9[61] +XtimeB[61] = _XtimeB[61] +XtimeD[61] = _XtimeD[61] +XtimeE[61] = _XtimeE[61] +Sbox[62] = _Sbox[62] +InvSbox[62] = _InvSbox[62] +Xtime2Sbox[62] = _Xtime2Sbox[62] +Xtime3Sbox[62] = _Xtime3Sbox[62] +Xtime2[62] = _Xtime2[62] +Xtime9[62] = _Xtime9[62] +XtimeB[62] = _XtimeB[62] +XtimeD[62] = _XtimeD[62] +XtimeE[62] = _XtimeE[62] +Sbox[63] = _Sbox[63] +InvSbox[63] = _InvSbox[63] +Xtime2Sbox[63] = _Xtime2Sbox[63] +Xtime3Sbox[63] = _Xtime3Sbox[63] +Xtime2[63] = _Xtime2[63] +Xtime9[63] = _Xtime9[63] +XtimeB[63] = _XtimeB[63] +XtimeD[63] = _XtimeD[63] +XtimeE[63] = _XtimeE[63] +Sbox[64] = _Sbox[64] +InvSbox[64] = _InvSbox[64] +Xtime2Sbox[64] = _Xtime2Sbox[64] +Xtime3Sbox[64] = _Xtime3Sbox[64] +Xtime2[64] = _Xtime2[64] +Xtime9[64] = _Xtime9[64] +XtimeB[64] = _XtimeB[64] +XtimeD[64] = _XtimeD[64] +XtimeE[64] = _XtimeE[64] +Sbox[65] = _Sbox[65] +InvSbox[65] = _InvSbox[65] +Xtime2Sbox[65] = _Xtime2Sbox[65] +Xtime3Sbox[65] = _Xtime3Sbox[65] +Xtime2[65] = _Xtime2[65] +Xtime9[65] = _Xtime9[65] +XtimeB[65] = _XtimeB[65] +XtimeD[65] = _XtimeD[65] +XtimeE[65] = _XtimeE[65] +Sbox[66] = _Sbox[66] +InvSbox[66] = _InvSbox[66] +Xtime2Sbox[66] = _Xtime2Sbox[66] +Xtime3Sbox[66] = _Xtime3Sbox[66] +Xtime2[66] = _Xtime2[66] +Xtime9[66] = _Xtime9[66] +XtimeB[66] = _XtimeB[66] +XtimeD[66] = _XtimeD[66] +XtimeE[66] = _XtimeE[66] +Sbox[67] = _Sbox[67] +InvSbox[67] = _InvSbox[67] +Xtime2Sbox[67] = _Xtime2Sbox[67] +Xtime3Sbox[67] = _Xtime3Sbox[67] +Xtime2[67] = _Xtime2[67] +Xtime9[67] = _Xtime9[67] +XtimeB[67] = _XtimeB[67] +XtimeD[67] = _XtimeD[67] +XtimeE[67] = _XtimeE[67] +Sbox[68] = _Sbox[68] +InvSbox[68] = _InvSbox[68] +Xtime2Sbox[68] = _Xtime2Sbox[68] +Xtime3Sbox[68] = _Xtime3Sbox[68] +Xtime2[68] = _Xtime2[68] +Xtime9[68] = _Xtime9[68] +XtimeB[68] = _XtimeB[68] +XtimeD[68] = _XtimeD[68] +XtimeE[68] = _XtimeE[68] +Sbox[69] = _Sbox[69] +InvSbox[69] = _InvSbox[69] +Xtime2Sbox[69] = _Xtime2Sbox[69] +Xtime3Sbox[69] = _Xtime3Sbox[69] +Xtime2[69] = _Xtime2[69] +Xtime9[69] = _Xtime9[69] +XtimeB[69] = _XtimeB[69] +XtimeD[69] = _XtimeD[69] +XtimeE[69] = _XtimeE[69] +Sbox[70] = _Sbox[70] +InvSbox[70] = _InvSbox[70] +Xtime2Sbox[70] = _Xtime2Sbox[70] +Xtime3Sbox[70] = _Xtime3Sbox[70] +Xtime2[70] = _Xtime2[70] +Xtime9[70] = _Xtime9[70] +XtimeB[70] = _XtimeB[70] +XtimeD[70] = _XtimeD[70] +XtimeE[70] = _XtimeE[70] +Sbox[71] = _Sbox[71] +InvSbox[71] = _InvSbox[71] +Xtime2Sbox[71] = _Xtime2Sbox[71] +Xtime3Sbox[71] = _Xtime3Sbox[71] +Xtime2[71] = _Xtime2[71] +Xtime9[71] = _Xtime9[71] +XtimeB[71] = _XtimeB[71] +XtimeD[71] = _XtimeD[71] +XtimeE[71] = _XtimeE[71] +Sbox[72] = _Sbox[72] +InvSbox[72] = _InvSbox[72] +Xtime2Sbox[72] = _Xtime2Sbox[72] +Xtime3Sbox[72] = _Xtime3Sbox[72] +Xtime2[72] = _Xtime2[72] +Xtime9[72] = _Xtime9[72] +XtimeB[72] = _XtimeB[72] +XtimeD[72] = _XtimeD[72] +XtimeE[72] = _XtimeE[72] +Sbox[73] = _Sbox[73] +InvSbox[73] = _InvSbox[73] +Xtime2Sbox[73] = _Xtime2Sbox[73] +Xtime3Sbox[73] = _Xtime3Sbox[73] +Xtime2[73] = _Xtime2[73] +Xtime9[73] = _Xtime9[73] +XtimeB[73] = _XtimeB[73] +XtimeD[73] = _XtimeD[73] +XtimeE[73] = _XtimeE[73] +Sbox[74] = _Sbox[74] +InvSbox[74] = _InvSbox[74] +Xtime2Sbox[74] = _Xtime2Sbox[74] +Xtime3Sbox[74] = _Xtime3Sbox[74] +Xtime2[74] = _Xtime2[74] +Xtime9[74] = _Xtime9[74] +XtimeB[74] = _XtimeB[74] +XtimeD[74] = _XtimeD[74] +XtimeE[74] = _XtimeE[74] +Sbox[75] = _Sbox[75] +InvSbox[75] = _InvSbox[75] +Xtime2Sbox[75] = _Xtime2Sbox[75] +Xtime3Sbox[75] = _Xtime3Sbox[75] +Xtime2[75] = _Xtime2[75] +Xtime9[75] = _Xtime9[75] +XtimeB[75] = _XtimeB[75] +XtimeD[75] = _XtimeD[75] +XtimeE[75] = _XtimeE[75] +Sbox[76] = _Sbox[76] +InvSbox[76] = _InvSbox[76] +Xtime2Sbox[76] = _Xtime2Sbox[76] +Xtime3Sbox[76] = _Xtime3Sbox[76] +Xtime2[76] = _Xtime2[76] +Xtime9[76] = _Xtime9[76] +XtimeB[76] = _XtimeB[76] +XtimeD[76] = _XtimeD[76] +XtimeE[76] = _XtimeE[76] +Sbox[77] = _Sbox[77] +InvSbox[77] = _InvSbox[77] +Xtime2Sbox[77] = _Xtime2Sbox[77] +Xtime3Sbox[77] = _Xtime3Sbox[77] +Xtime2[77] = _Xtime2[77] +Xtime9[77] = _Xtime9[77] +XtimeB[77] = _XtimeB[77] +XtimeD[77] = _XtimeD[77] +XtimeE[77] = _XtimeE[77] +Sbox[78] = _Sbox[78] +InvSbox[78] = _InvSbox[78] +Xtime2Sbox[78] = _Xtime2Sbox[78] +Xtime3Sbox[78] = _Xtime3Sbox[78] +Xtime2[78] = _Xtime2[78] +Xtime9[78] = _Xtime9[78] +XtimeB[78] = _XtimeB[78] +XtimeD[78] = _XtimeD[78] +XtimeE[78] = _XtimeE[78] +Sbox[79] = _Sbox[79] +InvSbox[79] = _InvSbox[79] +Xtime2Sbox[79] = _Xtime2Sbox[79] +Xtime3Sbox[79] = _Xtime3Sbox[79] +Xtime2[79] = _Xtime2[79] +Xtime9[79] = _Xtime9[79] +XtimeB[79] = _XtimeB[79] +XtimeD[79] = _XtimeD[79] +XtimeE[79] = _XtimeE[79] +Sbox[80] = _Sbox[80] +InvSbox[80] = _InvSbox[80] +Xtime2Sbox[80] = _Xtime2Sbox[80] +Xtime3Sbox[80] = _Xtime3Sbox[80] +Xtime2[80] = _Xtime2[80] +Xtime9[80] = _Xtime9[80] +XtimeB[80] = _XtimeB[80] +XtimeD[80] = _XtimeD[80] +XtimeE[80] = _XtimeE[80] +Sbox[81] = _Sbox[81] +InvSbox[81] = _InvSbox[81] +Xtime2Sbox[81] = _Xtime2Sbox[81] +Xtime3Sbox[81] = _Xtime3Sbox[81] +Xtime2[81] = _Xtime2[81] +Xtime9[81] = _Xtime9[81] +XtimeB[81] = _XtimeB[81] +XtimeD[81] = _XtimeD[81] +XtimeE[81] = _XtimeE[81] +Sbox[82] = _Sbox[82] +InvSbox[82] = _InvSbox[82] +Xtime2Sbox[82] = _Xtime2Sbox[82] +Xtime3Sbox[82] = _Xtime3Sbox[82] +Xtime2[82] = _Xtime2[82] +Xtime9[82] = _Xtime9[82] +XtimeB[82] = _XtimeB[82] +XtimeD[82] = _XtimeD[82] +XtimeE[82] = _XtimeE[82] +Sbox[83] = _Sbox[83] +InvSbox[83] = _InvSbox[83] +Xtime2Sbox[83] = _Xtime2Sbox[83] +Xtime3Sbox[83] = _Xtime3Sbox[83] +Xtime2[83] = _Xtime2[83] +Xtime9[83] = _Xtime9[83] +XtimeB[83] = _XtimeB[83] +XtimeD[83] = _XtimeD[83] +XtimeE[83] = _XtimeE[83] +Sbox[84] = _Sbox[84] +InvSbox[84] = _InvSbox[84] +Xtime2Sbox[84] = _Xtime2Sbox[84] +Xtime3Sbox[84] = _Xtime3Sbox[84] +Xtime2[84] = _Xtime2[84] +Xtime9[84] = _Xtime9[84] +XtimeB[84] = _XtimeB[84] +XtimeD[84] = _XtimeD[84] +XtimeE[84] = _XtimeE[84] +Sbox[85] = _Sbox[85] +InvSbox[85] = _InvSbox[85] +Xtime2Sbox[85] = _Xtime2Sbox[85] +Xtime3Sbox[85] = _Xtime3Sbox[85] +Xtime2[85] = _Xtime2[85] +Xtime9[85] = _Xtime9[85] +XtimeB[85] = _XtimeB[85] +XtimeD[85] = _XtimeD[85] +XtimeE[85] = _XtimeE[85] +Sbox[86] = _Sbox[86] +InvSbox[86] = _InvSbox[86] +Xtime2Sbox[86] = _Xtime2Sbox[86] +Xtime3Sbox[86] = _Xtime3Sbox[86] +Xtime2[86] = _Xtime2[86] +Xtime9[86] = _Xtime9[86] +XtimeB[86] = _XtimeB[86] +XtimeD[86] = _XtimeD[86] +XtimeE[86] = _XtimeE[86] +Sbox[87] = _Sbox[87] +InvSbox[87] = _InvSbox[87] +Xtime2Sbox[87] = _Xtime2Sbox[87] +Xtime3Sbox[87] = _Xtime3Sbox[87] +Xtime2[87] = _Xtime2[87] +Xtime9[87] = _Xtime9[87] +XtimeB[87] = _XtimeB[87] +XtimeD[87] = _XtimeD[87] +XtimeE[87] = _XtimeE[87] +Sbox[88] = _Sbox[88] +InvSbox[88] = _InvSbox[88] +Xtime2Sbox[88] = _Xtime2Sbox[88] +Xtime3Sbox[88] = _Xtime3Sbox[88] +Xtime2[88] = _Xtime2[88] +Xtime9[88] = _Xtime9[88] +XtimeB[88] = _XtimeB[88] +XtimeD[88] = _XtimeD[88] +XtimeE[88] = _XtimeE[88] +Sbox[89] = _Sbox[89] +InvSbox[89] = _InvSbox[89] +Xtime2Sbox[89] = _Xtime2Sbox[89] +Xtime3Sbox[89] = _Xtime3Sbox[89] +Xtime2[89] = _Xtime2[89] +Xtime9[89] = _Xtime9[89] +XtimeB[89] = _XtimeB[89] +XtimeD[89] = _XtimeD[89] +XtimeE[89] = _XtimeE[89] +Sbox[90] = _Sbox[90] +InvSbox[90] = _InvSbox[90] +Xtime2Sbox[90] = _Xtime2Sbox[90] +Xtime3Sbox[90] = _Xtime3Sbox[90] +Xtime2[90] = _Xtime2[90] +Xtime9[90] = _Xtime9[90] +XtimeB[90] = _XtimeB[90] +XtimeD[90] = _XtimeD[90] +XtimeE[90] = _XtimeE[90] +Sbox[91] = _Sbox[91] +InvSbox[91] = _InvSbox[91] +Xtime2Sbox[91] = _Xtime2Sbox[91] +Xtime3Sbox[91] = _Xtime3Sbox[91] +Xtime2[91] = _Xtime2[91] +Xtime9[91] = _Xtime9[91] +XtimeB[91] = _XtimeB[91] +XtimeD[91] = _XtimeD[91] +XtimeE[91] = _XtimeE[91] +Sbox[92] = _Sbox[92] +InvSbox[92] = _InvSbox[92] +Xtime2Sbox[92] = _Xtime2Sbox[92] +Xtime3Sbox[92] = _Xtime3Sbox[92] +Xtime2[92] = _Xtime2[92] +Xtime9[92] = _Xtime9[92] +XtimeB[92] = _XtimeB[92] +XtimeD[92] = _XtimeD[92] +XtimeE[92] = _XtimeE[92] +Sbox[93] = _Sbox[93] +InvSbox[93] = _InvSbox[93] +Xtime2Sbox[93] = _Xtime2Sbox[93] +Xtime3Sbox[93] = _Xtime3Sbox[93] +Xtime2[93] = _Xtime2[93] +Xtime9[93] = _Xtime9[93] +XtimeB[93] = _XtimeB[93] +XtimeD[93] = _XtimeD[93] +XtimeE[93] = _XtimeE[93] +Sbox[94] = _Sbox[94] +InvSbox[94] = _InvSbox[94] +Xtime2Sbox[94] = _Xtime2Sbox[94] +Xtime3Sbox[94] = _Xtime3Sbox[94] +Xtime2[94] = _Xtime2[94] +Xtime9[94] = _Xtime9[94] +XtimeB[94] = _XtimeB[94] +XtimeD[94] = _XtimeD[94] +XtimeE[94] = _XtimeE[94] +Sbox[95] = _Sbox[95] +InvSbox[95] = _InvSbox[95] +Xtime2Sbox[95] = _Xtime2Sbox[95] +Xtime3Sbox[95] = _Xtime3Sbox[95] +Xtime2[95] = _Xtime2[95] +Xtime9[95] = _Xtime9[95] +XtimeB[95] = _XtimeB[95] +XtimeD[95] = _XtimeD[95] +XtimeE[95] = _XtimeE[95] +Sbox[96] = _Sbox[96] +InvSbox[96] = _InvSbox[96] +Xtime2Sbox[96] = _Xtime2Sbox[96] +Xtime3Sbox[96] = _Xtime3Sbox[96] +Xtime2[96] = _Xtime2[96] +Xtime9[96] = _Xtime9[96] +XtimeB[96] = _XtimeB[96] +XtimeD[96] = _XtimeD[96] +XtimeE[96] = _XtimeE[96] +Sbox[97] = _Sbox[97] +InvSbox[97] = _InvSbox[97] +Xtime2Sbox[97] = _Xtime2Sbox[97] +Xtime3Sbox[97] = _Xtime3Sbox[97] +Xtime2[97] = _Xtime2[97] +Xtime9[97] = _Xtime9[97] +XtimeB[97] = _XtimeB[97] +XtimeD[97] = _XtimeD[97] +XtimeE[97] = _XtimeE[97] +Sbox[98] = _Sbox[98] +InvSbox[98] = _InvSbox[98] +Xtime2Sbox[98] = _Xtime2Sbox[98] +Xtime3Sbox[98] = _Xtime3Sbox[98] +Xtime2[98] = _Xtime2[98] +Xtime9[98] = _Xtime9[98] +XtimeB[98] = _XtimeB[98] +XtimeD[98] = _XtimeD[98] +XtimeE[98] = _XtimeE[98] +Sbox[99] = _Sbox[99] +InvSbox[99] = _InvSbox[99] +Xtime2Sbox[99] = _Xtime2Sbox[99] +Xtime3Sbox[99] = _Xtime3Sbox[99] +Xtime2[99] = _Xtime2[99] +Xtime9[99] = _Xtime9[99] +XtimeB[99] = _XtimeB[99] +XtimeD[99] = _XtimeD[99] +XtimeE[99] = _XtimeE[99] +Sbox[100] = _Sbox[100] +InvSbox[100] = _InvSbox[100] +Xtime2Sbox[100] = _Xtime2Sbox[100] +Xtime3Sbox[100] = _Xtime3Sbox[100] +Xtime2[100] = _Xtime2[100] +Xtime9[100] = _Xtime9[100] +XtimeB[100] = _XtimeB[100] +XtimeD[100] = _XtimeD[100] +XtimeE[100] = _XtimeE[100] +Sbox[101] = _Sbox[101] +InvSbox[101] = _InvSbox[101] +Xtime2Sbox[101] = _Xtime2Sbox[101] +Xtime3Sbox[101] = _Xtime3Sbox[101] +Xtime2[101] = _Xtime2[101] +Xtime9[101] = _Xtime9[101] +XtimeB[101] = _XtimeB[101] +XtimeD[101] = _XtimeD[101] +XtimeE[101] = _XtimeE[101] +Sbox[102] = _Sbox[102] +InvSbox[102] = _InvSbox[102] +Xtime2Sbox[102] = _Xtime2Sbox[102] +Xtime3Sbox[102] = _Xtime3Sbox[102] +Xtime2[102] = _Xtime2[102] +Xtime9[102] = _Xtime9[102] +XtimeB[102] = _XtimeB[102] +XtimeD[102] = _XtimeD[102] +XtimeE[102] = _XtimeE[102] +Sbox[103] = _Sbox[103] +InvSbox[103] = _InvSbox[103] +Xtime2Sbox[103] = _Xtime2Sbox[103] +Xtime3Sbox[103] = _Xtime3Sbox[103] +Xtime2[103] = _Xtime2[103] +Xtime9[103] = _Xtime9[103] +XtimeB[103] = _XtimeB[103] +XtimeD[103] = _XtimeD[103] +XtimeE[103] = _XtimeE[103] +Sbox[104] = _Sbox[104] +InvSbox[104] = _InvSbox[104] +Xtime2Sbox[104] = _Xtime2Sbox[104] +Xtime3Sbox[104] = _Xtime3Sbox[104] +Xtime2[104] = _Xtime2[104] +Xtime9[104] = _Xtime9[104] +XtimeB[104] = _XtimeB[104] +XtimeD[104] = _XtimeD[104] +XtimeE[104] = _XtimeE[104] +Sbox[105] = _Sbox[105] +InvSbox[105] = _InvSbox[105] +Xtime2Sbox[105] = _Xtime2Sbox[105] +Xtime3Sbox[105] = _Xtime3Sbox[105] +Xtime2[105] = _Xtime2[105] +Xtime9[105] = _Xtime9[105] +XtimeB[105] = _XtimeB[105] +XtimeD[105] = _XtimeD[105] +XtimeE[105] = _XtimeE[105] +Sbox[106] = _Sbox[106] +InvSbox[106] = _InvSbox[106] +Xtime2Sbox[106] = _Xtime2Sbox[106] +Xtime3Sbox[106] = _Xtime3Sbox[106] +Xtime2[106] = _Xtime2[106] +Xtime9[106] = _Xtime9[106] +XtimeB[106] = _XtimeB[106] +XtimeD[106] = _XtimeD[106] +XtimeE[106] = _XtimeE[106] +Sbox[107] = _Sbox[107] +InvSbox[107] = _InvSbox[107] +Xtime2Sbox[107] = _Xtime2Sbox[107] +Xtime3Sbox[107] = _Xtime3Sbox[107] +Xtime2[107] = _Xtime2[107] +Xtime9[107] = _Xtime9[107] +XtimeB[107] = _XtimeB[107] +XtimeD[107] = _XtimeD[107] +XtimeE[107] = _XtimeE[107] +Sbox[108] = _Sbox[108] +InvSbox[108] = _InvSbox[108] +Xtime2Sbox[108] = _Xtime2Sbox[108] +Xtime3Sbox[108] = _Xtime3Sbox[108] +Xtime2[108] = _Xtime2[108] +Xtime9[108] = _Xtime9[108] +XtimeB[108] = _XtimeB[108] +XtimeD[108] = _XtimeD[108] +XtimeE[108] = _XtimeE[108] +Sbox[109] = _Sbox[109] +InvSbox[109] = _InvSbox[109] +Xtime2Sbox[109] = _Xtime2Sbox[109] +Xtime3Sbox[109] = _Xtime3Sbox[109] +Xtime2[109] = _Xtime2[109] +Xtime9[109] = _Xtime9[109] +XtimeB[109] = _XtimeB[109] +XtimeD[109] = _XtimeD[109] +XtimeE[109] = _XtimeE[109] +Sbox[110] = _Sbox[110] +InvSbox[110] = _InvSbox[110] +Xtime2Sbox[110] = _Xtime2Sbox[110] +Xtime3Sbox[110] = _Xtime3Sbox[110] +Xtime2[110] = _Xtime2[110] +Xtime9[110] = _Xtime9[110] +XtimeB[110] = _XtimeB[110] +XtimeD[110] = _XtimeD[110] +XtimeE[110] = _XtimeE[110] +Sbox[111] = _Sbox[111] +InvSbox[111] = _InvSbox[111] +Xtime2Sbox[111] = _Xtime2Sbox[111] +Xtime3Sbox[111] = _Xtime3Sbox[111] +Xtime2[111] = _Xtime2[111] +Xtime9[111] = _Xtime9[111] +XtimeB[111] = _XtimeB[111] +XtimeD[111] = _XtimeD[111] +XtimeE[111] = _XtimeE[111] +Sbox[112] = _Sbox[112] +InvSbox[112] = _InvSbox[112] +Xtime2Sbox[112] = _Xtime2Sbox[112] +Xtime3Sbox[112] = _Xtime3Sbox[112] +Xtime2[112] = _Xtime2[112] +Xtime9[112] = _Xtime9[112] +XtimeB[112] = _XtimeB[112] +XtimeD[112] = _XtimeD[112] +XtimeE[112] = _XtimeE[112] +Sbox[113] = _Sbox[113] +InvSbox[113] = _InvSbox[113] +Xtime2Sbox[113] = _Xtime2Sbox[113] +Xtime3Sbox[113] = _Xtime3Sbox[113] +Xtime2[113] = _Xtime2[113] +Xtime9[113] = _Xtime9[113] +XtimeB[113] = _XtimeB[113] +XtimeD[113] = _XtimeD[113] +XtimeE[113] = _XtimeE[113] +Sbox[114] = _Sbox[114] +InvSbox[114] = _InvSbox[114] +Xtime2Sbox[114] = _Xtime2Sbox[114] +Xtime3Sbox[114] = _Xtime3Sbox[114] +Xtime2[114] = _Xtime2[114] +Xtime9[114] = _Xtime9[114] +XtimeB[114] = _XtimeB[114] +XtimeD[114] = _XtimeD[114] +XtimeE[114] = _XtimeE[114] +Sbox[115] = _Sbox[115] +InvSbox[115] = _InvSbox[115] +Xtime2Sbox[115] = _Xtime2Sbox[115] +Xtime3Sbox[115] = _Xtime3Sbox[115] +Xtime2[115] = _Xtime2[115] +Xtime9[115] = _Xtime9[115] +XtimeB[115] = _XtimeB[115] +XtimeD[115] = _XtimeD[115] +XtimeE[115] = _XtimeE[115] +Sbox[116] = _Sbox[116] +InvSbox[116] = _InvSbox[116] +Xtime2Sbox[116] = _Xtime2Sbox[116] +Xtime3Sbox[116] = _Xtime3Sbox[116] +Xtime2[116] = _Xtime2[116] +Xtime9[116] = _Xtime9[116] +XtimeB[116] = _XtimeB[116] +XtimeD[116] = _XtimeD[116] +XtimeE[116] = _XtimeE[116] +Sbox[117] = _Sbox[117] +InvSbox[117] = _InvSbox[117] +Xtime2Sbox[117] = _Xtime2Sbox[117] +Xtime3Sbox[117] = _Xtime3Sbox[117] +Xtime2[117] = _Xtime2[117] +Xtime9[117] = _Xtime9[117] +XtimeB[117] = _XtimeB[117] +XtimeD[117] = _XtimeD[117] +XtimeE[117] = _XtimeE[117] +Sbox[118] = _Sbox[118] +InvSbox[118] = _InvSbox[118] +Xtime2Sbox[118] = _Xtime2Sbox[118] +Xtime3Sbox[118] = _Xtime3Sbox[118] +Xtime2[118] = _Xtime2[118] +Xtime9[118] = _Xtime9[118] +XtimeB[118] = _XtimeB[118] +XtimeD[118] = _XtimeD[118] +XtimeE[118] = _XtimeE[118] +Sbox[119] = _Sbox[119] +InvSbox[119] = _InvSbox[119] +Xtime2Sbox[119] = _Xtime2Sbox[119] +Xtime3Sbox[119] = _Xtime3Sbox[119] +Xtime2[119] = _Xtime2[119] +Xtime9[119] = _Xtime9[119] +XtimeB[119] = _XtimeB[119] +XtimeD[119] = _XtimeD[119] +XtimeE[119] = _XtimeE[119] +Sbox[120] = _Sbox[120] +InvSbox[120] = _InvSbox[120] +Xtime2Sbox[120] = _Xtime2Sbox[120] +Xtime3Sbox[120] = _Xtime3Sbox[120] +Xtime2[120] = _Xtime2[120] +Xtime9[120] = _Xtime9[120] +XtimeB[120] = _XtimeB[120] +XtimeD[120] = _XtimeD[120] +XtimeE[120] = _XtimeE[120] +Sbox[121] = _Sbox[121] +InvSbox[121] = _InvSbox[121] +Xtime2Sbox[121] = _Xtime2Sbox[121] +Xtime3Sbox[121] = _Xtime3Sbox[121] +Xtime2[121] = _Xtime2[121] +Xtime9[121] = _Xtime9[121] +XtimeB[121] = _XtimeB[121] +XtimeD[121] = _XtimeD[121] +XtimeE[121] = _XtimeE[121] +Sbox[122] = _Sbox[122] +InvSbox[122] = _InvSbox[122] +Xtime2Sbox[122] = _Xtime2Sbox[122] +Xtime3Sbox[122] = _Xtime3Sbox[122] +Xtime2[122] = _Xtime2[122] +Xtime9[122] = _Xtime9[122] +XtimeB[122] = _XtimeB[122] +XtimeD[122] = _XtimeD[122] +XtimeE[122] = _XtimeE[122] +Sbox[123] = _Sbox[123] +InvSbox[123] = _InvSbox[123] +Xtime2Sbox[123] = _Xtime2Sbox[123] +Xtime3Sbox[123] = _Xtime3Sbox[123] +Xtime2[123] = _Xtime2[123] +Xtime9[123] = _Xtime9[123] +XtimeB[123] = _XtimeB[123] +XtimeD[123] = _XtimeD[123] +XtimeE[123] = _XtimeE[123] +Sbox[124] = _Sbox[124] +InvSbox[124] = _InvSbox[124] +Xtime2Sbox[124] = _Xtime2Sbox[124] +Xtime3Sbox[124] = _Xtime3Sbox[124] +Xtime2[124] = _Xtime2[124] +Xtime9[124] = _Xtime9[124] +XtimeB[124] = _XtimeB[124] +XtimeD[124] = _XtimeD[124] +XtimeE[124] = _XtimeE[124] +Sbox[125] = _Sbox[125] +InvSbox[125] = _InvSbox[125] +Xtime2Sbox[125] = _Xtime2Sbox[125] +Xtime3Sbox[125] = _Xtime3Sbox[125] +Xtime2[125] = _Xtime2[125] +Xtime9[125] = _Xtime9[125] +XtimeB[125] = _XtimeB[125] +XtimeD[125] = _XtimeD[125] +XtimeE[125] = _XtimeE[125] +Sbox[126] = _Sbox[126] +InvSbox[126] = _InvSbox[126] +Xtime2Sbox[126] = _Xtime2Sbox[126] +Xtime3Sbox[126] = _Xtime3Sbox[126] +Xtime2[126] = _Xtime2[126] +Xtime9[126] = _Xtime9[126] +XtimeB[126] = _XtimeB[126] +XtimeD[126] = _XtimeD[126] +XtimeE[126] = _XtimeE[126] +Sbox[127] = _Sbox[127] +InvSbox[127] = _InvSbox[127] +Xtime2Sbox[127] = _Xtime2Sbox[127] +Xtime3Sbox[127] = _Xtime3Sbox[127] +Xtime2[127] = _Xtime2[127] +Xtime9[127] = _Xtime9[127] +XtimeB[127] = _XtimeB[127] +XtimeD[127] = _XtimeD[127] +XtimeE[127] = _XtimeE[127] +Sbox[128] = _Sbox[128] +InvSbox[128] = _InvSbox[128] +Xtime2Sbox[128] = _Xtime2Sbox[128] +Xtime3Sbox[128] = _Xtime3Sbox[128] +Xtime2[128] = _Xtime2[128] +Xtime9[128] = _Xtime9[128] +XtimeB[128] = _XtimeB[128] +XtimeD[128] = _XtimeD[128] +XtimeE[128] = _XtimeE[128] +Sbox[129] = _Sbox[129] +InvSbox[129] = _InvSbox[129] +Xtime2Sbox[129] = _Xtime2Sbox[129] +Xtime3Sbox[129] = _Xtime3Sbox[129] +Xtime2[129] = _Xtime2[129] +Xtime9[129] = _Xtime9[129] +XtimeB[129] = _XtimeB[129] +XtimeD[129] = _XtimeD[129] +XtimeE[129] = _XtimeE[129] +Sbox[130] = _Sbox[130] +InvSbox[130] = _InvSbox[130] +Xtime2Sbox[130] = _Xtime2Sbox[130] +Xtime3Sbox[130] = _Xtime3Sbox[130] +Xtime2[130] = _Xtime2[130] +Xtime9[130] = _Xtime9[130] +XtimeB[130] = _XtimeB[130] +XtimeD[130] = _XtimeD[130] +XtimeE[130] = _XtimeE[130] +Sbox[131] = _Sbox[131] +InvSbox[131] = _InvSbox[131] +Xtime2Sbox[131] = _Xtime2Sbox[131] +Xtime3Sbox[131] = _Xtime3Sbox[131] +Xtime2[131] = _Xtime2[131] +Xtime9[131] = _Xtime9[131] +XtimeB[131] = _XtimeB[131] +XtimeD[131] = _XtimeD[131] +XtimeE[131] = _XtimeE[131] +Sbox[132] = _Sbox[132] +InvSbox[132] = _InvSbox[132] +Xtime2Sbox[132] = _Xtime2Sbox[132] +Xtime3Sbox[132] = _Xtime3Sbox[132] +Xtime2[132] = _Xtime2[132] +Xtime9[132] = _Xtime9[132] +XtimeB[132] = _XtimeB[132] +XtimeD[132] = _XtimeD[132] +XtimeE[132] = _XtimeE[132] +Sbox[133] = _Sbox[133] +InvSbox[133] = _InvSbox[133] +Xtime2Sbox[133] = _Xtime2Sbox[133] +Xtime3Sbox[133] = _Xtime3Sbox[133] +Xtime2[133] = _Xtime2[133] +Xtime9[133] = _Xtime9[133] +XtimeB[133] = _XtimeB[133] +XtimeD[133] = _XtimeD[133] +XtimeE[133] = _XtimeE[133] +Sbox[134] = _Sbox[134] +InvSbox[134] = _InvSbox[134] +Xtime2Sbox[134] = _Xtime2Sbox[134] +Xtime3Sbox[134] = _Xtime3Sbox[134] +Xtime2[134] = _Xtime2[134] +Xtime9[134] = _Xtime9[134] +XtimeB[134] = _XtimeB[134] +XtimeD[134] = _XtimeD[134] +XtimeE[134] = _XtimeE[134] +Sbox[135] = _Sbox[135] +InvSbox[135] = _InvSbox[135] +Xtime2Sbox[135] = _Xtime2Sbox[135] +Xtime3Sbox[135] = _Xtime3Sbox[135] +Xtime2[135] = _Xtime2[135] +Xtime9[135] = _Xtime9[135] +XtimeB[135] = _XtimeB[135] +XtimeD[135] = _XtimeD[135] +XtimeE[135] = _XtimeE[135] +Sbox[136] = _Sbox[136] +InvSbox[136] = _InvSbox[136] +Xtime2Sbox[136] = _Xtime2Sbox[136] +Xtime3Sbox[136] = _Xtime3Sbox[136] +Xtime2[136] = _Xtime2[136] +Xtime9[136] = _Xtime9[136] +XtimeB[136] = _XtimeB[136] +XtimeD[136] = _XtimeD[136] +XtimeE[136] = _XtimeE[136] +Sbox[137] = _Sbox[137] +InvSbox[137] = _InvSbox[137] +Xtime2Sbox[137] = _Xtime2Sbox[137] +Xtime3Sbox[137] = _Xtime3Sbox[137] +Xtime2[137] = _Xtime2[137] +Xtime9[137] = _Xtime9[137] +XtimeB[137] = _XtimeB[137] +XtimeD[137] = _XtimeD[137] +XtimeE[137] = _XtimeE[137] +Sbox[138] = _Sbox[138] +InvSbox[138] = _InvSbox[138] +Xtime2Sbox[138] = _Xtime2Sbox[138] +Xtime3Sbox[138] = _Xtime3Sbox[138] +Xtime2[138] = _Xtime2[138] +Xtime9[138] = _Xtime9[138] +XtimeB[138] = _XtimeB[138] +XtimeD[138] = _XtimeD[138] +XtimeE[138] = _XtimeE[138] +Sbox[139] = _Sbox[139] +InvSbox[139] = _InvSbox[139] +Xtime2Sbox[139] = _Xtime2Sbox[139] +Xtime3Sbox[139] = _Xtime3Sbox[139] +Xtime2[139] = _Xtime2[139] +Xtime9[139] = _Xtime9[139] +XtimeB[139] = _XtimeB[139] +XtimeD[139] = _XtimeD[139] +XtimeE[139] = _XtimeE[139] +Sbox[140] = _Sbox[140] +InvSbox[140] = _InvSbox[140] +Xtime2Sbox[140] = _Xtime2Sbox[140] +Xtime3Sbox[140] = _Xtime3Sbox[140] +Xtime2[140] = _Xtime2[140] +Xtime9[140] = _Xtime9[140] +XtimeB[140] = _XtimeB[140] +XtimeD[140] = _XtimeD[140] +XtimeE[140] = _XtimeE[140] +Sbox[141] = _Sbox[141] +InvSbox[141] = _InvSbox[141] +Xtime2Sbox[141] = _Xtime2Sbox[141] +Xtime3Sbox[141] = _Xtime3Sbox[141] +Xtime2[141] = _Xtime2[141] +Xtime9[141] = _Xtime9[141] +XtimeB[141] = _XtimeB[141] +XtimeD[141] = _XtimeD[141] +XtimeE[141] = _XtimeE[141] +Sbox[142] = _Sbox[142] +InvSbox[142] = _InvSbox[142] +Xtime2Sbox[142] = _Xtime2Sbox[142] +Xtime3Sbox[142] = _Xtime3Sbox[142] +Xtime2[142] = _Xtime2[142] +Xtime9[142] = _Xtime9[142] +XtimeB[142] = _XtimeB[142] +XtimeD[142] = _XtimeD[142] +XtimeE[142] = _XtimeE[142] +Sbox[143] = _Sbox[143] +InvSbox[143] = _InvSbox[143] +Xtime2Sbox[143] = _Xtime2Sbox[143] +Xtime3Sbox[143] = _Xtime3Sbox[143] +Xtime2[143] = _Xtime2[143] +Xtime9[143] = _Xtime9[143] +XtimeB[143] = _XtimeB[143] +XtimeD[143] = _XtimeD[143] +XtimeE[143] = _XtimeE[143] +Sbox[144] = _Sbox[144] +InvSbox[144] = _InvSbox[144] +Xtime2Sbox[144] = _Xtime2Sbox[144] +Xtime3Sbox[144] = _Xtime3Sbox[144] +Xtime2[144] = _Xtime2[144] +Xtime9[144] = _Xtime9[144] +XtimeB[144] = _XtimeB[144] +XtimeD[144] = _XtimeD[144] +XtimeE[144] = _XtimeE[144] +Sbox[145] = _Sbox[145] +InvSbox[145] = _InvSbox[145] +Xtime2Sbox[145] = _Xtime2Sbox[145] +Xtime3Sbox[145] = _Xtime3Sbox[145] +Xtime2[145] = _Xtime2[145] +Xtime9[145] = _Xtime9[145] +XtimeB[145] = _XtimeB[145] +XtimeD[145] = _XtimeD[145] +XtimeE[145] = _XtimeE[145] +Sbox[146] = _Sbox[146] +InvSbox[146] = _InvSbox[146] +Xtime2Sbox[146] = _Xtime2Sbox[146] +Xtime3Sbox[146] = _Xtime3Sbox[146] +Xtime2[146] = _Xtime2[146] +Xtime9[146] = _Xtime9[146] +XtimeB[146] = _XtimeB[146] +XtimeD[146] = _XtimeD[146] +XtimeE[146] = _XtimeE[146] +Sbox[147] = _Sbox[147] +InvSbox[147] = _InvSbox[147] +Xtime2Sbox[147] = _Xtime2Sbox[147] +Xtime3Sbox[147] = _Xtime3Sbox[147] +Xtime2[147] = _Xtime2[147] +Xtime9[147] = _Xtime9[147] +XtimeB[147] = _XtimeB[147] +XtimeD[147] = _XtimeD[147] +XtimeE[147] = _XtimeE[147] +Sbox[148] = _Sbox[148] +InvSbox[148] = _InvSbox[148] +Xtime2Sbox[148] = _Xtime2Sbox[148] +Xtime3Sbox[148] = _Xtime3Sbox[148] +Xtime2[148] = _Xtime2[148] +Xtime9[148] = _Xtime9[148] +XtimeB[148] = _XtimeB[148] +XtimeD[148] = _XtimeD[148] +XtimeE[148] = _XtimeE[148] +Sbox[149] = _Sbox[149] +InvSbox[149] = _InvSbox[149] +Xtime2Sbox[149] = _Xtime2Sbox[149] +Xtime3Sbox[149] = _Xtime3Sbox[149] +Xtime2[149] = _Xtime2[149] +Xtime9[149] = _Xtime9[149] +XtimeB[149] = _XtimeB[149] +XtimeD[149] = _XtimeD[149] +XtimeE[149] = _XtimeE[149] +Sbox[150] = _Sbox[150] +InvSbox[150] = _InvSbox[150] +Xtime2Sbox[150] = _Xtime2Sbox[150] +Xtime3Sbox[150] = _Xtime3Sbox[150] +Xtime2[150] = _Xtime2[150] +Xtime9[150] = _Xtime9[150] +XtimeB[150] = _XtimeB[150] +XtimeD[150] = _XtimeD[150] +XtimeE[150] = _XtimeE[150] +Sbox[151] = _Sbox[151] +InvSbox[151] = _InvSbox[151] +Xtime2Sbox[151] = _Xtime2Sbox[151] +Xtime3Sbox[151] = _Xtime3Sbox[151] +Xtime2[151] = _Xtime2[151] +Xtime9[151] = _Xtime9[151] +XtimeB[151] = _XtimeB[151] +XtimeD[151] = _XtimeD[151] +XtimeE[151] = _XtimeE[151] +Sbox[152] = _Sbox[152] +InvSbox[152] = _InvSbox[152] +Xtime2Sbox[152] = _Xtime2Sbox[152] +Xtime3Sbox[152] = _Xtime3Sbox[152] +Xtime2[152] = _Xtime2[152] +Xtime9[152] = _Xtime9[152] +XtimeB[152] = _XtimeB[152] +XtimeD[152] = _XtimeD[152] +XtimeE[152] = _XtimeE[152] +Sbox[153] = _Sbox[153] +InvSbox[153] = _InvSbox[153] +Xtime2Sbox[153] = _Xtime2Sbox[153] +Xtime3Sbox[153] = _Xtime3Sbox[153] +Xtime2[153] = _Xtime2[153] +Xtime9[153] = _Xtime9[153] +XtimeB[153] = _XtimeB[153] +XtimeD[153] = _XtimeD[153] +XtimeE[153] = _XtimeE[153] +Sbox[154] = _Sbox[154] +InvSbox[154] = _InvSbox[154] +Xtime2Sbox[154] = _Xtime2Sbox[154] +Xtime3Sbox[154] = _Xtime3Sbox[154] +Xtime2[154] = _Xtime2[154] +Xtime9[154] = _Xtime9[154] +XtimeB[154] = _XtimeB[154] +XtimeD[154] = _XtimeD[154] +XtimeE[154] = _XtimeE[154] +Sbox[155] = _Sbox[155] +InvSbox[155] = _InvSbox[155] +Xtime2Sbox[155] = _Xtime2Sbox[155] +Xtime3Sbox[155] = _Xtime3Sbox[155] +Xtime2[155] = _Xtime2[155] +Xtime9[155] = _Xtime9[155] +XtimeB[155] = _XtimeB[155] +XtimeD[155] = _XtimeD[155] +XtimeE[155] = _XtimeE[155] +Sbox[156] = _Sbox[156] +InvSbox[156] = _InvSbox[156] +Xtime2Sbox[156] = _Xtime2Sbox[156] +Xtime3Sbox[156] = _Xtime3Sbox[156] +Xtime2[156] = _Xtime2[156] +Xtime9[156] = _Xtime9[156] +XtimeB[156] = _XtimeB[156] +XtimeD[156] = _XtimeD[156] +XtimeE[156] = _XtimeE[156] +Sbox[157] = _Sbox[157] +InvSbox[157] = _InvSbox[157] +Xtime2Sbox[157] = _Xtime2Sbox[157] +Xtime3Sbox[157] = _Xtime3Sbox[157] +Xtime2[157] = _Xtime2[157] +Xtime9[157] = _Xtime9[157] +XtimeB[157] = _XtimeB[157] +XtimeD[157] = _XtimeD[157] +XtimeE[157] = _XtimeE[157] +Sbox[158] = _Sbox[158] +InvSbox[158] = _InvSbox[158] +Xtime2Sbox[158] = _Xtime2Sbox[158] +Xtime3Sbox[158] = _Xtime3Sbox[158] +Xtime2[158] = _Xtime2[158] +Xtime9[158] = _Xtime9[158] +XtimeB[158] = _XtimeB[158] +XtimeD[158] = _XtimeD[158] +XtimeE[158] = _XtimeE[158] +Sbox[159] = _Sbox[159] +InvSbox[159] = _InvSbox[159] +Xtime2Sbox[159] = _Xtime2Sbox[159] +Xtime3Sbox[159] = _Xtime3Sbox[159] +Xtime2[159] = _Xtime2[159] +Xtime9[159] = _Xtime9[159] +XtimeB[159] = _XtimeB[159] +XtimeD[159] = _XtimeD[159] +XtimeE[159] = _XtimeE[159] +Sbox[160] = _Sbox[160] +InvSbox[160] = _InvSbox[160] +Xtime2Sbox[160] = _Xtime2Sbox[160] +Xtime3Sbox[160] = _Xtime3Sbox[160] +Xtime2[160] = _Xtime2[160] +Xtime9[160] = _Xtime9[160] +XtimeB[160] = _XtimeB[160] +XtimeD[160] = _XtimeD[160] +XtimeE[160] = _XtimeE[160] +Sbox[161] = _Sbox[161] +InvSbox[161] = _InvSbox[161] +Xtime2Sbox[161] = _Xtime2Sbox[161] +Xtime3Sbox[161] = _Xtime3Sbox[161] +Xtime2[161] = _Xtime2[161] +Xtime9[161] = _Xtime9[161] +XtimeB[161] = _XtimeB[161] +XtimeD[161] = _XtimeD[161] +XtimeE[161] = _XtimeE[161] +Sbox[162] = _Sbox[162] +InvSbox[162] = _InvSbox[162] +Xtime2Sbox[162] = _Xtime2Sbox[162] +Xtime3Sbox[162] = _Xtime3Sbox[162] +Xtime2[162] = _Xtime2[162] +Xtime9[162] = _Xtime9[162] +XtimeB[162] = _XtimeB[162] +XtimeD[162] = _XtimeD[162] +XtimeE[162] = _XtimeE[162] +Sbox[163] = _Sbox[163] +InvSbox[163] = _InvSbox[163] +Xtime2Sbox[163] = _Xtime2Sbox[163] +Xtime3Sbox[163] = _Xtime3Sbox[163] +Xtime2[163] = _Xtime2[163] +Xtime9[163] = _Xtime9[163] +XtimeB[163] = _XtimeB[163] +XtimeD[163] = _XtimeD[163] +XtimeE[163] = _XtimeE[163] +Sbox[164] = _Sbox[164] +InvSbox[164] = _InvSbox[164] +Xtime2Sbox[164] = _Xtime2Sbox[164] +Xtime3Sbox[164] = _Xtime3Sbox[164] +Xtime2[164] = _Xtime2[164] +Xtime9[164] = _Xtime9[164] +XtimeB[164] = _XtimeB[164] +XtimeD[164] = _XtimeD[164] +XtimeE[164] = _XtimeE[164] +Sbox[165] = _Sbox[165] +InvSbox[165] = _InvSbox[165] +Xtime2Sbox[165] = _Xtime2Sbox[165] +Xtime3Sbox[165] = _Xtime3Sbox[165] +Xtime2[165] = _Xtime2[165] +Xtime9[165] = _Xtime9[165] +XtimeB[165] = _XtimeB[165] +XtimeD[165] = _XtimeD[165] +XtimeE[165] = _XtimeE[165] +Sbox[166] = _Sbox[166] +InvSbox[166] = _InvSbox[166] +Xtime2Sbox[166] = _Xtime2Sbox[166] +Xtime3Sbox[166] = _Xtime3Sbox[166] +Xtime2[166] = _Xtime2[166] +Xtime9[166] = _Xtime9[166] +XtimeB[166] = _XtimeB[166] +XtimeD[166] = _XtimeD[166] +XtimeE[166] = _XtimeE[166] +Sbox[167] = _Sbox[167] +InvSbox[167] = _InvSbox[167] +Xtime2Sbox[167] = _Xtime2Sbox[167] +Xtime3Sbox[167] = _Xtime3Sbox[167] +Xtime2[167] = _Xtime2[167] +Xtime9[167] = _Xtime9[167] +XtimeB[167] = _XtimeB[167] +XtimeD[167] = _XtimeD[167] +XtimeE[167] = _XtimeE[167] +Sbox[168] = _Sbox[168] +InvSbox[168] = _InvSbox[168] +Xtime2Sbox[168] = _Xtime2Sbox[168] +Xtime3Sbox[168] = _Xtime3Sbox[168] +Xtime2[168] = _Xtime2[168] +Xtime9[168] = _Xtime9[168] +XtimeB[168] = _XtimeB[168] +XtimeD[168] = _XtimeD[168] +XtimeE[168] = _XtimeE[168] +Sbox[169] = _Sbox[169] +InvSbox[169] = _InvSbox[169] +Xtime2Sbox[169] = _Xtime2Sbox[169] +Xtime3Sbox[169] = _Xtime3Sbox[169] +Xtime2[169] = _Xtime2[169] +Xtime9[169] = _Xtime9[169] +XtimeB[169] = _XtimeB[169] +XtimeD[169] = _XtimeD[169] +XtimeE[169] = _XtimeE[169] +Sbox[170] = _Sbox[170] +InvSbox[170] = _InvSbox[170] +Xtime2Sbox[170] = _Xtime2Sbox[170] +Xtime3Sbox[170] = _Xtime3Sbox[170] +Xtime2[170] = _Xtime2[170] +Xtime9[170] = _Xtime9[170] +XtimeB[170] = _XtimeB[170] +XtimeD[170] = _XtimeD[170] +XtimeE[170] = _XtimeE[170] +Sbox[171] = _Sbox[171] +InvSbox[171] = _InvSbox[171] +Xtime2Sbox[171] = _Xtime2Sbox[171] +Xtime3Sbox[171] = _Xtime3Sbox[171] +Xtime2[171] = _Xtime2[171] +Xtime9[171] = _Xtime9[171] +XtimeB[171] = _XtimeB[171] +XtimeD[171] = _XtimeD[171] +XtimeE[171] = _XtimeE[171] +Sbox[172] = _Sbox[172] +InvSbox[172] = _InvSbox[172] +Xtime2Sbox[172] = _Xtime2Sbox[172] +Xtime3Sbox[172] = _Xtime3Sbox[172] +Xtime2[172] = _Xtime2[172] +Xtime9[172] = _Xtime9[172] +XtimeB[172] = _XtimeB[172] +XtimeD[172] = _XtimeD[172] +XtimeE[172] = _XtimeE[172] +Sbox[173] = _Sbox[173] +InvSbox[173] = _InvSbox[173] +Xtime2Sbox[173] = _Xtime2Sbox[173] +Xtime3Sbox[173] = _Xtime3Sbox[173] +Xtime2[173] = _Xtime2[173] +Xtime9[173] = _Xtime9[173] +XtimeB[173] = _XtimeB[173] +XtimeD[173] = _XtimeD[173] +XtimeE[173] = _XtimeE[173] +Sbox[174] = _Sbox[174] +InvSbox[174] = _InvSbox[174] +Xtime2Sbox[174] = _Xtime2Sbox[174] +Xtime3Sbox[174] = _Xtime3Sbox[174] +Xtime2[174] = _Xtime2[174] +Xtime9[174] = _Xtime9[174] +XtimeB[174] = _XtimeB[174] +XtimeD[174] = _XtimeD[174] +XtimeE[174] = _XtimeE[174] +Sbox[175] = _Sbox[175] +InvSbox[175] = _InvSbox[175] +Xtime2Sbox[175] = _Xtime2Sbox[175] +Xtime3Sbox[175] = _Xtime3Sbox[175] +Xtime2[175] = _Xtime2[175] +Xtime9[175] = _Xtime9[175] +XtimeB[175] = _XtimeB[175] +XtimeD[175] = _XtimeD[175] +XtimeE[175] = _XtimeE[175] +Sbox[176] = _Sbox[176] +InvSbox[176] = _InvSbox[176] +Xtime2Sbox[176] = _Xtime2Sbox[176] +Xtime3Sbox[176] = _Xtime3Sbox[176] +Xtime2[176] = _Xtime2[176] +Xtime9[176] = _Xtime9[176] +XtimeB[176] = _XtimeB[176] +XtimeD[176] = _XtimeD[176] +XtimeE[176] = _XtimeE[176] +Sbox[177] = _Sbox[177] +InvSbox[177] = _InvSbox[177] +Xtime2Sbox[177] = _Xtime2Sbox[177] +Xtime3Sbox[177] = _Xtime3Sbox[177] +Xtime2[177] = _Xtime2[177] +Xtime9[177] = _Xtime9[177] +XtimeB[177] = _XtimeB[177] +XtimeD[177] = _XtimeD[177] +XtimeE[177] = _XtimeE[177] +Sbox[178] = _Sbox[178] +InvSbox[178] = _InvSbox[178] +Xtime2Sbox[178] = _Xtime2Sbox[178] +Xtime3Sbox[178] = _Xtime3Sbox[178] +Xtime2[178] = _Xtime2[178] +Xtime9[178] = _Xtime9[178] +XtimeB[178] = _XtimeB[178] +XtimeD[178] = _XtimeD[178] +XtimeE[178] = _XtimeE[178] +Sbox[179] = _Sbox[179] +InvSbox[179] = _InvSbox[179] +Xtime2Sbox[179] = _Xtime2Sbox[179] +Xtime3Sbox[179] = _Xtime3Sbox[179] +Xtime2[179] = _Xtime2[179] +Xtime9[179] = _Xtime9[179] +XtimeB[179] = _XtimeB[179] +XtimeD[179] = _XtimeD[179] +XtimeE[179] = _XtimeE[179] +Sbox[180] = _Sbox[180] +InvSbox[180] = _InvSbox[180] +Xtime2Sbox[180] = _Xtime2Sbox[180] +Xtime3Sbox[180] = _Xtime3Sbox[180] +Xtime2[180] = _Xtime2[180] +Xtime9[180] = _Xtime9[180] +XtimeB[180] = _XtimeB[180] +XtimeD[180] = _XtimeD[180] +XtimeE[180] = _XtimeE[180] +Sbox[181] = _Sbox[181] +InvSbox[181] = _InvSbox[181] +Xtime2Sbox[181] = _Xtime2Sbox[181] +Xtime3Sbox[181] = _Xtime3Sbox[181] +Xtime2[181] = _Xtime2[181] +Xtime9[181] = _Xtime9[181] +XtimeB[181] = _XtimeB[181] +XtimeD[181] = _XtimeD[181] +XtimeE[181] = _XtimeE[181] +Sbox[182] = _Sbox[182] +InvSbox[182] = _InvSbox[182] +Xtime2Sbox[182] = _Xtime2Sbox[182] +Xtime3Sbox[182] = _Xtime3Sbox[182] +Xtime2[182] = _Xtime2[182] +Xtime9[182] = _Xtime9[182] +XtimeB[182] = _XtimeB[182] +XtimeD[182] = _XtimeD[182] +XtimeE[182] = _XtimeE[182] +Sbox[183] = _Sbox[183] +InvSbox[183] = _InvSbox[183] +Xtime2Sbox[183] = _Xtime2Sbox[183] +Xtime3Sbox[183] = _Xtime3Sbox[183] +Xtime2[183] = _Xtime2[183] +Xtime9[183] = _Xtime9[183] +XtimeB[183] = _XtimeB[183] +XtimeD[183] = _XtimeD[183] +XtimeE[183] = _XtimeE[183] +Sbox[184] = _Sbox[184] +InvSbox[184] = _InvSbox[184] +Xtime2Sbox[184] = _Xtime2Sbox[184] +Xtime3Sbox[184] = _Xtime3Sbox[184] +Xtime2[184] = _Xtime2[184] +Xtime9[184] = _Xtime9[184] +XtimeB[184] = _XtimeB[184] +XtimeD[184] = _XtimeD[184] +XtimeE[184] = _XtimeE[184] +Sbox[185] = _Sbox[185] +InvSbox[185] = _InvSbox[185] +Xtime2Sbox[185] = _Xtime2Sbox[185] +Xtime3Sbox[185] = _Xtime3Sbox[185] +Xtime2[185] = _Xtime2[185] +Xtime9[185] = _Xtime9[185] +XtimeB[185] = _XtimeB[185] +XtimeD[185] = _XtimeD[185] +XtimeE[185] = _XtimeE[185] +Sbox[186] = _Sbox[186] +InvSbox[186] = _InvSbox[186] +Xtime2Sbox[186] = _Xtime2Sbox[186] +Xtime3Sbox[186] = _Xtime3Sbox[186] +Xtime2[186] = _Xtime2[186] +Xtime9[186] = _Xtime9[186] +XtimeB[186] = _XtimeB[186] +XtimeD[186] = _XtimeD[186] +XtimeE[186] = _XtimeE[186] +Sbox[187] = _Sbox[187] +InvSbox[187] = _InvSbox[187] +Xtime2Sbox[187] = _Xtime2Sbox[187] +Xtime3Sbox[187] = _Xtime3Sbox[187] +Xtime2[187] = _Xtime2[187] +Xtime9[187] = _Xtime9[187] +XtimeB[187] = _XtimeB[187] +XtimeD[187] = _XtimeD[187] +XtimeE[187] = _XtimeE[187] +Sbox[188] = _Sbox[188] +InvSbox[188] = _InvSbox[188] +Xtime2Sbox[188] = _Xtime2Sbox[188] +Xtime3Sbox[188] = _Xtime3Sbox[188] +Xtime2[188] = _Xtime2[188] +Xtime9[188] = _Xtime9[188] +XtimeB[188] = _XtimeB[188] +XtimeD[188] = _XtimeD[188] +XtimeE[188] = _XtimeE[188] +Sbox[189] = _Sbox[189] +InvSbox[189] = _InvSbox[189] +Xtime2Sbox[189] = _Xtime2Sbox[189] +Xtime3Sbox[189] = _Xtime3Sbox[189] +Xtime2[189] = _Xtime2[189] +Xtime9[189] = _Xtime9[189] +XtimeB[189] = _XtimeB[189] +XtimeD[189] = _XtimeD[189] +XtimeE[189] = _XtimeE[189] +Sbox[190] = _Sbox[190] +InvSbox[190] = _InvSbox[190] +Xtime2Sbox[190] = _Xtime2Sbox[190] +Xtime3Sbox[190] = _Xtime3Sbox[190] +Xtime2[190] = _Xtime2[190] +Xtime9[190] = _Xtime9[190] +XtimeB[190] = _XtimeB[190] +XtimeD[190] = _XtimeD[190] +XtimeE[190] = _XtimeE[190] +Sbox[191] = _Sbox[191] +InvSbox[191] = _InvSbox[191] +Xtime2Sbox[191] = _Xtime2Sbox[191] +Xtime3Sbox[191] = _Xtime3Sbox[191] +Xtime2[191] = _Xtime2[191] +Xtime9[191] = _Xtime9[191] +XtimeB[191] = _XtimeB[191] +XtimeD[191] = _XtimeD[191] +XtimeE[191] = _XtimeE[191] +Sbox[192] = _Sbox[192] +InvSbox[192] = _InvSbox[192] +Xtime2Sbox[192] = _Xtime2Sbox[192] +Xtime3Sbox[192] = _Xtime3Sbox[192] +Xtime2[192] = _Xtime2[192] +Xtime9[192] = _Xtime9[192] +XtimeB[192] = _XtimeB[192] +XtimeD[192] = _XtimeD[192] +XtimeE[192] = _XtimeE[192] +Sbox[193] = _Sbox[193] +InvSbox[193] = _InvSbox[193] +Xtime2Sbox[193] = _Xtime2Sbox[193] +Xtime3Sbox[193] = _Xtime3Sbox[193] +Xtime2[193] = _Xtime2[193] +Xtime9[193] = _Xtime9[193] +XtimeB[193] = _XtimeB[193] +XtimeD[193] = _XtimeD[193] +XtimeE[193] = _XtimeE[193] +Sbox[194] = _Sbox[194] +InvSbox[194] = _InvSbox[194] +Xtime2Sbox[194] = _Xtime2Sbox[194] +Xtime3Sbox[194] = _Xtime3Sbox[194] +Xtime2[194] = _Xtime2[194] +Xtime9[194] = _Xtime9[194] +XtimeB[194] = _XtimeB[194] +XtimeD[194] = _XtimeD[194] +XtimeE[194] = _XtimeE[194] +Sbox[195] = _Sbox[195] +InvSbox[195] = _InvSbox[195] +Xtime2Sbox[195] = _Xtime2Sbox[195] +Xtime3Sbox[195] = _Xtime3Sbox[195] +Xtime2[195] = _Xtime2[195] +Xtime9[195] = _Xtime9[195] +XtimeB[195] = _XtimeB[195] +XtimeD[195] = _XtimeD[195] +XtimeE[195] = _XtimeE[195] +Sbox[196] = _Sbox[196] +InvSbox[196] = _InvSbox[196] +Xtime2Sbox[196] = _Xtime2Sbox[196] +Xtime3Sbox[196] = _Xtime3Sbox[196] +Xtime2[196] = _Xtime2[196] +Xtime9[196] = _Xtime9[196] +XtimeB[196] = _XtimeB[196] +XtimeD[196] = _XtimeD[196] +XtimeE[196] = _XtimeE[196] +Sbox[197] = _Sbox[197] +InvSbox[197] = _InvSbox[197] +Xtime2Sbox[197] = _Xtime2Sbox[197] +Xtime3Sbox[197] = _Xtime3Sbox[197] +Xtime2[197] = _Xtime2[197] +Xtime9[197] = _Xtime9[197] +XtimeB[197] = _XtimeB[197] +XtimeD[197] = _XtimeD[197] +XtimeE[197] = _XtimeE[197] +Sbox[198] = _Sbox[198] +InvSbox[198] = _InvSbox[198] +Xtime2Sbox[198] = _Xtime2Sbox[198] +Xtime3Sbox[198] = _Xtime3Sbox[198] +Xtime2[198] = _Xtime2[198] +Xtime9[198] = _Xtime9[198] +XtimeB[198] = _XtimeB[198] +XtimeD[198] = _XtimeD[198] +XtimeE[198] = _XtimeE[198] +Sbox[199] = _Sbox[199] +InvSbox[199] = _InvSbox[199] +Xtime2Sbox[199] = _Xtime2Sbox[199] +Xtime3Sbox[199] = _Xtime3Sbox[199] +Xtime2[199] = _Xtime2[199] +Xtime9[199] = _Xtime9[199] +XtimeB[199] = _XtimeB[199] +XtimeD[199] = _XtimeD[199] +XtimeE[199] = _XtimeE[199] +Sbox[200] = _Sbox[200] +InvSbox[200] = _InvSbox[200] +Xtime2Sbox[200] = _Xtime2Sbox[200] +Xtime3Sbox[200] = _Xtime3Sbox[200] +Xtime2[200] = _Xtime2[200] +Xtime9[200] = _Xtime9[200] +XtimeB[200] = _XtimeB[200] +XtimeD[200] = _XtimeD[200] +XtimeE[200] = _XtimeE[200] +Sbox[201] = _Sbox[201] +InvSbox[201] = _InvSbox[201] +Xtime2Sbox[201] = _Xtime2Sbox[201] +Xtime3Sbox[201] = _Xtime3Sbox[201] +Xtime2[201] = _Xtime2[201] +Xtime9[201] = _Xtime9[201] +XtimeB[201] = _XtimeB[201] +XtimeD[201] = _XtimeD[201] +XtimeE[201] = _XtimeE[201] +Sbox[202] = _Sbox[202] +InvSbox[202] = _InvSbox[202] +Xtime2Sbox[202] = _Xtime2Sbox[202] +Xtime3Sbox[202] = _Xtime3Sbox[202] +Xtime2[202] = _Xtime2[202] +Xtime9[202] = _Xtime9[202] +XtimeB[202] = _XtimeB[202] +XtimeD[202] = _XtimeD[202] +XtimeE[202] = _XtimeE[202] +Sbox[203] = _Sbox[203] +InvSbox[203] = _InvSbox[203] +Xtime2Sbox[203] = _Xtime2Sbox[203] +Xtime3Sbox[203] = _Xtime3Sbox[203] +Xtime2[203] = _Xtime2[203] +Xtime9[203] = _Xtime9[203] +XtimeB[203] = _XtimeB[203] +XtimeD[203] = _XtimeD[203] +XtimeE[203] = _XtimeE[203] +Sbox[204] = _Sbox[204] +InvSbox[204] = _InvSbox[204] +Xtime2Sbox[204] = _Xtime2Sbox[204] +Xtime3Sbox[204] = _Xtime3Sbox[204] +Xtime2[204] = _Xtime2[204] +Xtime9[204] = _Xtime9[204] +XtimeB[204] = _XtimeB[204] +XtimeD[204] = _XtimeD[204] +XtimeE[204] = _XtimeE[204] +Sbox[205] = _Sbox[205] +InvSbox[205] = _InvSbox[205] +Xtime2Sbox[205] = _Xtime2Sbox[205] +Xtime3Sbox[205] = _Xtime3Sbox[205] +Xtime2[205] = _Xtime2[205] +Xtime9[205] = _Xtime9[205] +XtimeB[205] = _XtimeB[205] +XtimeD[205] = _XtimeD[205] +XtimeE[205] = _XtimeE[205] +Sbox[206] = _Sbox[206] +InvSbox[206] = _InvSbox[206] +Xtime2Sbox[206] = _Xtime2Sbox[206] +Xtime3Sbox[206] = _Xtime3Sbox[206] +Xtime2[206] = _Xtime2[206] +Xtime9[206] = _Xtime9[206] +XtimeB[206] = _XtimeB[206] +XtimeD[206] = _XtimeD[206] +XtimeE[206] = _XtimeE[206] +Sbox[207] = _Sbox[207] +InvSbox[207] = _InvSbox[207] +Xtime2Sbox[207] = _Xtime2Sbox[207] +Xtime3Sbox[207] = _Xtime3Sbox[207] +Xtime2[207] = _Xtime2[207] +Xtime9[207] = _Xtime9[207] +XtimeB[207] = _XtimeB[207] +XtimeD[207] = _XtimeD[207] +XtimeE[207] = _XtimeE[207] +Sbox[208] = _Sbox[208] +InvSbox[208] = _InvSbox[208] +Xtime2Sbox[208] = _Xtime2Sbox[208] +Xtime3Sbox[208] = _Xtime3Sbox[208] +Xtime2[208] = _Xtime2[208] +Xtime9[208] = _Xtime9[208] +XtimeB[208] = _XtimeB[208] +XtimeD[208] = _XtimeD[208] +XtimeE[208] = _XtimeE[208] +Sbox[209] = _Sbox[209] +InvSbox[209] = _InvSbox[209] +Xtime2Sbox[209] = _Xtime2Sbox[209] +Xtime3Sbox[209] = _Xtime3Sbox[209] +Xtime2[209] = _Xtime2[209] +Xtime9[209] = _Xtime9[209] +XtimeB[209] = _XtimeB[209] +XtimeD[209] = _XtimeD[209] +XtimeE[209] = _XtimeE[209] +Sbox[210] = _Sbox[210] +InvSbox[210] = _InvSbox[210] +Xtime2Sbox[210] = _Xtime2Sbox[210] +Xtime3Sbox[210] = _Xtime3Sbox[210] +Xtime2[210] = _Xtime2[210] +Xtime9[210] = _Xtime9[210] +XtimeB[210] = _XtimeB[210] +XtimeD[210] = _XtimeD[210] +XtimeE[210] = _XtimeE[210] +Sbox[211] = _Sbox[211] +InvSbox[211] = _InvSbox[211] +Xtime2Sbox[211] = _Xtime2Sbox[211] +Xtime3Sbox[211] = _Xtime3Sbox[211] +Xtime2[211] = _Xtime2[211] +Xtime9[211] = _Xtime9[211] +XtimeB[211] = _XtimeB[211] +XtimeD[211] = _XtimeD[211] +XtimeE[211] = _XtimeE[211] +Sbox[212] = _Sbox[212] +InvSbox[212] = _InvSbox[212] +Xtime2Sbox[212] = _Xtime2Sbox[212] +Xtime3Sbox[212] = _Xtime3Sbox[212] +Xtime2[212] = _Xtime2[212] +Xtime9[212] = _Xtime9[212] +XtimeB[212] = _XtimeB[212] +XtimeD[212] = _XtimeD[212] +XtimeE[212] = _XtimeE[212] +Sbox[213] = _Sbox[213] +InvSbox[213] = _InvSbox[213] +Xtime2Sbox[213] = _Xtime2Sbox[213] +Xtime3Sbox[213] = _Xtime3Sbox[213] +Xtime2[213] = _Xtime2[213] +Xtime9[213] = _Xtime9[213] +XtimeB[213] = _XtimeB[213] +XtimeD[213] = _XtimeD[213] +XtimeE[213] = _XtimeE[213] +Sbox[214] = _Sbox[214] +InvSbox[214] = _InvSbox[214] +Xtime2Sbox[214] = _Xtime2Sbox[214] +Xtime3Sbox[214] = _Xtime3Sbox[214] +Xtime2[214] = _Xtime2[214] +Xtime9[214] = _Xtime9[214] +XtimeB[214] = _XtimeB[214] +XtimeD[214] = _XtimeD[214] +XtimeE[214] = _XtimeE[214] +Sbox[215] = _Sbox[215] +InvSbox[215] = _InvSbox[215] +Xtime2Sbox[215] = _Xtime2Sbox[215] +Xtime3Sbox[215] = _Xtime3Sbox[215] +Xtime2[215] = _Xtime2[215] +Xtime9[215] = _Xtime9[215] +XtimeB[215] = _XtimeB[215] +XtimeD[215] = _XtimeD[215] +XtimeE[215] = _XtimeE[215] +Sbox[216] = _Sbox[216] +InvSbox[216] = _InvSbox[216] +Xtime2Sbox[216] = _Xtime2Sbox[216] +Xtime3Sbox[216] = _Xtime3Sbox[216] +Xtime2[216] = _Xtime2[216] +Xtime9[216] = _Xtime9[216] +XtimeB[216] = _XtimeB[216] +XtimeD[216] = _XtimeD[216] +XtimeE[216] = _XtimeE[216] +Sbox[217] = _Sbox[217] +InvSbox[217] = _InvSbox[217] +Xtime2Sbox[217] = _Xtime2Sbox[217] +Xtime3Sbox[217] = _Xtime3Sbox[217] +Xtime2[217] = _Xtime2[217] +Xtime9[217] = _Xtime9[217] +XtimeB[217] = _XtimeB[217] +XtimeD[217] = _XtimeD[217] +XtimeE[217] = _XtimeE[217] +Sbox[218] = _Sbox[218] +InvSbox[218] = _InvSbox[218] +Xtime2Sbox[218] = _Xtime2Sbox[218] +Xtime3Sbox[218] = _Xtime3Sbox[218] +Xtime2[218] = _Xtime2[218] +Xtime9[218] = _Xtime9[218] +XtimeB[218] = _XtimeB[218] +XtimeD[218] = _XtimeD[218] +XtimeE[218] = _XtimeE[218] +Sbox[219] = _Sbox[219] +InvSbox[219] = _InvSbox[219] +Xtime2Sbox[219] = _Xtime2Sbox[219] +Xtime3Sbox[219] = _Xtime3Sbox[219] +Xtime2[219] = _Xtime2[219] +Xtime9[219] = _Xtime9[219] +XtimeB[219] = _XtimeB[219] +XtimeD[219] = _XtimeD[219] +XtimeE[219] = _XtimeE[219] +Sbox[220] = _Sbox[220] +InvSbox[220] = _InvSbox[220] +Xtime2Sbox[220] = _Xtime2Sbox[220] +Xtime3Sbox[220] = _Xtime3Sbox[220] +Xtime2[220] = _Xtime2[220] +Xtime9[220] = _Xtime9[220] +XtimeB[220] = _XtimeB[220] +XtimeD[220] = _XtimeD[220] +XtimeE[220] = _XtimeE[220] +Sbox[221] = _Sbox[221] +InvSbox[221] = _InvSbox[221] +Xtime2Sbox[221] = _Xtime2Sbox[221] +Xtime3Sbox[221] = _Xtime3Sbox[221] +Xtime2[221] = _Xtime2[221] +Xtime9[221] = _Xtime9[221] +XtimeB[221] = _XtimeB[221] +XtimeD[221] = _XtimeD[221] +XtimeE[221] = _XtimeE[221] +Sbox[222] = _Sbox[222] +InvSbox[222] = _InvSbox[222] +Xtime2Sbox[222] = _Xtime2Sbox[222] +Xtime3Sbox[222] = _Xtime3Sbox[222] +Xtime2[222] = _Xtime2[222] +Xtime9[222] = _Xtime9[222] +XtimeB[222] = _XtimeB[222] +XtimeD[222] = _XtimeD[222] +XtimeE[222] = _XtimeE[222] +Sbox[223] = _Sbox[223] +InvSbox[223] = _InvSbox[223] +Xtime2Sbox[223] = _Xtime2Sbox[223] +Xtime3Sbox[223] = _Xtime3Sbox[223] +Xtime2[223] = _Xtime2[223] +Xtime9[223] = _Xtime9[223] +XtimeB[223] = _XtimeB[223] +XtimeD[223] = _XtimeD[223] +XtimeE[223] = _XtimeE[223] +Sbox[224] = _Sbox[224] +InvSbox[224] = _InvSbox[224] +Xtime2Sbox[224] = _Xtime2Sbox[224] +Xtime3Sbox[224] = _Xtime3Sbox[224] +Xtime2[224] = _Xtime2[224] +Xtime9[224] = _Xtime9[224] +XtimeB[224] = _XtimeB[224] +XtimeD[224] = _XtimeD[224] +XtimeE[224] = _XtimeE[224] +Sbox[225] = _Sbox[225] +InvSbox[225] = _InvSbox[225] +Xtime2Sbox[225] = _Xtime2Sbox[225] +Xtime3Sbox[225] = _Xtime3Sbox[225] +Xtime2[225] = _Xtime2[225] +Xtime9[225] = _Xtime9[225] +XtimeB[225] = _XtimeB[225] +XtimeD[225] = _XtimeD[225] +XtimeE[225] = _XtimeE[225] +Sbox[226] = _Sbox[226] +InvSbox[226] = _InvSbox[226] +Xtime2Sbox[226] = _Xtime2Sbox[226] +Xtime3Sbox[226] = _Xtime3Sbox[226] +Xtime2[226] = _Xtime2[226] +Xtime9[226] = _Xtime9[226] +XtimeB[226] = _XtimeB[226] +XtimeD[226] = _XtimeD[226] +XtimeE[226] = _XtimeE[226] +Sbox[227] = _Sbox[227] +InvSbox[227] = _InvSbox[227] +Xtime2Sbox[227] = _Xtime2Sbox[227] +Xtime3Sbox[227] = _Xtime3Sbox[227] +Xtime2[227] = _Xtime2[227] +Xtime9[227] = _Xtime9[227] +XtimeB[227] = _XtimeB[227] +XtimeD[227] = _XtimeD[227] +XtimeE[227] = _XtimeE[227] +Sbox[228] = _Sbox[228] +InvSbox[228] = _InvSbox[228] +Xtime2Sbox[228] = _Xtime2Sbox[228] +Xtime3Sbox[228] = _Xtime3Sbox[228] +Xtime2[228] = _Xtime2[228] +Xtime9[228] = _Xtime9[228] +XtimeB[228] = _XtimeB[228] +XtimeD[228] = _XtimeD[228] +XtimeE[228] = _XtimeE[228] +Sbox[229] = _Sbox[229] +InvSbox[229] = _InvSbox[229] +Xtime2Sbox[229] = _Xtime2Sbox[229] +Xtime3Sbox[229] = _Xtime3Sbox[229] +Xtime2[229] = _Xtime2[229] +Xtime9[229] = _Xtime9[229] +XtimeB[229] = _XtimeB[229] +XtimeD[229] = _XtimeD[229] +XtimeE[229] = _XtimeE[229] +Sbox[230] = _Sbox[230] +InvSbox[230] = _InvSbox[230] +Xtime2Sbox[230] = _Xtime2Sbox[230] +Xtime3Sbox[230] = _Xtime3Sbox[230] +Xtime2[230] = _Xtime2[230] +Xtime9[230] = _Xtime9[230] +XtimeB[230] = _XtimeB[230] +XtimeD[230] = _XtimeD[230] +XtimeE[230] = _XtimeE[230] +Sbox[231] = _Sbox[231] +InvSbox[231] = _InvSbox[231] +Xtime2Sbox[231] = _Xtime2Sbox[231] +Xtime3Sbox[231] = _Xtime3Sbox[231] +Xtime2[231] = _Xtime2[231] +Xtime9[231] = _Xtime9[231] +XtimeB[231] = _XtimeB[231] +XtimeD[231] = _XtimeD[231] +XtimeE[231] = _XtimeE[231] +Sbox[232] = _Sbox[232] +InvSbox[232] = _InvSbox[232] +Xtime2Sbox[232] = _Xtime2Sbox[232] +Xtime3Sbox[232] = _Xtime3Sbox[232] +Xtime2[232] = _Xtime2[232] +Xtime9[232] = _Xtime9[232] +XtimeB[232] = _XtimeB[232] +XtimeD[232] = _XtimeD[232] +XtimeE[232] = _XtimeE[232] +Sbox[233] = _Sbox[233] +InvSbox[233] = _InvSbox[233] +Xtime2Sbox[233] = _Xtime2Sbox[233] +Xtime3Sbox[233] = _Xtime3Sbox[233] +Xtime2[233] = _Xtime2[233] +Xtime9[233] = _Xtime9[233] +XtimeB[233] = _XtimeB[233] +XtimeD[233] = _XtimeD[233] +XtimeE[233] = _XtimeE[233] +Sbox[234] = _Sbox[234] +InvSbox[234] = _InvSbox[234] +Xtime2Sbox[234] = _Xtime2Sbox[234] +Xtime3Sbox[234] = _Xtime3Sbox[234] +Xtime2[234] = _Xtime2[234] +Xtime9[234] = _Xtime9[234] +XtimeB[234] = _XtimeB[234] +XtimeD[234] = _XtimeD[234] +XtimeE[234] = _XtimeE[234] +Sbox[235] = _Sbox[235] +InvSbox[235] = _InvSbox[235] +Xtime2Sbox[235] = _Xtime2Sbox[235] +Xtime3Sbox[235] = _Xtime3Sbox[235] +Xtime2[235] = _Xtime2[235] +Xtime9[235] = _Xtime9[235] +XtimeB[235] = _XtimeB[235] +XtimeD[235] = _XtimeD[235] +XtimeE[235] = _XtimeE[235] +Sbox[236] = _Sbox[236] +InvSbox[236] = _InvSbox[236] +Xtime2Sbox[236] = _Xtime2Sbox[236] +Xtime3Sbox[236] = _Xtime3Sbox[236] +Xtime2[236] = _Xtime2[236] +Xtime9[236] = _Xtime9[236] +XtimeB[236] = _XtimeB[236] +XtimeD[236] = _XtimeD[236] +XtimeE[236] = _XtimeE[236] +Sbox[237] = _Sbox[237] +InvSbox[237] = _InvSbox[237] +Xtime2Sbox[237] = _Xtime2Sbox[237] +Xtime3Sbox[237] = _Xtime3Sbox[237] +Xtime2[237] = _Xtime2[237] +Xtime9[237] = _Xtime9[237] +XtimeB[237] = _XtimeB[237] +XtimeD[237] = _XtimeD[237] +XtimeE[237] = _XtimeE[237] +Sbox[238] = _Sbox[238] +InvSbox[238] = _InvSbox[238] +Xtime2Sbox[238] = _Xtime2Sbox[238] +Xtime3Sbox[238] = _Xtime3Sbox[238] +Xtime2[238] = _Xtime2[238] +Xtime9[238] = _Xtime9[238] +XtimeB[238] = _XtimeB[238] +XtimeD[238] = _XtimeD[238] +XtimeE[238] = _XtimeE[238] +Sbox[239] = _Sbox[239] +InvSbox[239] = _InvSbox[239] +Xtime2Sbox[239] = _Xtime2Sbox[239] +Xtime3Sbox[239] = _Xtime3Sbox[239] +Xtime2[239] = _Xtime2[239] +Xtime9[239] = _Xtime9[239] +XtimeB[239] = _XtimeB[239] +XtimeD[239] = _XtimeD[239] +XtimeE[239] = _XtimeE[239] +Sbox[240] = _Sbox[240] +InvSbox[240] = _InvSbox[240] +Xtime2Sbox[240] = _Xtime2Sbox[240] +Xtime3Sbox[240] = _Xtime3Sbox[240] +Xtime2[240] = _Xtime2[240] +Xtime9[240] = _Xtime9[240] +XtimeB[240] = _XtimeB[240] +XtimeD[240] = _XtimeD[240] +XtimeE[240] = _XtimeE[240] +Sbox[241] = _Sbox[241] +InvSbox[241] = _InvSbox[241] +Xtime2Sbox[241] = _Xtime2Sbox[241] +Xtime3Sbox[241] = _Xtime3Sbox[241] +Xtime2[241] = _Xtime2[241] +Xtime9[241] = _Xtime9[241] +XtimeB[241] = _XtimeB[241] +XtimeD[241] = _XtimeD[241] +XtimeE[241] = _XtimeE[241] +Sbox[242] = _Sbox[242] +InvSbox[242] = _InvSbox[242] +Xtime2Sbox[242] = _Xtime2Sbox[242] +Xtime3Sbox[242] = _Xtime3Sbox[242] +Xtime2[242] = _Xtime2[242] +Xtime9[242] = _Xtime9[242] +XtimeB[242] = _XtimeB[242] +XtimeD[242] = _XtimeD[242] +XtimeE[242] = _XtimeE[242] +Sbox[243] = _Sbox[243] +InvSbox[243] = _InvSbox[243] +Xtime2Sbox[243] = _Xtime2Sbox[243] +Xtime3Sbox[243] = _Xtime3Sbox[243] +Xtime2[243] = _Xtime2[243] +Xtime9[243] = _Xtime9[243] +XtimeB[243] = _XtimeB[243] +XtimeD[243] = _XtimeD[243] +XtimeE[243] = _XtimeE[243] +Sbox[244] = _Sbox[244] +InvSbox[244] = _InvSbox[244] +Xtime2Sbox[244] = _Xtime2Sbox[244] +Xtime3Sbox[244] = _Xtime3Sbox[244] +Xtime2[244] = _Xtime2[244] +Xtime9[244] = _Xtime9[244] +XtimeB[244] = _XtimeB[244] +XtimeD[244] = _XtimeD[244] +XtimeE[244] = _XtimeE[244] +Sbox[245] = _Sbox[245] +InvSbox[245] = _InvSbox[245] +Xtime2Sbox[245] = _Xtime2Sbox[245] +Xtime3Sbox[245] = _Xtime3Sbox[245] +Xtime2[245] = _Xtime2[245] +Xtime9[245] = _Xtime9[245] +XtimeB[245] = _XtimeB[245] +XtimeD[245] = _XtimeD[245] +XtimeE[245] = _XtimeE[245] +Sbox[246] = _Sbox[246] +InvSbox[246] = _InvSbox[246] +Xtime2Sbox[246] = _Xtime2Sbox[246] +Xtime3Sbox[246] = _Xtime3Sbox[246] +Xtime2[246] = _Xtime2[246] +Xtime9[246] = _Xtime9[246] +XtimeB[246] = _XtimeB[246] +XtimeD[246] = _XtimeD[246] +XtimeE[246] = _XtimeE[246] +Sbox[247] = _Sbox[247] +InvSbox[247] = _InvSbox[247] +Xtime2Sbox[247] = _Xtime2Sbox[247] +Xtime3Sbox[247] = _Xtime3Sbox[247] +Xtime2[247] = _Xtime2[247] +Xtime9[247] = _Xtime9[247] +XtimeB[247] = _XtimeB[247] +XtimeD[247] = _XtimeD[247] +XtimeE[247] = _XtimeE[247] +Sbox[248] = _Sbox[248] +InvSbox[248] = _InvSbox[248] +Xtime2Sbox[248] = _Xtime2Sbox[248] +Xtime3Sbox[248] = _Xtime3Sbox[248] +Xtime2[248] = _Xtime2[248] +Xtime9[248] = _Xtime9[248] +XtimeB[248] = _XtimeB[248] +XtimeD[248] = _XtimeD[248] +XtimeE[248] = _XtimeE[248] +Sbox[249] = _Sbox[249] +InvSbox[249] = _InvSbox[249] +Xtime2Sbox[249] = _Xtime2Sbox[249] +Xtime3Sbox[249] = _Xtime3Sbox[249] +Xtime2[249] = _Xtime2[249] +Xtime9[249] = _Xtime9[249] +XtimeB[249] = _XtimeB[249] +XtimeD[249] = _XtimeD[249] +XtimeE[249] = _XtimeE[249] +Sbox[250] = _Sbox[250] +InvSbox[250] = _InvSbox[250] +Xtime2Sbox[250] = _Xtime2Sbox[250] +Xtime3Sbox[250] = _Xtime3Sbox[250] +Xtime2[250] = _Xtime2[250] +Xtime9[250] = _Xtime9[250] +XtimeB[250] = _XtimeB[250] +XtimeD[250] = _XtimeD[250] +XtimeE[250] = _XtimeE[250] +Sbox[251] = _Sbox[251] +InvSbox[251] = _InvSbox[251] +Xtime2Sbox[251] = _Xtime2Sbox[251] +Xtime3Sbox[251] = _Xtime3Sbox[251] +Xtime2[251] = _Xtime2[251] +Xtime9[251] = _Xtime9[251] +XtimeB[251] = _XtimeB[251] +XtimeD[251] = _XtimeD[251] +XtimeE[251] = _XtimeE[251] +Sbox[252] = _Sbox[252] +InvSbox[252] = _InvSbox[252] +Xtime2Sbox[252] = _Xtime2Sbox[252] +Xtime3Sbox[252] = _Xtime3Sbox[252] +Xtime2[252] = _Xtime2[252] +Xtime9[252] = _Xtime9[252] +XtimeB[252] = _XtimeB[252] +XtimeD[252] = _XtimeD[252] +XtimeE[252] = _XtimeE[252] +Sbox[253] = _Sbox[253] +InvSbox[253] = _InvSbox[253] +Xtime2Sbox[253] = _Xtime2Sbox[253] +Xtime3Sbox[253] = _Xtime3Sbox[253] +Xtime2[253] = _Xtime2[253] +Xtime9[253] = _Xtime9[253] +XtimeB[253] = _XtimeB[253] +XtimeD[253] = _XtimeD[253] +XtimeE[253] = _XtimeE[253] +Sbox[254] = _Sbox[254] +InvSbox[254] = _InvSbox[254] +Xtime2Sbox[254] = _Xtime2Sbox[254] +Xtime3Sbox[254] = _Xtime3Sbox[254] +Xtime2[254] = _Xtime2[254] +Xtime9[254] = _Xtime9[254] +XtimeB[254] = _XtimeB[254] +XtimeD[254] = _XtimeD[254] +XtimeE[254] = _XtimeE[254] +Sbox[255] = _Sbox[255] +InvSbox[255] = _InvSbox[255] +Xtime2Sbox[255] = _Xtime2Sbox[255] +Xtime3Sbox[255] = _Xtime3Sbox[255] +Xtime2[255] = _Xtime2[255] +Xtime9[255] = _Xtime9[255] +XtimeB[255] = _XtimeB[255] +XtimeD[255] = _XtimeD[255] +XtimeE[255] = _XtimeE[255] diff --git a/flash-src/third-party/com/hurlant/crypto/tests/AESKeyTest.as b/flash-src/third-party/com/hurlant/crypto/tests/AESKeyTest.as new file mode 100755 index 0000000..c43fc5f --- /dev/null +++ b/flash-src/third-party/com/hurlant/crypto/tests/AESKeyTest.as @@ -0,0 +1,1220 @@ +/**
+ * AESKeyTest
+ *
+ * A test class for AESKey
+ * Copyright (c) 2007 Henri Torgemane
+ *
+ * See LICENSE.txt for full license information.
+ */
+package com.hurlant.crypto.tests
+{
+ import com.hurlant.crypto.prng.Random;
+ import com.hurlant.crypto.symmetric.AESKey;
+ import com.hurlant.crypto.symmetric.ECBMode;
+ import com.hurlant.util.Hex;
+
+ import flash.utils.ByteArray;
+ import flash.utils.getTimer;
+
+ public class AESKeyTest extends TestCase
+ {
+ public function AESKeyTest(h:ITestHarness) {
+ super(h, "AESKey Test");
+
+ runTest(testGetBlockSize, "AES Block Size");
+ runTest(testECB_TBL, "AES ECB Test Vectors");
+
+ h.endTestCase();
+ }
+
+
+ public function testGetBlockSize():void {
+ var key:ByteArray = new ByteArray;
+ for (var i:uint=0;i<32;i++) {
+ key[i]=i;
+ }
+ var k:AESKey = new AESKey(key);
+ assert("128bit block size", k.getBlockSize()==16);
+ }
+
+ /**
+ * http://csrc.nist.gov/encryption/aes/rijndael/rijndael-vals.zip
+ * this uses ecb_tbl.txt
+ * we test encryption and decryption with keys of length 128,192,256 bits.
+ */
+ public function testECB_TBL():void {
+ var keys:Array = [
+ "00010203050607080A0B0C0D0F101112",
+ "14151617191A1B1C1E1F202123242526",
+ "28292A2B2D2E2F30323334353738393A",
+ "3C3D3E3F41424344464748494B4C4D4E",
+ "50515253555657585A5B5C5D5F606162",
+ "64656667696A6B6C6E6F707173747576",
+ "78797A7B7D7E7F80828384858788898A",
+ "8C8D8E8F91929394969798999B9C9D9E",
+ "A0A1A2A3A5A6A7A8AAABACADAFB0B1B2",
+ "B4B5B6B7B9BABBBCBEBFC0C1C3C4C5C6",
+ "C8C9CACBCDCECFD0D2D3D4D5D7D8D9DA",
+ "DCDDDEDFE1E2E3E4E6E7E8E9EBECEDEE",
+ "F0F1F2F3F5F6F7F8FAFBFCFDFE010002",
+ "04050607090A0B0C0E0F101113141516",
+ "2C2D2E2F31323334363738393B3C3D3E",
+ "40414243454647484A4B4C4D4F505152",
+ "54555657595A5B5C5E5F606163646566",
+ "68696A6B6D6E6F70727374757778797A",
+ "7C7D7E7F81828384868788898B8C8D8E",
+ "A4A5A6A7A9AAABACAEAFB0B1B3B4B5B6",
+ "E0E1E2E3E5E6E7E8EAEBECEDEFF0F1F2",
+ "08090A0B0D0E0F10121314151718191A",
+ "6C6D6E6F71727374767778797B7C7D7E",
+ "80818283858687888A8B8C8D8F909192",
+ "94959697999A9B9C9E9FA0A1A3A4A5A6",
+ "A8A9AAABADAEAFB0B2B3B4B5B7B8B9BA",
+ "BCBDBEBFC1C2C3C4C6C7C8C9CBCCCDCE",
+ "D0D1D2D3D5D6D7D8DADBDCDDDFE0E1E2",
+ "E4E5E6E7E9EAEBECEEEFF0F1F3F4F5F6",
+ "F8F9FAFBFDFEFE00020304050708090A",
+ "0C0D0E0F11121314161718191B1C1D1E",
+ "20212223252627282A2B2C2D2F303132",
+ "34353637393A3B3C3E3F404143444546",
+ "48494A4B4D4E4F50525354555758595A",
+ "5C5D5E5F61626364666768696B6C6D6E",
+ "70717273757677787A7B7C7D7F808182",
+ "84858687898A8B8C8E8F909193949596",
+ "98999A9B9D9E9FA0A2A3A4A5A7A8A9AA",
+ "ACADAEAFB1B2B3B4B6B7B8B9BBBCBDBE",
+ "C0C1C2C3C5C6C7C8CACBCCCDCFD0D1D2",
+ "D4D5D6D7D9DADBDCDEDFE0E1E3E4E5E6",
+ "E8E9EAEBEDEEEFF0F2F3F4F5F7F8F9FA",
+ "FCFDFEFF01020304060708090B0C0D0E",
+ "10111213151617181A1B1C1D1F202122",
+ "24252627292A2B2C2E2F303133343536",
+ "38393A3B3D3E3F40424344454748494A",
+ "4C4D4E4F51525354565758595B5C5D5E",
+ "60616263656667686A6B6C6D6F707172",
+ "74757677797A7B7C7E7F808183848586",
+ "88898A8B8D8E8F90929394959798999A",
+ "9C9D9E9FA1A2A3A4A6A7A8A9ABACADAE",
+ "B0B1B2B3B5B6B7B8BABBBCBDBFC0C1C2",
+ "C4C5C6C7C9CACBCCCECFD0D1D3D4D5D6",
+ "D8D9DADBDDDEDFE0E2E3E4E5E7E8E9EA",
+ "ECEDEEEFF1F2F3F4F6F7F8F9FBFCFDFE",
+ "00010203050607080A0B0C0D0F101112",
+ "14151617191A1B1C1E1F202123242526",
+ "28292A2B2D2E2F30323334353738393A",
+ "3C3D3E3F41424344464748494B4C4D4E",
+ "50515253555657585A5B5C5D5F606162",
+ "64656667696A6B6C6E6F707173747576",
+ "78797A7B7D7E7F80828384858788898A",
+ "8C8D8E8F91929394969798999B9C9D9E",
+ "A0A1A2A3A5A6A7A8AAABACADAFB0B1B2",
+ "B4B5B6B7B9BABBBCBEBFC0C1C3C4C5C6",
+ "C8C9CACBCDCECFD0D2D3D4D5D7D8D9DA",
+ "DCDDDEDFE1E2E3E4E6E7E8E9EBECEDEE",
+ "F0F1F2F3F5F6F7F8FAFBFCFDFE010002",
+ "04050607090A0B0C0E0F101113141516",
+ "18191A1B1D1E1F20222324252728292A",
+ "2C2D2E2F31323334363738393B3C3D3E",
+ "40414243454647484A4B4C4D4F505152",
+ "54555657595A5B5C5E5F606163646566",
+ "68696A6B6D6E6F70727374757778797A",
+ "7C7D7E7F81828384868788898B8C8D8E",
+ "90919293959697989A9B9C9D9FA0A1A2",
+ "A4A5A6A7A9AAABACAEAFB0B1B3B4B5B6",
+ "B8B9BABBBDBEBFC0C2C3C4C5C7C8C9CA",
+ "CCCDCECFD1D2D3D4D6D7D8D9DBDCDDDE",
+ "E0E1E2E3E5E6E7E8EAEBECEDEFF0F1F2",
+ "F4F5F6F7F9FAFBFCFEFE010103040506",
+ "08090A0B0D0E0F10121314151718191A",
+ "1C1D1E1F21222324262728292B2C2D2E",
+ "30313233353637383A3B3C3D3F404142",
+ "44454647494A4B4C4E4F505153545556",
+ "58595A5B5D5E5F60626364656768696A",
+ "6C6D6E6F71727374767778797B7C7D7E",
+ "80818283858687888A8B8C8D8F909192",
+ "94959697999A9B9C9E9FA0A1A3A4A5A6",
+ "A8A9AAABADAEAFB0B2B3B4B5B7B8B9BA",
+ "BCBDBEBFC1C2C3C4C6C7C8C9CBCCCDCE",
+ "D0D1D2D3D5D6D7D8DADBDCDDDFE0E1E2",
+ "E4E5E6E7E9EAEBECEEEFF0F1F3F4F5F6",
+ "F8F9FAFBFDFEFE00020304050708090A",
+ "0C0D0E0F11121314161718191B1C1D1E",
+ "20212223252627282A2B2C2D2F303132",
+ "34353637393A3B3C3E3F404143444546",
+ "48494A4B4D4E4F50525354555758595A",
+ "5C5D5E5F61626364666768696B6C6D6E",
+ "70717273757677787A7B7C7D7F808182",
+ "84858687898A8B8C8E8F909193949596",
+ "98999A9B9D9E9FA0A2A3A4A5A7A8A9AA",
+ "ACADAEAFB1B2B3B4B6B7B8B9BBBCBDBE",
+ "C0C1C2C3C5C6C7C8CACBCCCDCFD0D1D2",
+ "D4D5D6D7D9DADBDCDEDFE0E1E3E4E5E6",
+ "E8E9EAEBEDEEEFF0F2F3F4F5F7F8F9FA",
+ "FCFDFEFF01020304060708090B0C0D0E",
+ "10111213151617181A1B1C1D1F202122",
+ "24252627292A2B2C2E2F303133343536",
+ "38393A3B3D3E3F40424344454748494A",
+ "4C4D4E4F51525354565758595B5C5D5E",
+ "60616263656667686A6B6C6D6F707172",
+ "74757677797A7B7C7E7F808183848586",
+ "88898A8B8D8E8F90929394959798999A",
+ "9C9D9E9FA1A2A3A4A6A7A8A9ABACADAE",
+ "B0B1B2B3B5B6B7B8BABBBCBDBFC0C1C2",
+ "C4C5C6C7C9CACBCCCECFD0D1D3D4D5D6",
+ "D8D9DADBDDDEDFE0E2E3E4E5E7E8E9EA",
+ "ECEDEEEFF1F2F3F4F6F7F8F9FBFCFDFE",
+ "00010203050607080A0B0C0D0F101112",
+ "14151617191A1B1C1E1F202123242526",
+ "28292A2B2D2E2F30323334353738393A",
+ "3C3D3E3F41424344464748494B4C4D4E",
+ "50515253555657585A5B5C5D5F606162",
+ "64656667696A6B6C6E6F707173747576",
+ "78797A7B7D7E7F80828384858788898A",
+ "8C8D8E8F91929394969798999B9C9D9E",
+ "A0A1A2A3A5A6A7A8AAABACADAFB0B1B2",
+ "00010203050607080A0B0C0D0F10111214151617191A1B1C",
+ "1E1F20212324252628292A2B2D2E2F30323334353738393A",
+ "3C3D3E3F41424344464748494B4C4D4E5051525355565758",
+ "5A5B5C5D5F60616264656667696A6B6C6E6F707173747576",
+ "78797A7B7D7E7F80828384858788898A8C8D8E8F91929394",
+ "969798999B9C9D9EA0A1A2A3A5A6A7A8AAABACADAFB0B1B2",
+ "B4B5B6B7B9BABBBCBEBFC0C1C3C4C5C6C8C9CACBCDCECFD0",
+ "D2D3D4D5D7D8D9DADCDDDEDFE1E2E3E4E6E7E8E9EBECEDEE",
+ "F0F1F2F3F5F6F7F8FAFBFCFDFE01000204050607090A0B0C",
+ "0E0F10111314151618191A1B1D1E1F20222324252728292A",
+ "2C2D2E2F31323334363738393B3C3D3E4041424345464748",
+ "4A4B4C4D4F50515254555657595A5B5C5E5F606163646566",
+ "68696A6B6D6E6F70727374757778797A7C7D7E7F81828384",
+ "868788898B8C8D8E90919293959697989A9B9C9D9FA0A1A2",
+ "A4A5A6A7A9AAABACAEAFB0B1B3B4B5B6B8B9BABBBDBEBFC0",
+ "C2C3C4C5C7C8C9CACCCDCECFD1D2D3D4D6D7D8D9DBDCDDDE",
+ "E0E1E2E3E5E6E7E8EAEBECEDEFF0F1F2F4F5F6F7F9FAFBFC",
+ "FEFE01010304050608090A0B0D0E0F10121314151718191A",
+ "1C1D1E1F21222324262728292B2C2D2E3031323335363738",
+ "3A3B3C3D3F40414244454647494A4B4C4E4F505153545556",
+ "58595A5B5D5E5F60626364656768696A6C6D6E6F71727374",
+ "767778797B7C7D7E80818283858687888A8B8C8D8F909192",
+ "94959697999A9B9C9E9FA0A1A3A4A5A6A8A9AAABADAEAFB0",
+ "D0D1D2D3D5D6D7D8DADBDCDDDFE0E1E2E4E5E6E7E9EAEBEC",
+ "2A2B2C2D2F30313234353637393A3B3C3E3F404143444546",
+ "48494A4B4D4E4F50525354555758595A5C5D5E5F61626364",
+ "84858687898A8B8C8E8F90919394959698999A9B9D9E9FA0",
+ "A2A3A4A5A7A8A9AAACADAEAFB1B2B3B4B6B7B8B9BBBCBDBE",
+ "C0C1C2C3C5C6C7C8CACBCCCDCFD0D1D2D4D5D6D7D9DADBDC",
+ "1A1B1C1D1F20212224252627292A2B2C2E2F303133343536",
+ "38393A3B3D3E3F40424344454748494A4C4D4E4F51525354",
+ "929394959798999A9C9D9E9FA1A2A3A4A6A7A8A9ABACADAE",
+ "464748494B4C4D4E50515253555657585A5B5C5D5F606162",
+ "828384858788898A8C8D8E8F91929394969798999B9C9D9E",
+ "A0A1A2A3A5A6A7A8AAABACADAFB0B1B2B4B5B6B7B9BABBBC",
+ "BEBFC0C1C3C4C5C6C8C9CACBCDCECFD0D2D3D4D5D7D8D9DA",
+ "DCDDDEDFE1E2E3E4E6E7E8E9EBECEDEEF0F1F2F3F5F6F7F8",
+ "FAFBFCFDFE01000204050607090A0B0C0E0F101113141516",
+ "18191A1B1D1E1F20222324252728292A2C2D2E2F31323334",
+ "363738393B3C3D3E40414243454647484A4B4C4D4F505152",
+ "54555657595A5B5C5E5F60616364656668696A6B6D6E6F70",
+ "727374757778797A7C7D7E7F81828384868788898B8C8D8E",
+ "90919293959697989A9B9C9D9FA0A1A2A4A5A6A7A9AAABAC",
+ "AEAFB0B1B3B4B5B6B8B9BABBBDBEBFC0C2C3C4C5C7C8C9CA",
+ "CCCDCECFD1D2D3D4D6D7D8D9DBDCDDDEE0E1E2E3E5E6E7E8",
+ "EAEBECEDEFF0F1F2F4F5F6F7F9FAFBFCFEFE010103040506",
+ "08090A0B0D0E0F10121314151718191A1C1D1E1F21222324",
+ "262728292B2C2D2E30313233353637383A3B3C3D3F404142",
+ "44454647494A4B4C4E4F50515354555658595A5B5D5E5F60",
+ "626364656768696A6C6D6E6F71727374767778797B7C7D7E",
+ "80818283858687888A8B8C8D8F90919294959697999A9B9C",
+ "9E9FA0A1A3A4A5A6A8A9AAABADAEAFB0B2B3B4B5B7B8B9BA",
+ "BCBDBEBFC1C2C3C4C6C7C8C9CBCCCDCED0D1D2D3D5D6D7D8",
+ "DADBDCDDDFE0E1E2E4E5E6E7E9EAEBECEEEFF0F1F3F4F5F6",
+ "F8F9FAFBFDFEFE00020304050708090A0C0D0E0F11121314",
+ "161718191B1C1D1E20212223252627282A2B2C2D2F303132",
+ "34353637393A3B3C3E3F40414344454648494A4B4D4E4F50",
+ "525354555758595A5C5D5E5F61626364666768696B6C6D6E",
+ "70717273757677787A7B7C7D7F80818284858687898A8B8C",
+ "8E8F90919394959698999A9B9D9E9FA0A2A3A4A5A7A8A9AA",
+ "ACADAEAFB1B2B3B4B6B7B8B9BBBCBDBEC0C1C2C3C5C6C7C8",
+ "CACBCCCDCFD0D1D2D4D5D6D7D9DADBDCDEDFE0E1E3E4E5E6",
+ "E8E9EAEBEDEEEFF0F2F3F4F5F7F8F9FAFCFDFEFF01020304",
+ "060708090B0C0D0E10111213151617181A1B1C1D1F202122",
+ "24252627292A2B2C2E2F30313334353638393A3B3D3E3F40",
+ "424344454748494A4C4D4E4F51525354565758595B5C5D5E",
+ "60616263656667686A6B6C6D6F70717274757677797A7B7C",
+ "7E7F80818384858688898A8B8D8E8F90929394959798999A",
+ "9C9D9E9FA1A2A3A4A6A7A8A9ABACADAEB0B1B2B3B5B6B7B8",
+ "BABBBCBDBFC0C1C2C4C5C6C7C9CACBCCCECFD0D1D3D4D5D6",
+ "D8D9DADBDDDEDFE0E2E3E4E5E7E8E9EAECEDEEEFF1F2F3F4",
+ "F6F7F8F9FBFCFDFE00010203050607080A0B0C0D0F101112",
+ "14151617191A1B1C1E1F20212324252628292A2B2D2E2F30",
+ "323334353738393A3C3D3E3F41424344464748494B4C4D4E",
+ "50515253555657585A5B5C5D5F60616264656667696A6B6C",
+ "6E6F70717374757678797A7B7D7E7F80828384858788898A",
+ "8C8D8E8F91929394969798999B9C9D9EA0A1A2A3A5A6A7A8",
+ "AAABACADAFB0B1B2B4B5B6B7B9BABBBCBEBFC0C1C3C4C5C6",
+ "C8C9CACBCDCECFD0D2D3D4D5D7D8D9DADCDDDEDFE1E2E3E4",
+ "E6E7E8E9EBECEDEEF0F1F2F3F5F6F7F8FAFBFCFDFE010002",
+ "04050607090A0B0C0E0F10111314151618191A1B1D1E1F20",
+ "222324252728292A2C2D2E2F31323334363738393B3C3D3E",
+ "40414243454647484A4B4C4D4F50515254555657595A5B5C",
+ "5E5F60616364656668696A6B6D6E6F70727374757778797A",
+ "7C7D7E7F81828384868788898B8C8D8E9091929395969798",
+ "9A9B9C9D9FA0A1A2A4A5A6A7A9AAABACAEAFB0B1B3B4B5B6",
+ "B8B9BABBBDBEBFC0C2C3C4C5C7C8C9CACCCDCECFD1D2D3D4",
+ "D6D7D8D9DBDCDDDEE0E1E2E3E5E6E7E8EAEBECEDEFF0F1F2",
+ "F4F5F6F7F9FAFBFCFEFE01010304050608090A0B0D0E0F10",
+ "121314151718191A1C1D1E1F21222324262728292B2C2D2E",
+ "30313233353637383A3B3C3D3F40414244454647494A4B4C",
+ "4E4F50515354555658595A5B5D5E5F60626364656768696A",
+ "6C6D6E6F71727374767778797B7C7D7E8081828385868788",
+ "8A8B8C8D8F90919294959697999A9B9C9E9FA0A1A3A4A5A6",
+ "A8A9AAABADAEAFB0B2B3B4B5B7B8B9BABCBDBEBFC1C2C3C4",
+ "C6C7C8C9CBCCCDCED0D1D2D3D5D6D7D8DADBDCDDDFE0E1E2",
+ "E4E5E6E7E9EAEBECEEEFF0F1F3F4F5F6F8F9FAFBFDFEFE00",
+ "020304050708090A0C0D0E0F11121314161718191B1C1D1E",
+ "20212223252627282A2B2C2D2F30313234353637393A3B3C",
+ "3E3F40414344454648494A4B4D4E4F50525354555758595A",
+ "5C5D5E5F61626364666768696B6C6D6E7071727375767778",
+ "7A7B7C7D7F80818284858687898A8B8C8E8F909193949596",
+ "98999A9B9D9E9FA0A2A3A4A5A7A8A9AAACADAEAFB1B2B3B4",
+ "B6B7B8B9BBBCBDBEC0C1C2C3C5C6C7C8CACBCCCDCFD0D1D2",
+ "D4D5D6D7D9DADBDCDEDFE0E1E3E4E5E6E8E9EAEBEDEEEFF0",
+ "F2F3F4F5F7F8F9FAFCFDFEFF01020304060708090B0C0D0E",
+ "10111213151617181A1B1C1D1F20212224252627292A2B2C",
+ "2E2F30313334353638393A3B3D3E3F40424344454748494A",
+ "4C4D4E4F51525354565758595B5C5D5E6061626365666768",
+ "6A6B6C6D6F70717274757677797A7B7C7E7F808183848586",
+ "88898A8B8D8E8F90929394959798999A9C9D9E9FA1A2A3A4",
+ "A6A7A8A9ABACADAEB0B1B2B3B5B6B7B8BABBBCBDBFC0C1C2",
+ "C4C5C6C7C9CACBCCCECFD0D1D3D4D5D6D8D9DADBDDDEDFE0",
+ "E2E3E4E5E7E8E9EAECEDEEEFF1F2F3F4F6F7F8F9FBFCFDFE",
+ "00010203050607080A0B0C0D0F10111214151617191A1B1C",
+ "1E1F20212324252628292A2B2D2E2F30323334353738393A",
+ "3C3D3E3F41424344464748494B4C4D4E5051525355565758",
+ "5A5B5C5D5F60616264656667696A6B6C6E6F707173747576",
+ "78797A7B7D7E7F80828384858788898A8C8D8E8F91929394",
+ "969798999B9C9D9EA0A1A2A3A5A6A7A8AAABACADAFB0B1B2",
+ "B4B5B6B7B9BABBBCBEBFC0C1C3C4C5C6C8C9CACBCDCECFD0",
+ "D2D3D4D5D7D8D9DADCDDDEDFE1E2E3E4E6E7E8E9EBECEDEE",
+ "F0F1F2F3F5F6F7F8FAFBFCFDFE01000204050607090A0B0C",
+ "0E0F10111314151618191A1B1D1E1F20222324252728292A",
+ "2C2D2E2F31323334363738393B3C3D3E4041424345464748",
+ "4A4B4C4D4F50515254555657595A5B5C5E5F606163646566",
+ "68696A6B6D6E6F70727374757778797A7C7D7E7F81828384",
+ "868788898B8C8D8E90919293959697989A9B9C9D9FA0A1A2",
+ "00010203050607080A0B0C0D0F10111214151617191A1B1C1E1F202123242526",
+ "28292A2B2D2E2F30323334353738393A3C3D3E3F41424344464748494B4C4D4E",
+ "50515253555657585A5B5C5D5F60616264656667696A6B6C6E6F707173747576",
+ "78797A7B7D7E7F80828384858788898A8C8D8E8F91929394969798999B9C9D9E",
+ "A0A1A2A3A5A6A7A8AAABACADAFB0B1B2B4B5B6B7B9BABBBCBEBFC0C1C3C4C5C6",
+ "C8C9CACBCDCECFD0D2D3D4D5D7D8D9DADCDDDEDFE1E2E3E4E6E7E8E9EBECEDEE",
+ "F0F1F2F3F5F6F7F8FAFBFCFDFE01000204050607090A0B0C0E0F101113141516",
+ "18191A1B1D1E1F20222324252728292A2C2D2E2F31323334363738393B3C3D3E",
+ "40414243454647484A4B4C4D4F50515254555657595A5B5C5E5F606163646566",
+ "68696A6B6D6E6F70727374757778797A7C7D7E7F81828384868788898B8C8D8E",
+ "90919293959697989A9B9C9D9FA0A1A2A4A5A6A7A9AAABACAEAFB0B1B3B4B5B6",
+ "B8B9BABBBDBEBFC0C2C3C4C5C7C8C9CACCCDCECFD1D2D3D4D6D7D8D9DBDCDDDE",
+ "E0E1E2E3E5E6E7E8EAEBECEDEFF0F1F2F4F5F6F7F9FAFBFCFEFE010103040506",
+ "08090A0B0D0E0F10121314151718191A1C1D1E1F21222324262728292B2C2D2E",
+ "30313233353637383A3B3C3D3F40414244454647494A4B4C4E4F505153545556",
+ "58595A5B5D5E5F60626364656768696A6C6D6E6F71727374767778797B7C7D7E",
+ "80818283858687888A8B8C8D8F90919294959697999A9B9C9E9FA0A1A3A4A5A6",
+ "A8A9AAABADAEAFB0B2B3B4B5B7B8B9BABCBDBEBFC1C2C3C4C6C7C8C9CBCCCDCE",
+ "D0D1D2D3D5D6D7D8DADBDCDDDFE0E1E2E4E5E6E7E9EAEBECEEEFF0F1F3F4F5F6",
+ "70717273757677787A7B7C7D7F80818284858687898A8B8C8E8F909193949596",
+ "98999A9B9D9E9FA0A2A3A4A5A7A8A9AAACADAEAFB1B2B3B4B6B7B8B9BBBCBDBE",
+ "C0C1C2C3C5C6C7C8CACBCCCDCFD0D1D2D4D5D6D7D9DADBDCDEDFE0E1E3E4E5E6",
+ "E8E9EAEBEDEEEFF0F2F3F4F5F7F8F9FAFCFDFEFF01020304060708090B0C0D0E",
+ "10111213151617181A1B1C1D1F20212224252627292A2B2C2E2F303133343536",
+ "38393A3B3D3E3F40424344454748494A4C4D4E4F51525354565758595B5C5D5E",
+ "60616263656667686A6B6C6D6F70717274757677797A7B7C7E7F808183848586",
+ "88898A8B8D8E8F90929394959798999A9C9D9E9FA1A2A3A4A6A7A8A9ABACADAE",
+ "B0B1B2B3B5B6B7B8BABBBCBDBFC0C1C2C4C5C6C7C9CACBCCCECFD0D1D3D4D5D6",
+ "D8D9DADBDDDEDFE0E2E3E4E5E7E8E9EAECEDEEEFF1F2F3F4F6F7F8F9FBFCFDFE",
+ "00010203050607080A0B0C0D0F10111214151617191A1B1C1E1F202123242526",
+ "28292A2B2D2E2F30323334353738393A3C3D3E3F41424344464748494B4C4D4E",
+ "50515253555657585A5B5C5D5F60616264656667696A6B6C6E6F707173747576",
+ "78797A7B7D7E7F80828384858788898A8C8D8E8F91929394969798999B9C9D9E",
+ "A0A1A2A3A5A6A7A8AAABACADAFB0B1B2B4B5B6B7B9BABBBCBEBFC0C1C3C4C5C6",
+ "C8C9CACBCDCECFD0D2D3D4D5D7D8D9DADCDDDEDFE1E2E3E4E6E7E8E9EBECEDEE",
+ "F0F1F2F3F5F6F7F8FAFBFCFDFE01000204050607090A0B0C0E0F101113141516",
+ "18191A1B1D1E1F20222324252728292A2C2D2E2F31323334363738393B3C3D3E",
+ "40414243454647484A4B4C4D4F50515254555657595A5B5C5E5F606163646566",
+ "68696A6B6D6E6F70727374757778797A7C7D7E7F81828384868788898B8C8D8E",
+ "90919293959697989A9B9C9D9FA0A1A2A4A5A6A7A9AAABACAEAFB0B1B3B4B5B6",
+ "B8B9BABBBDBEBFC0C2C3C4C5C7C8C9CACCCDCECFD1D2D3D4D6D7D8D9DBDCDDDE",
+ "E0E1E2E3E5E6E7E8EAEBECEDEFF0F1F2F4F5F6F7F9FAFBFCFEFE010103040506",
+ "08090A0B0D0E0F10121314151718191A1C1D1E1F21222324262728292B2C2D2E",
+ "30313233353637383A3B3C3D3F40414244454647494A4B4C4E4F505153545556",
+ "58595A5B5D5E5F60626364656768696A6C6D6E6F71727374767778797B7C7D7E",
+ "80818283858687888A8B8C8D8F90919294959697999A9B9C9E9FA0A1A3A4A5A6",
+ "A8A9AAABADAEAFB0B2B3B4B5B7B8B9BABCBDBEBFC1C2C3C4C6C7C8C9CBCCCDCE",
+ "D0D1D2D3D5D6D7D8DADBDCDDDFE0E1E2E4E5E6E7E9EAEBECEEEFF0F1F3F4F5F6",
+ "F8F9FAFBFDFEFE00020304050708090A0C0D0E0F11121314161718191B1C1D1E",
+ "20212223252627282A2B2C2D2F30313234353637393A3B3C3E3F404143444546",
+ "48494A4B4D4E4F50525354555758595A5C5D5E5F61626364666768696B6C6D6E",
+ "70717273757677787A7B7C7D7F80818284858687898A8B8C8E8F909193949596",
+ "98999A9B9D9E9FA0A2A3A4A5A7A8A9AAACADAEAFB1B2B3B4B6B7B8B9BBBCBDBE",
+ "C0C1C2C3C5C6C7C8CACBCCCDCFD0D1D2D4D5D6D7D9DADBDCDEDFE0E1E3E4E5E6",
+ "E8E9EAEBEDEEEFF0F2F3F4F5F7F8F9FAFCFDFEFF01020304060708090B0C0D0E",
+ "10111213151617181A1B1C1D1F20212224252627292A2B2C2E2F303133343536",
+ "38393A3B3D3E3F40424344454748494A4C4D4E4F51525354565758595B5C5D5E",
+ "60616263656667686A6B6C6D6F70717274757677797A7B7C7E7F808183848586",
+ "88898A8B8D8E8F90929394959798999A9C9D9E9FA1A2A3A4A6A7A8A9ABACADAE",
+ "B0B1B2B3B5B6B7B8BABBBCBDBFC0C1C2C4C5C6C7C9CACBCCCECFD0D1D3D4D5D6",
+ "D8D9DADBDDDEDFE0E2E3E4E5E7E8E9EAECEDEEEFF1F2F3F4F6F7F8F9FBFCFDFE",
+ "00010203050607080A0B0C0D0F10111214151617191A1B1C1E1F202123242526",
+ "28292A2B2D2E2F30323334353738393A3C3D3E3F41424344464748494B4C4D4E",
+ "50515253555657585A5B5C5D5F60616264656667696A6B6C6E6F707173747576",
+ "78797A7B7D7E7F80828384858788898A8C8D8E8F91929394969798999B9C9D9E",
+ "A0A1A2A3A5A6A7A8AAABACADAFB0B1B2B4B5B6B7B9BABBBCBEBFC0C1C3C4C5C6",
+ "C8C9CACBCDCECFD0D2D3D4D5D7D8D9DADCDDDEDFE1E2E3E4E6E7E8E9EBECEDEE",
+ "F0F1F2F3F5F6F7F8FAFBFCFDFE01000204050607090A0B0C0E0F101113141516",
+ "18191A1B1D1E1F20222324252728292A2C2D2E2F31323334363738393B3C3D3E",
+ "40414243454647484A4B4C4D4F50515254555657595A5B5C5E5F606163646566",
+ "68696A6B6D6E6F70727374757778797A7C7D7E7F81828384868788898B8C8D8E",
+ "90919293959697989A9B9C9D9FA0A1A2A4A5A6A7A9AAABACAEAFB0B1B3B4B5B6",
+ "B8B9BABBBDBEBFC0C2C3C4C5C7C8C9CACCCDCECFD1D2D3D4D6D7D8D9DBDCDDDE",
+ "E0E1E2E3E5E6E7E8EAEBECEDEFF0F1F2F4F5F6F7F9FAFBFCFEFE010103040506",
+ "08090A0B0D0E0F10121314151718191A1C1D1E1F21222324262728292B2C2D2E",
+ "30313233353637383A3B3C3D3F40414244454647494A4B4C4E4F505153545556",
+ "58595A5B5D5E5F60626364656768696A6C6D6E6F71727374767778797B7C7D7E",
+ "80818283858687888A8B8C8D8F90919294959697999A9B9C9E9FA0A1A3A4A5A6",
+ "A8A9AAABADAEAFB0B2B3B4B5B7B8B9BABCBDBEBFC1C2C3C4C6C7C8C9CBCCCDCE",
+ "D0D1D2D3D5D6D7D8DADBDCDDDFE0E1E2E4E5E6E7E9EAEBECEEEFF0F1F3F4F5F6",
+ "F8F9FAFBFDFEFE00020304050708090A0C0D0E0F11121314161718191B1C1D1E",
+ "20212223252627282A2B2C2D2F30313234353637393A3B3C3E3F404143444546",
+ "48494A4B4D4E4F50525354555758595A5C5D5E5F61626364666768696B6C6D6E",
+ "70717273757677787A7B7C7D7F80818284858687898A8B8C8E8F909193949596",
+ "98999A9B9D9E9FA0A2A3A4A5A7A8A9AAACADAEAFB1B2B3B4B6B7B8B9BBBCBDBE",
+ "C0C1C2C3C5C6C7C8CACBCCCDCFD0D1D2D4D5D6D7D9DADBDCDEDFE0E1E3E4E5E6",
+ "E8E9EAEBEDEEEFF0F2F3F4F5F7F8F9FAFCFDFEFF01020304060708090B0C0D0E",
+ "10111213151617181A1B1C1D1F20212224252627292A2B2C2E2F303133343536",
+ "38393A3B3D3E3F40424344454748494A4C4D4E4F51525354565758595B5C5D5E",
+ "60616263656667686A6B6C6D6F70717274757677797A7B7C7E7F808183848586",
+ "88898A8B8D8E8F90929394959798999A9C9D9E9FA1A2A3A4A6A7A8A9ABACADAE",
+ "B0B1B2B3B5B6B7B8BABBBCBDBFC0C1C2C4C5C6C7C9CACBCCCECFD0D1D3D4D5D6",
+ "D8D9DADBDDDEDFE0E2E3E4E5E7E8E9EAECEDEEEFF1F2F3F4F6F7F8F9FBFCFDFE",
+ "00010203050607080A0B0C0D0F10111214151617191A1B1C1E1F202123242526",
+ "28292A2B2D2E2F30323334353738393A3C3D3E3F41424344464748494B4C4D4E",
+ "50515253555657585A5B5C5D5F60616264656667696A6B6C6E6F707173747576",
+ "78797A7B7D7E7F80828384858788898A8C8D8E8F91929394969798999B9C9D9E",
+ "A0A1A2A3A5A6A7A8AAABACADAFB0B1B2B4B5B6B7B9BABBBCBEBFC0C1C3C4C5C6",
+ "C8C9CACBCDCECFD0D2D3D4D5D7D8D9DADCDDDEDFE1E2E3E4E6E7E8E9EBECEDEE",
+ "F0F1F2F3F5F6F7F8FAFBFCFDFE01000204050607090A0B0C0E0F101113141516",
+ "18191A1B1D1E1F20222324252728292A2C2D2E2F31323334363738393B3C3D3E",
+ "40414243454647484A4B4C4D4F50515254555657595A5B5C5E5F606163646566",
+ "68696A6B6D6E6F70727374757778797A7C7D7E7F81828384868788898B8C8D8E",
+ "90919293959697989A9B9C9D9FA0A1A2A4A5A6A7A9AAABACAEAFB0B1B3B4B5B6",
+ "B8B9BABBBDBEBFC0C2C3C4C5C7C8C9CACCCDCECFD1D2D3D4D6D7D8D9DBDCDDDE",
+ "E0E1E2E3E5E6E7E8EAEBECEDEFF0F1F2F4F5F6F7F9FAFBFCFEFE010103040506",
+ "08090A0B0D0E0F10121314151718191A1C1D1E1F21222324262728292B2C2D2E",
+ "30313233353637383A3B3C3D3F40414244454647494A4B4C4E4F505153545556",
+ "58595A5B5D5E5F60626364656768696A6C6D6E6F71727374767778797B7C7D7E",
+ "80818283858687888A8B8C8D8F90919294959697999A9B9C9E9FA0A1A3A4A5A6",
+ "A8A9AAABADAEAFB0B2B3B4B5B7B8B9BABCBDBEBFC1C2C3C4C6C7C8C9CBCCCDCE",
+ "D0D1D2D3D5D6D7D8DADBDCDDDFE0E1E2E4E5E6E7E9EAEBECEEEFF0F1F3F4F5F6",
+ "F8F9FAFBFDFEFE00020304050708090A0C0D0E0F11121314161718191B1C1D1E",
+ "20212223252627282A2B2C2D2F30313234353637393A3B3C3E3F404143444546",
+ "48494A4B4D4E4F50525354555758595A5C5D5E5F61626364666768696B6C6D6E",
+ "70717273757677787A7B7C7D7F80818284858687898A8B8C8E8F909193949596",
+ "98999A9B9D9E9FA0A2A3A4A5A7A8A9AAACADAEAFB1B2B3B4B6B7B8B9BBBCBDBE",
+ "C0C1C2C3C5C6C7C8CACBCCCDCFD0D1D2D4D5D6D7D9DADBDCDEDFE0E1E3E4E5E6",
+ "E8E9EAEBEDEEEFF0F2F3F4F5F7F8F9FAFCFDFEFF01020304060708090B0C0D0E",
+ "10111213151617181A1B1C1D1F20212224252627292A2B2C2E2F303133343536",
+ "38393A3B3D3E3F40424344454748494A4C4D4E4F51525354565758595B5C5D5E",
+ "60616263656667686A6B6C6D6F70717274757677797A7B7C7E7F808183848586",
+ "88898A8B8D8E8F90929394959798999A9C9D9E9FA1A2A3A4A6A7A8A9ABACADAE",
+ "B0B1B2B3B5B6B7B8BABBBCBDBFC0C1C2C4C5C6C7C9CACBCCCECFD0D1D3D4D5D6",
+ "D8D9DADBDDDEDFE0E2E3E4E5E7E8E9EAECEDEEEFF1F2F3F4F6F7F8F9FBFCFDFE",
+ "00010203050607080A0B0C0D0F10111214151617191A1B1C1E1F202123242526",
+ "28292A2B2D2E2F30323334353738393A3C3D3E3F41424344464748494B4C4D4E",
+ "50515253555657585A5B5C5D5F60616264656667696A6B6C6E6F707173747576"];
+
+ var pts:Array = [
+ "506812A45F08C889B97F5980038B8359",
+ "5C6D71CA30DE8B8B00549984D2EC7D4B",
+ "53F3F4C64F8616E4E7C56199F48F21F6",
+ "A1EB65A3487165FB0F1C27FF9959F703",
+ "3553ECF0B1739558B08E350A98A39BFA",
+ "67429969490B9711AE2B01DC497AFDE8",
+ "93385C1F2AEC8BED192F5A8E161DD508",
+ "B5BF946BE19BEB8DB3983B5F4C6E8DDB",
+ "41321EE10E21BD907227C4450FF42324",
+ "00A82F59C91C8486D12C0A80124F6089",
+ "7CE0FD076754691B4BBD9FAF8A1372FE",
+ "23605A8243D07764541BC5AD355B3129",
+ "12A8CFA23EA764FD876232B4E842BC44",
+ "BCAF32415E8308B3723E5FDD853CCC80",
+ "89AFAE685D801AD747ACE91FC49ADDE0",
+ "F521D07B484357C4A69E76124A634216",
+ "3E23B3BC065BCC152407E23896D77783",
+ "79F0FBA002BE1744670E7E99290D8F52",
+ "DA23FE9D5BD63E1D72E3DAFBE21A6C2A",
+ "E3F5698BA90B6A022EFD7DB2C7E6C823",
+ "BDC2691D4F1B73D2700679C3BCBF9C6E",
+ "BA74E02093217EE1BA1B42BD5624349A",
+ "B5C593B5851C57FBF8B3F57715E8F680",
+ "3DA9BD9CEC072381788F9387C3BBF4EE",
+ "4197F3051121702AB65D316B3C637374",
+ "9F46C62EC4F6EE3F6E8C62554BC48AB7",
+ "0220673FE9E699A4EBC8E0DBEB6979C8",
+ "B2B99171337DED9BC8C2C23FF6F18867",
+ "A7FACF4E301E984E5EFEEFD645B23505",
+ "F7C762E4A9819160FD7ACFB6C4EEDCDD",
+ "9B64FC21EA08709F4915436FAA70F1BE",
+ "52AF2C3DE07EE6777F55A4ABFC100B3F",
+ "2FCA001224386C57AA3F968CBE2C816F",
+ "4149C73658A4A9C564342755EE2C132F",
+ "AF60005A00A1772F7C07A48A923C23D2",
+ "6FCCBC28363759914B6F0280AFAF20C6",
+ "7D82A43DDF4FEFA2FC5947499884D386",
+ "5D5A990EAAB9093AFE4CE254DFA49EF9",
+ "4CD1E2FD3F4434B553AAE453F0ED1A02",
+ "5A2C9A9641D4299125FA1B9363104B5E",
+ "B517FE34C0FA217D341740BFD4FE8DD4",
+ "014BAF2278A69D331D5180103643E99A",
+ "B529BD8164F20D0AA443D4932116841C",
+ "2E596DCBB2F33D4216A1176D5BD1E456",
+ "7274A1EA2B7EE2424E9A0E4673689143",
+ "AE20020BD4F13E9D90140BEE3B5D26AF",
+ "BAAC065DA7AC26E855E79C8849D75A02",
+ "7C917D8D1D45FAB9E2540E28832540CC",
+ "BDE6F89E16DAADB0E847A2A614566A91",
+ "C9DE163725F1F5BE44EBB1DB51D07FBC",
+ "3AF57A58F0C07DFFA669572B521E2B92",
+ "3D5EBAC306DDE4604F1B4FBBBFCDAE55",
+ "C2DFA91BCEB76A1183C995020AC0B556",
+ "C70F54305885E9A0746D01EC56C8596B",
+ "C4F81B610E98012CE000182050C0C2B2",
+ "EAAB86B1D02A95D7404EFF67489F97D4",
+ "7C55BDB40B88870B52BEC3738DE82886",
+ "BA6EAA88371FF0A3BD875E3F2A975CE0",
+ "08059130C4C24BD30CF0575E4E0373DC",
+ "9A8EAB004EF53093DFCF96F57E7EDA82",
+ "0745B589E2400C25F117B1D796C28129",
+ "2F1777781216CEC3F044F134B1B92BBE",
+ "353A779FFC541B3A3805D90CE17580FC",
+ "1A1EAE4415CEFCF08C4AC1C8F68BEA8F",
+ "E6E7E4E5B0B3B2B5D4D5AAAB16111013",
+ "F8F9FAFBFBF8F9E677767170EFE0E1E2",
+ "63626160A1A2A3A445444B4A75727370",
+ "717073720605040B2D2C2B2A05FAFBF9",
+ "78797A7BEAE9E8EF3736292891969794",
+ "838281803231300FDDDCDBDAA0AFAEAD",
+ "18191A1BBFBCBDBA75747B7A7F78797A",
+ "848586879B989996A3A2A5A4849B9A99",
+ "0001020322212027CACBF4F551565754",
+ "CECFCCCDAFACADB2515057564A454447",
+ "92939091CDCECFC813121D1C80878685",
+ "D2D3D0D16F6C6D6259585F5ED1EEEFEC",
+ "ACADAEAF878485820F0E1110D5D2D3D0",
+ "9091929364676619E6E7E0E1757A7B78",
+ "BABBB8B98A89888F74757A7B92959497",
+ "8D8C8F8E6E6D6C633B3A3D3CCAD5D4D7",
+ "86878485010203040808F7F767606162",
+ "8E8F8C8D656667788A8B8C8D010E0F0C",
+ "C8C9CACB858687807A7B7475E7E0E1E2",
+ "6D6C6F6E5053525D8C8D8A8BADD2D3D0",
+ "28292A2B393A3B3C0607181903040506",
+ "A5A4A7A6B0B3B28DDBDADDDCBDB2B3B0",
+ "323330316467666130313E3F2C2B2A29",
+ "27262524080B0A05171611100B141516",
+ "040506074142434435340B0AA3A4A5A6",
+ "242526271112130C61606766BDB2B3B0",
+ "4B4A4948252627209E9F9091CEC9C8CB",
+ "68696A6B6665646B9F9E9998D9E6E7E4",
+ "34353637C5C6C7C0F0F1EEEF7C7B7A79",
+ "32333031C2C1C13F0D0C0B0A050A0B08",
+ "CDCCCFCEBEBDBCBBABAAA5A4181F1E1D",
+ "212023223635343BA0A1A6A7445B5A59",
+ "0E0F0C0DA8ABAAAD2F2E515002050407",
+ "070605042A2928378E8F8889BDB2B3B0",
+ "CBCAC9C893909196A9A8A7A6A5A2A3A0",
+ "80818283C1C2C3CC9C9D9A9B0CF3F2F1",
+ "1213101125262720FAFBE4E5B1B6B7B4",
+ "7F7E7D7C3033320D97969190222D2C2F",
+ "4E4F4C4D484B4A4D81808F8E53545556",
+ "DCDDDEDFB0B3B2BD15141312A1BEBFBC",
+ "93929190282B2A2DC4C5FAFB92959497",
+ "F5F4F7F6C4C7C6D9373631307E717073",
+ "93929190B6B5B4B364656A6B05020300",
+ "BABBB8B90D0E0F00A4A5A2A3043B3A39",
+ "D8D9DADB7F7C7D7A10110E0F787F7E7D",
+ "FEFFFCFDEFECED923B3A3D3C6768696A",
+ "D6D7D4D58A89888F96979899A5A2A3A0",
+ "18191A1BA8ABAAA5303136379B848586",
+ "6B6A6968A4A7A6A1D6D72829B0B7B6B5",
+ "000102038A89889755545352A6A9A8AB",
+ "2D2C2F2EB3B0B1B6B6B7B8B9F2F5F4F7",
+ "979695943536373856575051E09F9E9D",
+ "A4A5A6A7989B9A9DB1B0AFAE7A7D7C7F",
+ "C1C0C3C2686B6A55A8A9AEAFEAE5E4E7",
+ "C1C0C3C2141716118C8D828364636261",
+ "93929190CCCFCEC196979091E0FFFEFD",
+ "B4B5B6B7F9FAFBFC25241B1A6E69686B",
+ "868784850704051AC7C6C1C08788898A",
+ "F4F5F6F7AAA9A8AFFDFCF3F277707172",
+ "D3D2D1D00605040BC3C2C5C43E010003",
+ "73727170424140476A6B74750D0A0B08",
+ "C2C3C0C10A0908F754555253A1AEAFAC",
+ "6D6C6F6EF8FBFAFD82838C8DF8FFFEFD",
+ "F5F4F7F684878689A6A7A0A1D2CDCCCF",
+ "2D33EEF2C0430A8A9EBF45E809C40BB6",
+ "6AA375D1FA155A61FB72353E0A5A8756",
+ "BC3736518B9490DCB8ED60EB26758ED4",
+ "AA214402B46CFFB9F761EC11263A311E",
+ "02AEA86E572EEAB66B2C3AF5E9A46FD6",
+ "E2AEF6ACC33B965C4FA1F91C75FF6F36",
+ "0659DF46427162B9434865DD9499F91D",
+ "49A44239C748FEB456F59C276A5658DF",
+ "66208F6E9D04525BDEDB2733B6A6BE37",
+ "3393F8DFC729C97F5480B950BC9666B0",
+ "606834C8CE063F3234CF1145325DBD71",
+ "FEC1C04F529BBD17D8CECFCC4718B17F",
+ "32DF99B431ED5DC5ACF8CAF6DC6CE475",
+ "7FDC2B746F3F665296943B83710D1F82",
+ "8FBA1510A3C5B87E2EAA3F7A91455CA2",
+ "2C9B468B1C2EED92578D41B0716B223B",
+ "0A2BBF0EFC6BC0034F8A03433FCA1B1A",
+ "25260E1F31F4104D387222E70632504B",
+ "C527D25A49F08A5228D338642AE65137",
+ "3B49FC081432F5890D0E3D87E884A69E",
+ "D173F9ED1E57597E166931DF2754A083",
+ "8C2B7CAFA5AFE7F13562DAEAE1ADEDE0",
+ "AAF4EC8C1A815AEB826CAB741339532C",
+ "40BE8C5D9108E663F38F1A2395279ECF",
+ "0C8AD9BC32D43E04716753AA4CFBE351",
+ "1407B1D5F87D63357C8DC7EBBAEBBFEE",
+ "E62734D1AE3378C4549E939E6F123416",
+ "5A752CFF2A176DB1A1DE77F2D2CDEE41",
+ "A9C8C3A4EABEDC80C64730DDD018CD88",
+ "EE9B3DBBDB86180072130834D305999A",
+ "A7FA8C3586B8EBDE7568EAD6F634A879",
+ "37E0F4A87F127D45AC936FE7AD88C10A",
+ "3F77D8B5D92BAC148E4E46F697A535C5",
+ "D25EBB686C40F7E2C4DA1014936571CA",
+ "4F1C769D1E5B0552C7ECA84DEA26A549",
+ "8548E2F882D7584D0FAFC54372B6633A",
+ "87D7A336CB476F177CD2A51AF2A62CDF",
+ "03B1FEAC668C4E485C1065DFC22B44EE",
+ "BDA15E66819FA72D653A6866AA287962",
+ "4D0C7A0D2505B80BF8B62CEB12467F0A",
+ "626D34C9429B37211330986466B94E5F",
+ "333C3E6BF00656B088A17E5FF0E7F60A",
+ "687ED0CDC0D2A2BC8C466D05EF9D2891",
+ "487830E78CC56C1693E64B2A6660C7B6",
+ "7A48D6B7B52B29392AA2072A32B66160",
+ "907320E64C8C5314D10F8D7A11C8618D",
+ "B561F2CA2D6E65A4A98341F3ED9FF533",
+ "DF769380D212792D026F049E2E3E48EF",
+ "79F374BC445BDABF8FCCB8843D6054C6",
+ "4E02F1242FA56B05C68DBAE8FE44C9D6",
+ "CF73C93CBFF57AC635A6F4AD2A4A1545",
+ "9923548E2875750725B886566784C625",
+ "4888336B723A022C9545320F836A4207",
+ "F84D9A5561B0608B1160DEE000C41BA8",
+ "C23192A0418E30A19B45AE3E3625BF22",
+ "B84E0690B28B0025381AD82A15E501A7",
+ "ACEF5E5C108876C4F06269F865B8F0B0",
+ "0F1B3603E0F5DDEA4548246153A5E064",
+ "FBB63893450D42B58C6D88CD3C1809E3",
+ "4BEF736DF150259DAE0C91354E8A5F92",
+ "7D2D46242056EF13D3C3FC93C128F4C7",
+ "E9C1BA2DF415657A256EDB33934680FD",
+ "E23EE277B0AA0A1DFB81F7527C3514F1",
+ "3E7445B0B63CAAF75E4A911E12106B4C",
+ "767774752023222544455A5BE6E1E0E3",
+ "72737475717E7F7CE9E8EBEA696A6B6C",
+ "DFDEDDDC25262728C9C8CFCEF1EEEFEC",
+ "FFFE0100707776755F5E5D5C7675746B",
+ "E0E1E2E3424140479F9E9190292E2F2C",
+ "2120272690EFEEED3B3A39384E4D4C4B",
+ "ECEDEEEF5350516EA1A0A7A6A3ACADAE",
+ "32333C3D25222320E9E8EBEACECDCCC3",
+ "40414243626160678A8BB4B511161714",
+ "94959293F5FAFBF81F1E1D1C7C7F7E79",
+ "BEBFBCBD191A1B14CFCEC9C8546B6A69",
+ "2C2D3233898E8F8CBBBAB9B8333031CE",
+ "84858687BFBCBDBA37363938FDFAFBF8",
+ "828384857669686B909192930B08090E",
+ "BEBFBCBD9695948B707176779E919093",
+ "8B8A85846067666521202322D0D3D2DD",
+ "76777475F1F2F3F4F8F9E6E777707172",
+ "A4A5A2A34F404142B4B5B6B727242522",
+ "94959697E1E2E3EC16171011839C9D9E",
+ "03023D3C06010003DEDFDCDDFFFCFDE2",
+ "10111213F1F2F3F4CECFC0C1DBDCDDDE",
+ "67666160724D4C4F1D1C1F1E73707176",
+ "E6E7E4E5A8ABAAD584858283909F9E9D",
+ "71707F7E565150537D7C7F7E6162636C",
+ "64656667212223245555AAAA03040506",
+ "9E9F9899ABA4A5A6CFCECDCC2B28292E",
+ "C7C6C5C4D1D2D3DC626364653A454447",
+ "F6F7E8E9E0E7E6E51D1C1F1E5B585966",
+ "BCBDBEBF5D5E5F5868696667F4F3F2F1",
+ "40414647B0AFAEAD9B9A99989B98999E",
+ "69686B6A0201001F0F0E0908B4BBBAB9",
+ "C7C6C9C8D8DFDEDD5A5B5859BEBDBCB3",
+ "DEDFDCDD787B7A7DFFFEE1E0B2B5B4B7",
+ "4D4C4B4A606F6E6DD0D1D2D3FBF8F9FE",
+ "B7B6B5B4D7D4D5DAE5E4E3E2E1FEFFFC",
+ "CECFB0B1F7F0F1F2AEAFACAD3E3D3C23",
+ "CACBC8C9CDCECFC812131C1D494E4F4C",
+ "9D9C9B9AD22D2C2FB1B0B3B20C0F0E09",
+ "7A7B787964676659959493924F404142",
+ "AAABA4A5CEC9C8CB1F1E1D1CABA8A9A6",
+ "93929190282B2A2DC4C5FAFB92959497",
+ "EFEEE9E8DED1D0D339383B3A888B8A8D",
+ "7F7E7D7CA2A1A0AF78797E7F112E2F2C",
+ "84859A9B2B2C2D2E868784852625245B",
+ "B0B1B2B3070405026869666710171615",
+ "ACADAAABBDA2A3A00D0C0F0E595A5B5C",
+ "121310115655544B5253545569666764",
+ "DEDFD0D166616063EAEBE8E94142434C",
+ "DBDAD9D81417161166677879E0E7E6E5",
+ "6A6B6C6DE0EFEEED2B2A2928C0C3C2C5",
+ "B1B0B3B21714151A1A1B1C1D5649484B",
+ "39380706A3A4A5A6C4C5C6C77271706F",
+ "5C5D5E5F1013121539383736E2E5E4E7",
+ "43424544EAD5D4D72E2F2C2D64676661",
+ "55545756989B9A65F8F9FEFF18171615",
+ "05040B0A525554573C3D3E3F4A494847",
+ "14151617595A5B5C8584FBFA8E89888B",
+ "7C7D7A7BFDF2F3F029282B2A51525354",
+ "38393A3B1E1D1C1341404746C23D3C3E",
+ "8D8C939240474645818083827C7F7E41",
+ "3B3A39381A19181F32333C3D45424340",
+ "F0F1F6F738272625828380817F7C7D7A",
+ "89888B8A0407061966676061141B1A19",
+ "D3D2DDDCAAADACAF9C9D9E9FE8EBEAE5",
+ "834EADFCCAC7E1B30664B1ABA44815AB",
+ "D9DC4DBA3021B05D67C0518F72B62BF1",
+ "A291D86301A4A739F7392173AA3C604C",
+ "4264B2696498DE4DF79788A9F83E9390",
+ "EE9932B3721804D5A83EF5949245B6F6",
+ "E6248F55C5FDCBCA9CBBB01C88A2EA77",
+ "B8358E41B9DFF65FD461D55A99266247",
+ "F0E2D72260AF58E21E015AB3A4C0D906",
+ "475B8B823CE8893DB3C44A9F2A379FF7",
+ "688F5281945812862F5F3076CF80412F",
+ "08D1D2BC750AF553365D35E75AFACEAA",
+ "8707121F47CC3EFCECA5F9A8474950A1",
+ "E51AA0B135DBA566939C3B6359A980C5",
+ "069A007FC76A459F98BAF917FEDF9521",
+ "726165C1723FBCF6C026D7D00B091027",
+ "D7C544DE91D55CFCDE1F84CA382200CE",
+ "FED3C9A161B9B5B2BD611B41DC9DA357",
+ "4F634CDC6551043409F30B635832CF82",
+ "109CE98DB0DFB36734D9F3394711B4E6",
+ "4EA6DFABA2D8A02FFDFFA89835987242",
+ "5AE094F54AF58E6E3CDBF976DAC6D9EF",
+ "764D8E8E0F29926DBE5122E66354FDBE",
+ "3F0418F888CDF29A982BF6B75410D6A9",
+ "E4A3E7CB12CDD56AA4A75197A9530220",
+ "211677684AAC1EC1A160F44C4EBF3F26",
+ "D21E439FF749AC8F18D6D4B105E03895",
+ "D9F6FF44646C4725BD4C0103FF5552A7",
+ "0B1256C2A00B976250CFC5B0C37ED382",
+ "B056447FFC6DC4523A36CC2E972A3A79",
+ "5E25CA78F0DE55802524D38DA3FE4456",
+ "A5BCF4728FA5EAAD8567C0DC24675F83",
+ "814E59F97ED84646B78B2CA022E9CA43",
+ "15478BEEC58F4775C7A7F5D4395514D7",
+ "253548FFCA461C67C8CBC78CD59F4756",
+ "FD7AD8D73B9B0F8CC41600640F503D65",
+ "06199DE52C6CBF8AF954CD65830BCD56",
+ "F17C4FFE48E44C61BD891E257E725794",
+ "9A5B4A402A3E8A59BE6BF5CD8154F029",
+ "79BD40B91A7E07DC939D441782AE6B17",
+ "D8CEAAF8976E5FBE1012D8C84F323799",
+ "3316E2751E2E388B083DA23DD6AC3FBE",
+ "8B7CFBE37DE7DCA793521819242C5816",
+ "F23F033C0EEBF8EC55752662FD58CE68",
+ "59EB34F6C8BDBACC5FC6AD73A59A1301",
+ "DCDE8B6BD5CF7CC22D9505E3CE81261A",
+ "E33CF7E524FED781E7042FF9F4B35DC7",
+ "27963C8FACDF73062867D164DF6D064C",
+ "77B1CE386B551B995F2F2A1DA994EEF8",
+ "F083388B013679EFCF0BB9B15D52AE5C",
+ "C5009E0DAB55DB0ABDB636F2600290C8",
+ "7804881E26CD532D8514D3683F00F1B9",
+ "46CDDCD73D1EB53E675CA012870A92A3",
+ "A9FB44062BB07FE130A8E8299EACB1AB",
+ "2B6FF8D7A5CC3A28A22D5A6F221AF26B",
+ "1A9527C29B8ADD4B0E3E656DBB2AF8B4",
+ "7F99CF2C75244DF015EB4B0C1050AEAE",
+ "E84FF85B0D9454071909C1381646C4ED",
+ "89AFD40F99521280D5399B12404F6DB4",
+ "A09EF32DBC5119A35AB7FA38656F0329",
+ "61773457F068C376C7829B93E696E716",
+ "A34F0CAE726CCE41DD498747D891B967",
+ "856F59496C7388EE2D2B1A27B7697847",
+ "CB090C593EF7720BD95908FB93B49DF4",
+ "A0AC75CD2F1923D460FC4D457AD95BAF",
+ "2A2B282974777689E8E9EEEF525D5C5F",
+ "909192939390919E0F0E09089788898A",
+ "777675748D8E8F907170777649464744",
+ "717073720605040B2D2C2B2A05FAFBF9",
+ "64656667FEFDFCC31B1A1D1CA5AAABA8",
+ "DBDAD9D86A696867B5B4B3B2C8D7D6D5",
+ "5C5D5E5FE3E0E1FE31303736333C3D3E",
+ "545556574B48494673727574546B6A69",
+ "ECEDEEEFC6C5C4BB56575051F5FAFBF8",
+ "464744452724252AC9C8CFCED2CDCCCF",
+ "E6E7E4E54142435C878681801C131211",
+ "72737071CFCCCDC2F9F8FFFE710E0F0C",
+ "505152537370714EC3C2C5C4010E0F0C",
+ "A8A9AAAB5C5F5E51AEAFA8A93D222320",
+ "DEDFDCDDF6F5F4EB10111617FEF1F0F3",
+ "BDBCBFBE5E5D5C530B0A0D0CFAC5C4C7",
+ "8A8B8889050606F8F4F5F2F3636C6D6E",
+ "A6A7A4A54D4E4F40B2B3B4B539262724",
+ "9C9D9E9FE9EAEBF40E0F08099B949596",
+ "2D2C2F2E1013121DCCCDCACBED121310",
+ "F4F5F6F7EDEEEFD0EAEBECEDF7F8F9FA",
+ "3D3C3F3E282B2A2573727574150A0B08",
+ "B6B7B4B5F8FBFAE5B4B5B2B3A0AFAEAD",
+ "B7B6B5B4989B9A95878681809BA4A5A6",
+ "A8A9AAABE5E6E798E9E8EFEE4748494A",
+ "ECEDEEEFD9DADBD4B9B8BFBE657A7B78",
+ "7F7E7D7C696A6B74CACBCCCD929D9C9F",
+ "08090A0B0605040BFFFEF9F8B9C6C7C4",
+ "08090A0BF1F2F3CCFCFDFAFB68676665",
+ "CACBC8C93A393837050403020D121310",
+ "E9E8EBEA8281809F8F8E8988343B3A39",
+ "515053524645444BD0D1D6D7340B0A09",
+ "42434041ECEFEE1193929594C6C9C8CB",
+ "EFEEEDECC2C1C0CF76777071455A5B58",
+ "5F5E5D5C3F3C3D221D1C1B1A19161714",
+ "000102034142434C1C1D1A1B8D727371",
+ "8E8F8C8DB1B2B38C56575051050A0B08",
+ "A7A6A5A4E8EBEAE57F7E7978CAD5D4D7",
+ "8A8B888994979689454443429F909192",
+ "8C8D8E8FE0E3E2ED45444342F1CECFCC",
+ "FFFEFDFC4C4F4E31D8D9DEDFB6B9B8BB",
+ "FDFCFFFECCCFCEC12F2E29286679787B",
+ "67666564BAB9B8A77071767719161714",
+ "9A9B98992D2E2F2084858283245B5A59",
+ "A4A5A6A70B0809365C5D5A5B2C232221",
+ "464744455754555AF3F2F5F4AFB0B1B2",
+ "323330317675746B7273747549464744",
+ "A8A9AAAB181B1A15808186872B141516",
+ "E7E6E5E4202323DDAAABACAD343B3A39",
+ "A8A9AAAB2221202FEDECEBEA1E010003",
+ "F9F8FBFA5F5C5D42424344450E010003",
+ "57565554F5F6F7F89697909120DFDEDD",
+ "F8F9FAFBCCCFCEF1DDDCDBDA0E010003",
+ "D9D8DBDA7073727D80818687C2DDDCDF",
+ "C5C4C7C6080B0A1588898E8F68676665",
+ "83828180DCDFDED186878081F0CFCECD",
+ "98999A9BDDDEDFA079787F7E0A050407",
+ "CECFCCCD4F4C4D429F9E9998DFC0C1C2",
+ "404142436665647B29282F2EABA4A5A6",
+ "33323130E6E5E4EB23222524DEA1A0A3",
+ "CFCECDCCF6F5F4CBE6E7E0E199969794",
+ "BABBB8B97271707FDCDDDADB29363734",
+ "C9C8CBCA4447465926272021545B5A59",
+ "050407067477767956575051221D1C1F"];
+
+ var cts:Array = [
+ "D8F532538289EF7D06B506A4FD5BE9C9",
+ "59AB30F4D4EE6E4FF9907EF65B1FB68C",
+ "BF1ED2FCB2AF3FD41443B56D85025CB1",
+ "7316632D5C32233EDCB0780560EAE8B2",
+ "408C073E3E2538072B72625E68B8364B",
+ "E1F94DFA776597BEACA262F2F6366FEA",
+ "F29E986C6A1C27D7B29FFD7EE92B75F1",
+ "131C886A57F8C2E713ABA6955E2B55B5",
+ "D2AB7662DF9B8C740210E5EEB61C199D",
+ "14C10554B2859C484CAB5869BBE7C470",
+ "DB4D498F0A49CF55445D502C1F9AB3B5",
+ "6D96FEF7D66590A77A77BB2056667F7F",
+ "316FB68EDBA736C53E78477BF913725C",
+ "6936F2B93AF8397FD3A771FC011C8C37",
+ "F3F92F7A9C59179C1FCC2C2BA0B082CD",
+ "6A95EA659EE3889158E7A9152FF04EBC",
+ "1959338344E945670678A5D432C90B93",
+ "E49BDDD2369B83EE66E6C75A1161B394",
+ "D3388F19057FF704B70784164A74867D",
+ "23AA03E2D5E4CD24F3217E596480D1E1",
+ "C84113D68B666AB2A50A8BDB222E91B9",
+ "AC02403981CD4340B507963DB65CB7B6",
+ "8D1299236223359474011F6BF5088414",
+ "5A1D6AB8605505F7977E55B9A54D9B90",
+ "72E9C2D519CF555E4208805AABE3B258",
+ "A8F3E81C4A23A39EF4D745DFFE026E80",
+ "546F646449D31458F9EB4EF5483AEE6C",
+ "4DBE4BC84AC797C0EE4EFB7F1A07401C",
+ "25E10BFB411BBD4D625AC8795C8CA3B3",
+ "315637405054EC803614E43DEF177579",
+ "60C5BC8A1410247295C6386C59E572A8",
+ "01366FC8CA52DFE055D6A00A76471BA6",
+ "ECC46595516EC612449C3F581E7D42FF",
+ "6B7FFE4C602A154B06EE9C7DAB5331C9",
+ "7DA234C14039A240DD02DD0FBF84EB67",
+ "C7DC217D9E3604FFE7E91F080ECD5A3A",
+ "37785901863F5C81260EA41E7580CDA5",
+ "A07B9338E92ED105E6AD720FCCCE9FE4",
+ "AE0FB9722418CC21A7DA816BBC61322C",
+ "C826A193080FF91FFB21F71D3373C877",
+ "1181B11B0E494E8D8B0AA6B1D5AC2C48",
+ "6743C3D1519AB4F2CD9A78AB09A511BD",
+ "DC55C076D52BACDF2EEFD952946A439D",
+ "711B17B590FFC72B5C8E342B601E8003",
+ "19983BB0950783A537E1339F4AA21C75",
+ "3BA7762E15554169C0F4FA39164C410C",
+ "A0564C41245AFCA7AF8AA2E0E588EA89",
+ "5E36A42A2E099F54AE85ECD92E2381ED",
+ "770036F878CD0F6CA2268172F106F2FE",
+ "7E4E03908B716116443CCF7C94E7C259",
+ "482735A48C30613A242DD494C7F9185D",
+ "B4C0F6C9D4D7079ADDF9369FC081061D",
+ "D5810FE0509AC53EDCD74F89962E6270",
+ "03F17A16B3F91848269ECDD38EBB2165",
+ "DA1248C3180348BAD4A93B4D9856C9DF",
+ "3D10D7B63F3452C06CDF6CCE18BE0C2C",
+ "4AB823E7477DFDDC0E6789018FCB6258",
+ "E6478BA56A77E70CFDAA5C843ABDE30E",
+ "1673064895FBEAF7F09C5429FF75772D",
+ "4488033AE9F2EFD0CA9383BFCA1A94E9",
+ "978F3B8C8F9D6F46626CAC3C0BCB9217",
+ "E08C8A7E582E15E5527F1D9E2EECB236",
+ "CEC155B76AC5FFDA4CF4F9CA91E49A7A",
+ "D5AC7165763225DD2A38CDC6862C29AD",
+ "03680FE19F7CE7275452020BE70E8204",
+ "461DF740C9781C388E94BB861CEB54F6",
+ "451BD60367F96483042742219786A074",
+ "E4DFA42671A02E57EF173B85C0EA9F2B",
+ "ED11B89E76274282227D854700A78B9E",
+ "433946EAA51EA47AF33895F2B90B3B75",
+ "6BC6D616A5D7D0284A5910AB35022528",
+ "D2A920ECFE919D354B5F49EAE9719C98",
+ "3A061B17F6A92885EFBD0676985B373D",
+ "FADEEC16E33EA2F4688499D157E20D8F",
+ "5CDEFEDE59601AA3C3CDA36FA6B1FA13",
+ "9574B00039844D92EBBA7EE8719265F8",
+ "9A9CF33758671787E5006928188643FA",
+ "2CDDD634C846BA66BB46CBFEA4A674F9",
+ "D28BAE029393C3E7E26E9FAFBBB4B98F",
+ "EC27529B1BEE0A9AB6A0D73EBC82E9B7",
+ "3CB25C09472AFF6EE7E2B47CCD7CCB17",
+ "DEE33103A7283370D725E44CA38F8FE5",
+ "27F9BCD1AAC64BFFC11E7815702C1A69",
+ "5DF534FFAD4ED0749A9988E9849D0021",
+ "A48BEE75DB04FB60CA2B80F752A8421B",
+ "024C8CF70BC86EE5CE03678CB7AF45F9",
+ "3C19AC0F8A3A3862CE577831301E166B",
+ "C5E355B796A57421D59CA6BE82E73BCA",
+ "D94033276417ABFB05A69D15B6E386E2",
+ "24B36559EA3A9B9B958FE6DA3E5B8D85",
+ "20FD4FEAA0E8BF0CCE7861D74EF4CB72",
+ "350E20D5174277B9EC314C501570A11D",
+ "87A29D61B7C604D238FE73045A7EFD57",
+ "2C3164C1CC7D0064816BDC0FAA362C52",
+ "195FE5E8A05A2ED594F6E4400EEE10B3",
+ "E4663DF19B9A21A5A284C2BD7F905025",
+ "21B88714CFB4E2A933BD281A2C4743FD",
+ "CBFC3980D704FD0FC54378AB84E17870",
+ "BC5144BAA48BDEB8B63E22E03DA418EF",
+ "5A1DBAEF1EE2984B8395DA3BDFFA3CCC",
+ "F0B11CD0729DFCC80CEC903D97159574",
+ "9F95314ACFDDC6D1914B7F19A9CC8209",
+ "595736F6F0F70914A94E9E007F022519",
+ "1F19F57892CAE586FCDFB4C694DEB183",
+ "540700EE1F6F3DAB0B3EDDF6CAEE1EF5",
+ "14A342A91019A331687A2254E6626CA2",
+ "7B25F3C3B2EEA18D743EF283140F29FF",
+ "46C2587D66E5E6FA7F7CA6411AD28047",
+ "09470E72229D954ED5EE73886DFEEBA9",
+ "D77C03DE92D4D0D79EF8D4824EF365EB",
+ "1D190219F290E0F1715D152D41A23593",
+ "A2CD332CE3A0818769616292E87F757B",
+ "D54AFA6CE60FBF9341A3690E21385102",
+ "06E5C364DED628A3F5E05E613E356F46",
+ "EAE63C0E62556DAC85D221099896355A",
+ "1FED060E2C6FC93EE764403A889985A2",
+ "C25235C1A30FDEC1C7CB5C5737B2A588",
+ "796DBEF95147D4D30873AD8B7B92EFC0",
+ "CBCF0FB34D98D0BD5C22CE37211A46BF",
+ "94B44DA6466126CAFA7C7FD09063FC24",
+ "D78C5B5EBF9B4DBDA6AE506C5074C8FE",
+ "6C27444C27204B043812CF8CF95F9769",
+ "BE94524EE5A2AA50BBA8B75F4C0AEBCF",
+ "A0AEAAE91BA9F31F51AEB3588CF3A39E",
+ "275297779C28266EF9FE4C6A13C08488",
+ "86523D92BB8672CB01CF4A77FD725882",
+ "4B8327640E9F33322A04DD96FCBF9A36",
+ "CE52AF650D088CA559425223F4D32694",
+ "DFF4945E0336DF4C1C56BC700EFF837F",
+ "B6FDDEF4752765E347D5D2DC196D1252",
+ "D23684E3D963B3AFCF1A114ACA90CBD6",
+ "3A7AC027753E2A18C2CEAB9E17C11FD0",
+ "8F6786BD007528BA26603C1601CDD0D8",
+ "D17D073B01E71502E28B47AB551168B3",
+ "A469DA517119FAB95876F41D06D40FFA",
+ "6091AA3B695C11F5C0B6AD26D3D862FF",
+ "70F9E67F9F8DF1294131662DC6E69364",
+ "D154DCAFAD8B207FA5CBC95E9996B559",
+ "4934D541E8B46FA339C805A7AEB9E5DA",
+ "62564C738F3EFE186E1A127A0C4D3C61",
+ "07805AA043986EB23693E23BEF8F3438",
+ "DF0B4931038BADE848DEE3B4B85AA44B",
+ "592D5FDED76582E4143C65099309477C",
+ "C9B8D6545580D3DFBCDD09B954ED4E92",
+ "5DCCD5D6EB7C1B42ACB008201DF707A0",
+ "A2A91682FFEB6ED1D34340946829E6F9",
+ "E45D185B797000348D9267960A68435D",
+ "45E060DAE5901CDA8089E10D4F4C246B",
+ "F6951AFACC0079A369C71FDCFF45DF50",
+ "9E95E00F351D5B3AC3D0E22E626DDAD6",
+ "9CB566FF26D92DAD083B51FDC18C173C",
+ "C9C82766176A9B228EB9A974A010B4FB",
+ "D8E26AA02945881D5137F1C1E1386E88",
+ "C0E024CCD68FF5FFA4D139C355A77C55",
+ "0B18B3D16F491619DA338640DF391D43",
+ "DBE09AC8F66027BF20CB6E434F252EFC",
+ "6D04E5E43C5B9CBE05FEB9606B6480FE",
+ "DD1D6553B96BE526D9FEE0FBD7176866",
+ "0260CA7E3F979FD015B0DD4690E16D2A",
+ "9893734DE10EDCC8A67C3B110B8B8CC6",
+ "93B30B750516B2D18808D710C2EE84EF",
+ "16F65FA47BE3CB5E6DFE7C6C37016C0E",
+ "F3847210D5391E2360608E5ACB560581",
+ "8754462CD223366D0753913E6AF2643D",
+ "1EA20617468D1B806A1FD58145462017",
+ "3B155D927355D737C6BE9DDA60136E2E",
+ "26144F7B66DAA91B6333DBD3850502B3",
+ "E4F9A4AB52CED8134C649BF319EBCC90",
+ "B9DDD29AC6128A6CAB121E34A4C62B36",
+ "6FCDDAD898F2CE4EFF51294F5EAAF5C9",
+ "C9A6FE2BF4028080BEA6F7FC417BD7E3",
+ "6A2026846D8609D60F298A9C0673127F",
+ "2CB25C005E26EFEA44336C4C97A4240B",
+ "496967AB8680DDD73D09A0E4C7DCC8AA",
+ "D5AF94DE93487D1F3A8C577CB84A66A4",
+ "84BDAC569CAE2828705F267CC8376E90",
+ "F7401DDA5AD5AB712B7EB5D10C6F99B6",
+ "1C9D54318539EBD4C3B5B7E37BF119F0",
+ "ACA572D65FB2764CFFD4A6ECA090EA0D",
+ "36D9C627B8C2A886A10CCB36EAE3DFBB",
+ "010EDBF5981E143A81D646E597A4A568",
+ "8DB44D538DC20CC2F40F3067FD298E60",
+ "930EB53BC71E6AC4B82972BDCD5AAFB3",
+ "6C42A81EDCBC9517CCD89C30C95597B4",
+ "DA389847AD06DF19D76EE119C71E1DD3",
+ "E018FDAE13D3118F9A5D1A647A3F0462",
+ "2AA65DB36264239D3846180FABDFAD20",
+ "1472163E9A4F780F1CEB44B07ECF4FDB",
+ "C8273FDC8F3A9F72E91097614B62397C",
+ "66C8427DCD733AAF7B3470CB7D976E3F",
+ "146131CB17F1424D4F8DA91E6F80C1D0",
+ "2610D0AD83659081AE085266A88770DC",
+ "38A2B5A974B0575C5D733917FB0D4570",
+ "E21D401EBC60DE20D6C486E4F39A588B",
+ "E51D5F88C670B079C0CA1F0C2C4405A2",
+ "246A94788A642FB3D1B823C8762380C8",
+ "B80C391C5C41A4C3B30C68E0E3D7550F",
+ "B77C4754FC64EB9A1154A9AF0BB1F21C",
+ "FB554DE520D159A06BF219FC7F34A02F",
+ "A89FBA152D76B4927BEED160DDB76C57",
+ "5676EAB4A98D2E8473B3F3D46424247C",
+ "4E8F068BD7EDE52A639036EC86C33568",
+ "F0193C4D7AFF1791EE4C07EB4A1824FC",
+ "AC8686EECA9BA761AFE82D67B928C33F",
+ "5FAF8573E33B145B6A369CD3606AB2C9",
+ "31587E9944AB1C16B844ECAD0DF2E7DA",
+ "D017FECD91148ABA37F6F3068AA67D8A",
+ "788EF2F021A73CBA2794B616078A8500",
+ "5D1EF20DCED6BCBC12131AC7C54788AA",
+ "B3C8CF961FAF9EA05FDDE6D1E4D8F663",
+ "143075C70605861C7FAC6526199E459F",
+ "A5AE12EADE9A87268D898BFC8FC0252A",
+ "0924F7CF2E877A4819F5244A360DCEA9",
+ "3D9E9635AFCC3E291CC7AB3F27D1C99A",
+ "9D80FEEBF87510E2B8FB98BB54FD788C",
+ "5F9D1A082A1A37985F174002ECA01309",
+ "A390EBB1D1403930184A44B4876646E4",
+ "700FE918981C3195BB6C4BCB46B74E29",
+ "907984406F7BF2D17FB1EB15B673D747",
+ "C32A956DCFC875C2AC7C7CC8B8CC26E1",
+ "02646E2EBFA9B820CF8424E9B9B6EB51",
+ "621FDA3A5BBD54C6D3C685816BD4EAD8",
+ "D4E216040426DFAF18B152469BC5AC2F",
+ "9D0635B9D33B6CDBD71F5D246EA17CC8",
+ "10ABAD1BD9BAE5448808765583A2CC1A",
+ "6891889E16544E355FF65A793C39C9A8",
+ "CC735582E68072C163CD9DDF46B91279",
+ "C5C68B9AEEB7F878DF578EFA562F9574",
+ "5F4764395A667A47D73452955D0D2CE8",
+ "701448331F66106CEFDDF1EB8267C357",
+ "CB3EE56D2E14B4E1941666F13379D657",
+ "9FE16EFD18AB6E1981191851FEDB0764",
+ "3DC9BA24E1B223589B147ADCEB4C8E48",
+ "1C333032682E7D4DE5E5AFC05C3E483C",
+ "D593CC99A95AFEF7E92038E05A59D00A",
+ "51E7F96F53B4353923452C222134E1EC",
+ "4075B357A1A2B473400C3B25F32F81A4",
+ "302E341A3EBCD74F0D55F61714570284",
+ "57ABDD8231280DA01C5042B78CF76522",
+ "17F9EA7EEA17AC1ADF0E190FEF799E92",
+ "2E1BDD563DD87EE5C338DD6D098D0A7A",
+ "EB869996E6F8BFB2BFDD9E0C4504DBB2",
+ "C2E01549E9DECF317468B3E018C61BA8",
+ "8DA875D033C01DD463B244A1770F4A22",
+ "8BA0DCF3A186844F026D022F8839D696",
+ "E9691FF9A6CC6970E51670A0FD5B88C1",
+ "F2BAEC06FAEED30F88EE63BA081A6E5B",
+ "9C39D4C459AE5753394D6094ADC21E78",
+ "6345B532A11904502EA43BA99C6BD2B2",
+ "5FFAE3061A95172E4070CEDCE1E428C8",
+ "0A4566BE4CDF9ADCE5DEC865B5AB34CD",
+ "CA17FCCE79B7404F2559B22928F126FB",
+ "97CA39B849ED73A6470A97C821D82F58",
+ "8198CB06BC684C6D3E9B7989428DCF7A",
+ "F53C464C705EE0F28D9A4C59374928BD",
+ "9ADB3D4CCA559BB98C3E2ED73DBF1154",
+ "1946DABF6A03A2A2C3D0B05080AED6FC",
+ "5ED301D747D3CC715445EBDEC62F2FB4",
+ "6585C8F43D13A6BEAB6419FC5935B9D0",
+ "2A5B56A596680FCC0E05F5E0F151ECAE",
+ "F5D6FF414FD2C6181494D20C37F2B8C4",
+ "85399C01F59FFFB5204F19F8482F00B8",
+ "92097B4C88A041DDF98144BC8D22E8E7",
+ "89BD5B73B356AB412AEF9F76CEA2D65C",
+ "2536969093C55FF9454692F2FAC2F530",
+ "07FC76A872843F3F6E0081EE9396D637",
+ "E38BA8EC2AA741358DCC93E8F141C491",
+ "D028EE23E4A89075D0B03E868D7D3A42",
+ "8CD9423DFC459E547155C5D1D522E540",
+ "080E9517EB1677719ACF728086040AE3",
+ "7C1700211A3991FC0ECDED0AB3E576B0",
+ "DABCBCC855839251DB51E224FBE87435",
+ "68D56FAD0406947A4DD27A7448C10F1D",
+ "DA9A11479844D1FFEE24BBF3719A9925",
+ "5E4BA572F8D23E738DA9B05BA24B8D81",
+ "A115A2065D667E3F0B883837A6E903F8",
+ "3E9E90DC33EAC2437D86AD30B137E66E",
+ "01CE82D8FBCDAE824CB3C48E495C3692",
+ "0C9CFF163CE936FAAF083CFD3DEA3117",
+ "5131BA9BD48F2BBA85560680DF504B52",
+ "9DC503BBF09823AEC8A977A5AD26CCB2",
+ "9A6DB0C0862E506A9E397225884041D7",
+ "430BF9570804185E1AB6365FC6A6860C",
+ "3525EBC02F4886E6A5A3762813E8CE8A",
+ "07FA265C763779CCE224C7BAD671027B",
+ "E8B72B4E8BE243438C9FFF1F0E205872",
+ "109D4F999A0E11ACE1F05E6B22CBCB50",
+ "45A5E8D4C3ED58403FF08D68A0CC4029",
+ "196865964DB3D417B6BD4D586BCB7634",
+ "60436AD45AC7D30D99195F815D98D2AE",
+ "BB07A23F0B61014B197620C185E2CD75",
+ "5BC0B2850129C854423AFF0751FE343B",
+ "7541A78F96738E6417D2A24BD2BECA40",
+ "B0A303054412882E464591F1546C5B9E",
+ "778C06D8A355EEEE214FCEA14B4E0EEF",
+ "09614206D15CBACE63227D06DB6BEEBB",
+ "41B97FB20E427A9FDBBB358D9262255D",
+ "C1940F703D845F957652C2D64ABD7ADF",
+ "D2D44FCDAE5332343366DB297EFCF21B",
+ "EA8196B79DBE167B6AA9896E287EED2B",
+ "D6B0B0C4BA6C7DBE5ED467A1E3F06C2D",
+ "EC51EB295250C22C2FB01816FB72BCAE",
+ "ADED6630A07CE9C7408A155D3BD0D36F",
+ "697C9245B9937F32F5D1C82319F0363A",
+ "AAD5AD50C6262AAEC30541A1B7B5B19C",
+ "7D34B893855341EC625BD6875AC18C0D",
+ "7EF05105440F83862F5D780E88F02B41",
+ "C377C06403382061AF2C9C93A8E70DF6",
+ "1DBDB3FFDC052DACC83318853ABC6DE5",
+ "69A6EAB00432517D0BF483C91C0963C7",
+ "0797F41DC217C80446E1D514BD6AB197",
+ "9DFD76575902A637C01343C58E011A03",
+ "ACF4328AE78F34B9FA9B459747CC2658",
+ "B0479AEA12BAC4FE2384CF98995150C6",
+ "9DD52789EFE3FFB99F33B3DA5030109A",
+ "ABBB755E4621EF8F1214C19F649FB9FD",
+ "DA27FB8174357BCE2BED0E7354F380F9",
+ "C59A0663F0993838F6E5856593BDC5EF",
+ "ED60B264B5213E831607A99C0CE5E57E",
+ "E50548746846F3EB77B8C520640884ED",
+ "28282CC7D21D6A2923641E52D188EF0C",
+ "0DFA5B02ABB18E5A815305216D6D4F8E",
+ "7359635C0EECEFE31D673395FB46FB99",
+ "73C679F7D5AEF2745C9737BB4C47FB36",
+ "B192BD472A4D2EAFB786E97458967626",
+ "0EC327F6C8A2B147598CA3FDE61DC6A4",
+ "FC418EB3C41B859B38D4B6F646629729",
+ "30249E5AC282B1C981EA64B609F3A154",
+ "5E6E08646D12150776BB43C2D78A9703",
+ "FAEB3D5DE652CD3447DCEB343F30394A",
+ "A8E88706823F6993EF80D05C1C7B2CF0",
+ "8CED86677E6E00A1A1B15968F2D3CCE6",
+ "9FC7C23858BE03BDEBB84E90DB6786A9",
+ "B4FBD65B33F70D8CF7F1111AC4649C36",
+ "C5C32D5ED03C4B53CC8C1BD0EF0DBBF6",
+ "D1A7F03B773E5C212464B63709C6A891",
+ "6B7161D8745947AC6950438EA138D028",
+ "FD47A9F7E366EE7A09BC508B00460661",
+ "00D40B003DC3A0D9310B659B98C7E416",
+ "EEA4C79DCC8E2BDA691F20AC48BE0717",
+ "E78F43B11C204403E5751F89D05A2509",
+ "D0F0E3D1F1244BB979931E38DD1786EF",
+ "042E639DC4E1E4DDE7B75B749EA6F765",
+ "BC032FDD0EFE29503A980A7D07AB46A8",
+ "0C93AC949C0DA6446EFFB86183B6C910",
+ "E0D343E14DA75C917B4A5CEC4810D7C2",
+ "0EAFB821748408279B937B626792E619",
+ "FA1AC6E02D23B106A1FEF18B274A553F",
+ "0DADFE019CD12368075507DF33C1A1E9",
+ "3A0879B414465D9FFBAF86B33A63A1B9",
+ "62199FADC76D0BE1805D3BA0B7D914BF",
+ "1B06D6C5D333E742730130CF78E719B4",
+ "F1F848824C32E9DCDCBF21580F069329",
+ "1A09050CBD684F784D8E965E0782F28A",
+ "79C2969E7DED2BA7D088F3F320692360",
+ "091A658A2F7444C16ACCB669450C7B63",
+ "97C1E3A72CCA65FA977D5ED0E8A7BBFC",
+ "70C430C6DB9A17828937305A2DF91A2A",
+ "629553457FBE2479098571C7C903FDE8",
+ "A25B25A61F612669E7D91265C7D476BA",
+ "EB7E4E49B8AE0F024570DDA293254FED",
+ "38FE15D61CCA84516E924ADCE5014F67",
+ "3AD208492249108C9F3EBEB167AD0583",
+ "299BA9F9BF5AB05C3580FC26EDD1ED12",
+ "19DC705B857A60FB07717B2EA5717781",
+ "FFC8AEB885B5EFCAD06B6DBEBF92E76B",
+ "F58900C5E0B385253FF2546250A0142B",
+ "2EE67B56280BC462429CEE6E3370CBC1",
+ "20DB650A9C8E9A84AB4D25F7EDC8F03F",
+ "3C36DA169525CF818843805F25B78AE5",
+ "9A781D960DB9E45E37779042FEA51922",
+ "6560395EC269C672A3C288226EFDBA77",
+ "8C772B7A189AC544453D5916EBB27B9A",
+ "77CA5468CC48E843D05F78EED9D6578F",
+ "72CDCC71DC82C60D4429C9E2D8195BAA",
+ "8080D68CE60E94B40B5B8B69EEB35AFA",
+ "44222D3CDE299C04369D58AC0EBA1E8E",
+ "9B8721B0A8DFC691C5BC5885DBFCB27A",
+ "0DC015CE9A3A3414B5E62EC643384183",
+ "705715448A8DA412025CE38345C2A148",
+ "C32B5B0B6FBAE165266C569F4B6ECF0B",
+ "4DCA6C75192A01DDCA9476AF2A521E87",
+ "058691E627ECBC36AC07B6DB423BD698",
+ "7444527095838FE080FC2BCDD30847EB"];
+
+ for (var i:uint=0;i<keys.length;i++) {
+ var key:ByteArray = Hex.toArray(keys[i]);
+ var pt:ByteArray = Hex.toArray(pts[i]);
+ var aes:AESKey = new AESKey(key);
+ aes.encrypt(pt);
+ var out:String = Hex.fromArray(pt).toUpperCase();
+ assert("comparing "+cts[i]+" to "+out, cts[i]==out);
+ // now go back to plaintext.
+ aes.decrypt(pt);
+ out = Hex.fromArray(pt).toUpperCase();
+ assert("comparing "+pts[i]+" to "+out, pts[i]==out);
+ }
+ }
+
+
+ }
+}
\ No newline at end of file diff --git a/flash-src/third-party/com/hurlant/crypto/tests/ARC4Test.as b/flash-src/third-party/com/hurlant/crypto/tests/ARC4Test.as new file mode 100755 index 0000000..94683c3 --- /dev/null +++ b/flash-src/third-party/com/hurlant/crypto/tests/ARC4Test.as @@ -0,0 +1,58 @@ +/**
+ * ARC4Test
+ *
+ * A test class for ARC4
+ * Copyright (c) 2007 Henri Torgemane
+ *
+ * See LICENSE.txt for full license information.
+ */
+package com.hurlant.crypto.tests
+{
+ import com.hurlant.util.Hex;
+ import flash.utils.ByteArray;
+ import com.hurlant.crypto.prng.ARC4;
+
+ public class ARC4Test extends TestCase
+ {
+ public function ARC4Test(h:ITestHarness)
+ {
+ super(h, "ARC4 Test");
+ runTest(testLameVectors,"ARC4 Test Vectors");
+ h.endTestCase();
+ }
+
+ /**
+ * Sad test vectors pilfered from
+ * http://en.wikipedia.org/wiki/RC4
+ */
+ public function testLameVectors():void {
+ var keys:Array = [
+ Hex.fromString("Key"),
+ Hex.fromString("Wiki"),
+ Hex.fromString("Secret")];
+ var pts:Array = [
+ Hex.fromString("Plaintext"),
+ Hex.fromString("pedia"),
+ Hex.fromString("Attack at dawn")];
+ var cts:Array = [
+ "BBF316E8D940AF0AD3",
+ "1021BF0420",
+ "45A01F645FC35B383552544B9BF5"];
+
+ for (var i:uint=0;i<keys.length;i++) {
+ var key:ByteArray = Hex.toArray(keys[i]);
+ var pt:ByteArray = Hex.toArray(pts[i]);
+ var rc4:ARC4 = new ARC4(key);
+ rc4.encrypt(pt);
+ var out:String = Hex.fromArray(pt).toUpperCase();
+ assert("comparing "+cts[i]+" to "+out, cts[i]==out);
+ // now go back to plaintext
+ rc4.init(key);
+ rc4.decrypt(pt);
+ out = Hex.fromArray(pt);
+ assert("comparing "+pts[i]+" to "+out, pts[i]==out);
+ }
+ }
+
+ }
+}
\ No newline at end of file diff --git a/flash-src/third-party/com/hurlant/crypto/tests/BigIntegerTest.as b/flash-src/third-party/com/hurlant/crypto/tests/BigIntegerTest.as new file mode 100755 index 0000000..ac6a4ee --- /dev/null +++ b/flash-src/third-party/com/hurlant/crypto/tests/BigIntegerTest.as @@ -0,0 +1,39 @@ +/**
+ * BigIntegerTest
+ *
+ * A test class for BigInteger
+ * Copyright (c) 2007 Henri Torgemane
+ *
+ * See LICENSE.txt for full license information.
+ */
+package com.hurlant.crypto.tests
+{
+ import com.hurlant.math.BigInteger;
+ import com.hurlant.util.Hex;
+
+ public class BigIntegerTest extends TestCase
+ {
+ public function BigIntegerTest(h:ITestHarness)
+ {
+ super(h, "BigInteger Tests");
+ runTest(testAdd, "BigInteger Addition");
+ h.endTestCase();
+ }
+
+ public function testAdd():void {
+ var n1:BigInteger = BigInteger.nbv(25);
+ var n2:BigInteger = BigInteger.nbv(1002);
+ var n3:BigInteger = n1.add(n2);
+ var v:int = n3.valueOf();
+ assert("25+1002 = "+v, 25+1002==v);
+
+ var p:BigInteger = new BigInteger(Hex.toArray("e564d8b801a61f47"));
+ var xp:BigInteger = new BigInteger(Hex.toArray("99246db2a3507fa"));
+
+ xp = xp.add(p);
+
+ assert("xp==eef71f932bdb2741", xp.toString(16)=="eef71f932bdb2741");
+ }
+
+ }
+}
\ No newline at end of file diff --git a/flash-src/third-party/com/hurlant/crypto/tests/BlowFishKeyTest.as b/flash-src/third-party/com/hurlant/crypto/tests/BlowFishKeyTest.as new file mode 100755 index 0000000..96645fb --- /dev/null +++ b/flash-src/third-party/com/hurlant/crypto/tests/BlowFishKeyTest.as @@ -0,0 +1,148 @@ +/**
+ * BlowFishKeyTest
+ *
+ * A test class for BlowFishKey
+ * Copyright (c) 2007 Henri Torgemane
+ *
+ * See LICENSE.txt for full license information.
+ */
+package com.hurlant.crypto.tests
+{
+ import com.hurlant.crypto.symmetric.BlowFishKey;
+ import com.hurlant.util.Hex;
+ import flash.utils.ByteArray;
+
+ public class BlowFishKeyTest extends TestCase
+ {
+ public function BlowFishKeyTest(h:ITestHarness)
+ {
+ super(h, "BlowFishKey Test");
+ runTest(testECB,"BlowFish ECB Test Vectors");
+ h.endTestCase();
+ }
+
+ /**
+ * Test vectors from http://www.schneier.com/code/vectors.txt
+ */
+ public function testECB():void {
+ var keys:Array = [
+ "0000000000000000",
+ "FFFFFFFFFFFFFFFF",
+ "3000000000000000",
+ "1111111111111111",
+ "0123456789ABCDEF",
+ "1111111111111111",
+ "0000000000000000",
+ "FEDCBA9876543210",
+ "7CA110454A1A6E57",
+ "0131D9619DC1376E",
+ "07A1133E4A0B2686",
+ "3849674C2602319E",
+ "04B915BA43FEB5B6",
+ "0113B970FD34F2CE",
+ "0170F175468FB5E6",
+ "43297FAD38E373FE",
+ "07A7137045DA2A16",
+ "04689104C2FD3B2F",
+ "37D06BB516CB7546",
+ "1F08260D1AC2465E",
+ "584023641ABA6176",
+ "025816164629B007",
+ "49793EBC79B3258F",
+ "4FB05E1515AB73A7",
+ "49E95D6D4CA229BF",
+ "018310DC409B26D6",
+ "1C587F1C13924FEF",
+ "0101010101010101",
+ "1F1F1F1F0E0E0E0E",
+ "E0FEE0FEF1FEF1FE",
+ "0000000000000000",
+ "FFFFFFFFFFFFFFFF",
+ "0123456789ABCDEF",
+ "FEDCBA9876543210" ];
+ var pts:Array = [
+ "0000000000000000",
+ "FFFFFFFFFFFFFFFF",
+ "1000000000000001",
+ "1111111111111111",
+ "1111111111111111",
+ "0123456789ABCDEF",
+ "0000000000000000",
+ "0123456789ABCDEF",
+ "01A1D6D039776742",
+ "5CD54CA83DEF57DA",
+ "0248D43806F67172",
+ "51454B582DDF440A",
+ "42FD443059577FA2",
+ "059B5E0851CF143A",
+ "0756D8E0774761D2",
+ "762514B829BF486A",
+ "3BDD119049372802",
+ "26955F6835AF609A",
+ "164D5E404F275232",
+ "6B056E18759F5CCA",
+ "004BD6EF09176062",
+ "480D39006EE762F2",
+ "437540C8698F3CFA",
+ "072D43A077075292",
+ "02FE55778117F12A",
+ "1D9D5C5018F728C2",
+ "305532286D6F295A",
+ "0123456789ABCDEF",
+ "0123456789ABCDEF",
+ "0123456789ABCDEF",
+ "FFFFFFFFFFFFFFFF",
+ "0000000000000000",
+ "0000000000000000",
+ "FFFFFFFFFFFFFFFF" ];
+ var cts:Array = [
+ "4EF997456198DD78",
+ "51866FD5B85ECB8A",
+ "7D856F9A613063F2",
+ "2466DD878B963C9D",
+ "61F9C3802281B096",
+ "7D0CC630AFDA1EC7",
+ "4EF997456198DD78",
+ "0ACEAB0FC6A0A28D",
+ "59C68245EB05282B",
+ "B1B8CC0B250F09A0",
+ "1730E5778BEA1DA4",
+ "A25E7856CF2651EB",
+ "353882B109CE8F1A",
+ "48F4D0884C379918",
+ "432193B78951FC98",
+ "13F04154D69D1AE5",
+ "2EEDDA93FFD39C79",
+ "D887E0393C2DA6E3",
+ "5F99D04F5B163969",
+ "4A057A3B24D3977B",
+ "452031C1E4FADA8E",
+ "7555AE39F59B87BD",
+ "53C55F9CB49FC019",
+ "7A8E7BFA937E89A3",
+ "CF9C5D7A4986ADB5",
+ "D1ABB290658BC778",
+ "55CB3774D13EF201",
+ "FA34EC4847B268B2",
+ "A790795108EA3CAE",
+ "C39E072D9FAC631D",
+ "014933E0CDAFF6E4",
+ "F21E9A77B71C49BC",
+ "245946885754369A",
+ "6B5C5A9C5D9E0A5A" ];
+
+ for (var i:uint=0;i<keys.length;i++) {
+ var key:ByteArray = Hex.toArray(keys[i]);
+ var pt:ByteArray = Hex.toArray(pts[i]);
+ var bf:BlowFishKey = new BlowFishKey(key);
+ bf.encrypt(pt);
+ var out:String = Hex.fromArray(pt).toUpperCase();
+ assert("comparing "+cts[i]+" to "+out, cts[i]==out);
+ // now go back to plaintext
+ bf.decrypt(pt);
+ out = Hex.fromArray(pt).toUpperCase();
+ assert("comparing "+pts[i]+" to "+out, pts[i]==out);
+ }
+ }
+ }
+}
\ No newline at end of file diff --git a/flash-src/third-party/com/hurlant/crypto/tests/CBCModeTest.as b/flash-src/third-party/com/hurlant/crypto/tests/CBCModeTest.as new file mode 100755 index 0000000..153aa00 --- /dev/null +++ b/flash-src/third-party/com/hurlant/crypto/tests/CBCModeTest.as @@ -0,0 +1,160 @@ +/**
+ * CBCModeTest
+ *
+ * A test class for CBCMode
+ * Copyright (c) 2007 Henri Torgemane
+ *
+ * See LICENSE.txt for full license information.
+ */
+package com.hurlant.crypto.tests
+{
+ import com.hurlant.crypto.symmetric.AESKey;
+ import com.hurlant.crypto.symmetric.CBCMode;
+ import com.hurlant.crypto.symmetric.NullPad;
+ import com.hurlant.crypto.symmetric.XTeaKey;
+ import com.hurlant.util.Hex;
+
+ import flash.utils.ByteArray;
+
+ public class CBCModeTest extends TestCase
+ {
+ public function CBCModeTest(h:ITestHarness) {
+ super(h, "CBCMode Test");
+ runTest(testAES,"CBC AES Test Vectors");
+ runTest(testXTea,"CBC XTea Test Vectors");
+ //
+ runTest(testCBC_AES128, "CBC AES-128 Test Vectors");
+ runTest(testCBC_AES192, "CBC AES-192 Test Vectors");
+ runTest(testCBC_AES256, "CBC AES-256 Test Vectors");
+ h.endTestCase();
+ }
+
+ /**
+ * Hawt NIST Vectors: http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
+ * Section F.2.1 and below.
+ */
+ public function testCBC_AES128():void {
+ var key:ByteArray = Hex.toArray("2b7e151628aed2a6abf7158809cf4f3c");
+ var pt:ByteArray = Hex.toArray(
+ "6bc1bee22e409f96e93d7e117393172a" +
+ "ae2d8a571e03ac9c9eb76fac45af8e51" +
+ "30c81c46a35ce411e5fbc1191a0a52ef" +
+ "f69f2445df4f9b17ad2b417be66c3710");
+ var ct:ByteArray = Hex.toArray(
+ "7649abac8119b246cee98e9b12e9197d" +
+ "5086cb9b507219ee95db113a917678b2" +
+ "73bed6b8e3c1743b7116e69e22229516" +
+ "3ff1caa1681fac09120eca307586e1a7");
+ var cbc:CBCMode = new CBCMode(new AESKey(key), new NullPad);
+ cbc.IV = Hex.toArray("000102030405060708090a0b0c0d0e0f");
+ var src:ByteArray = new ByteArray;
+ src.writeBytes(pt);
+ cbc.encrypt(src);
+ assert("CBC_AES128 test 1", Hex.fromArray(src)==Hex.fromArray(ct));
+ cbc.decrypt(src);
+ assert("CBC_AES128 test 2", Hex.fromArray(src)==Hex.fromArray(pt));
+ }
+ public function testCBC_AES192():void {
+ var key:ByteArray = Hex.toArray("8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b");
+ var pt:ByteArray = Hex.toArray(
+ "6bc1bee22e409f96e93d7e117393172a" +
+ "ae2d8a571e03ac9c9eb76fac45af8e51" +
+ "30c81c46a35ce411e5fbc1191a0a52ef" +
+ "f69f2445df4f9b17ad2b417be66c3710");
+ var ct:ByteArray = Hex.toArray(
+ "4f021db243bc633d7178183a9fa071e8" +
+ "b4d9ada9ad7dedf4e5e738763f69145a" +
+ "571b242012fb7ae07fa9baac3df102e0" +
+ "08b0e27988598881d920a9e64f5615cd");
+ var cbc:CBCMode = new CBCMode(new AESKey(key), new NullPad);
+ cbc.IV = Hex.toArray("000102030405060708090a0b0c0d0e0f");
+ var src:ByteArray = new ByteArray;
+ src.writeBytes(pt);
+ cbc.encrypt(src);
+ assert("CBC_AES192 test 1", Hex.fromArray(src)==Hex.fromArray(ct));
+ cbc.decrypt(src);
+ assert("CBC_AES192 test 2", Hex.fromArray(src)==Hex.fromArray(pt));
+ }
+ public function testCBC_AES256():void {
+ var key:ByteArray = Hex.toArray(
+ "603deb1015ca71be2b73aef0857d7781" +
+ "1f352c073b6108d72d9810a30914dff4");
+ var pt:ByteArray = Hex.toArray(
+ "6bc1bee22e409f96e93d7e117393172a" +
+ "ae2d8a571e03ac9c9eb76fac45af8e51" +
+ "30c81c46a35ce411e5fbc1191a0a52ef" +
+ "f69f2445df4f9b17ad2b417be66c3710");
+ var ct:ByteArray = Hex.toArray(
+ "f58c4c04d6e5f1ba779eabfb5f7bfbd6" +
+ "9cfc4e967edb808d679f777bc6702c7d" +
+ "39f23369a9d9bacfa530e26304231461" +
+ "b2eb05e2c39be9fcda6c19078c6a9d1b");
+ var cbc:CBCMode = new CBCMode(new AESKey(key), new NullPad);
+ cbc.IV = Hex.toArray("000102030405060708090a0b0c0d0e0f");
+ var src:ByteArray = new ByteArray;
+ src.writeBytes(pt);
+ cbc.encrypt(src);
+ assert("CBC_AES256 test 1", Hex.fromArray(src)==Hex.fromArray(ct));
+ cbc.decrypt(src);
+ assert("CBC_AES256 test 2", Hex.fromArray(src)==Hex.fromArray(pt));
+ }
+
+
+ /**
+ * For now the main goal is to show we can decrypt what we encrypt in this mode.
+ * Eventually, this should get correlated with some well known vectors.
+ */
+ public function testAES():void {
+ var keys:Array = [
+ "00010203050607080A0B0C0D0F101112",
+ "14151617191A1B1C1E1F202123242526"];
+ var cts:Array = [
+ "D8F532538289EF7D06B506A4FD5BE9C94894C5508A8D8E29AB600DB0261F0555A8FA287B89E65C0973F1F8283E70C72863FE1C8F1F782084CE05626E961A67B3",
+ "59AB30F4D4EE6E4FF9907EF65B1FB68C96890CE217689B1BE0C93ED51CF21BB5A0101A8C30714EC4F52DBC9C6F4126067D363F67ABE58463005E679B68F0B496"];
+ var pts:Array = [
+ "506812A45F08C889B97F5980038B8359506812A45F08C889B97F5980038B8359506812A45F08C889B97F5980038B8359",
+ "5C6D71CA30DE8B8B00549984D2EC7D4B5C6D71CA30DE8B8B00549984D2EC7D4B5C6D71CA30DE8B8B00549984D2EC7D4B"];
+
+ for (var i:uint=0;i<keys.length;i++) {
+ var key:ByteArray = Hex.toArray(keys[i]);
+ var pt:ByteArray = Hex.toArray(pts[i]);
+ var aes:AESKey = new AESKey(key);
+ var cbc:CBCMode = new CBCMode(aes);
+ cbc.IV = Hex.toArray("00000000000000000000000000000000");
+ cbc.encrypt(pt);
+ var str:String = Hex.fromArray(pt).toUpperCase();
+ assert("comparing "+cts[i]+" to "+str, cts[i]==str);
+ // back to pt
+ cbc.decrypt(pt);
+ str = Hex.fromArray(pt).toUpperCase();
+ assert("comparing "+pts[i]+" to "+str, pts[i]==str);
+ }
+ }
+ public function testXTea():void {
+ var keys:Array=[
+ "00000000000000000000000000000000",
+ "2b02056806144976775d0e266c287843"];
+ var cts:Array = [
+ "2dc7e8d3695b0538d8f1640d46dca717790af2ab545e11f3b08e798eb3f17b1744299d4d20b534aa",
+ "790958213819878370eb8251ffdac371081c5a457fc42502c63910306fea150be8674c3b8e675516"];
+ var pts:Array=[
+ "0000000000000000000000000000000000000000000000000000000000000000",
+ "74657374206d652e74657374206d652e74657374206d652e74657374206d652e"];
+
+ for (var i:uint=0;i<keys.length;i++) {
+ var key:ByteArray = Hex.toArray(keys[i]);
+ var pt:ByteArray = Hex.toArray(pts[i]);
+ var tea:XTeaKey = new XTeaKey(key);
+ var cbc:CBCMode = new CBCMode(tea);
+ cbc.IV = Hex.toArray("0000000000000000");
+ cbc.encrypt(pt);
+ var str:String = Hex.fromArray(pt);
+ assert("comparing "+cts[i]+" to "+str, cts[i]==str);
+ // now go back to plaintext.
+ cbc.decrypt(pt);
+ str = Hex.fromArray(pt);
+ assert("comparing "+pts[i]+" to "+str, pts[i]==str);
+ }
+ }
+ }
+}
\ No newline at end of file diff --git a/flash-src/third-party/com/hurlant/crypto/tests/CFB8ModeTest.as b/flash-src/third-party/com/hurlant/crypto/tests/CFB8ModeTest.as new file mode 100755 index 0000000..481277f --- /dev/null +++ b/flash-src/third-party/com/hurlant/crypto/tests/CFB8ModeTest.as @@ -0,0 +1,71 @@ +/**
+ * CFB8ModeTest
+ *
+ * A test class for CFB8Mode
+ * Copyright (c) 2007 Henri Torgemane
+ *
+ * See LICENSE.txt for full license information.
+ */
+package com.hurlant.crypto.tests
+{
+ import flash.utils.ByteArray;
+ import com.hurlant.util.Hex;
+ import com.hurlant.crypto.symmetric.CFB8Mode;
+ import com.hurlant.crypto.symmetric.AESKey;
+ import com.hurlant.crypto.symmetric.NullPad;
+
+ public class CFB8ModeTest extends TestCase
+ {
+ public function CFB8ModeTest(h:ITestHarness) {
+ super(h,"CBF8Mode Test");
+ runTest(testCFB8_AES128, "CFB-8 AES-128 Test Vectors");
+ runTest(testCFB8_AES192, "CFB-8 AES-192 Test Vectors");
+ runTest(testCFB8_AES256, "CFB-8 AES-192 Test Vectors");
+ h.endTestCase();
+ }
+
+ /**
+ * http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
+ */
+ public function testCFB8_AES128():void {
+ var key:ByteArray = Hex.toArray("2b7e151628aed2a6abf7158809cf4f3c");
+ var pt:ByteArray = Hex.toArray("6bc1bee22e409f96e93d7e117393172aae2d");
+ var ct:ByteArray = Hex.toArray("3b79424c9c0dd436bace9e0ed4586a4f32b9");
+ var cfb8:CFB8Mode = new CFB8Mode(new AESKey(key), new NullPad);
+ cfb8.IV = Hex.toArray("000102030405060708090a0b0c0d0e0f");
+ var src:ByteArray = new ByteArray;
+ src.writeBytes(pt);
+ cfb8.encrypt(src);
+ assert("CFB8_AES128 test 1", Hex.fromArray(src)==Hex.fromArray(ct));
+ cfb8.decrypt(src);
+ assert("CFB8_AES128 test 2", Hex.fromArray(src)==Hex.fromArray(pt));
+ }
+ public function testCFB8_AES192():void {
+ var key:ByteArray = Hex.toArray("8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b");
+ var pt:ByteArray = Hex.toArray("6bc1bee22e409f96e93d7e117393172aae2d");
+ var ct:ByteArray = Hex.toArray("cda2521ef0a905ca44cd057cbf0d47a0678a");
+ var cfb8:CFB8Mode = new CFB8Mode(new AESKey(key), new NullPad);
+ cfb8.IV = Hex.toArray("000102030405060708090a0b0c0d0e0f");
+ var src:ByteArray = new ByteArray;
+ src.writeBytes(pt);
+ cfb8.encrypt(src);
+ assert("CFB8_AES128 test 1", Hex.fromArray(src)==Hex.fromArray(ct));
+ cfb8.decrypt(src);
+ assert("CFB8_AES128 test 2", Hex.fromArray(src)==Hex.fromArray(pt));
+ }
+ public function testCFB8_AES256():void {
+ var key:ByteArray = Hex.toArray("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4");
+ var pt:ByteArray = Hex.toArray("6bc1bee22e409f96e93d7e117393172aae2d");
+ var ct:ByteArray = Hex.toArray("dc1f1a8520a64db55fcc8ac554844e889700");
+ var cfb8:CFB8Mode = new CFB8Mode(new AESKey(key), new NullPad);
+ cfb8.IV = Hex.toArray("000102030405060708090a0b0c0d0e0f");
+ var src:ByteArray = new ByteArray;
+ src.writeBytes(pt);
+ cfb8.encrypt(src);
+ assert("CFB8_AES128 test 1", Hex.fromArray(src)==Hex.fromArray(ct));
+ cfb8.decrypt(src);
+ assert("CFB8_AES128 test 2", Hex.fromArray(src)==Hex.fromArray(pt));
+ }
+
+ }
+}
\ No newline at end of file diff --git a/flash-src/third-party/com/hurlant/crypto/tests/CFBModeTest.as b/flash-src/third-party/com/hurlant/crypto/tests/CFBModeTest.as new file mode 100755 index 0000000..9d63fe0 --- /dev/null +++ b/flash-src/third-party/com/hurlant/crypto/tests/CFBModeTest.as @@ -0,0 +1,98 @@ +/**
+ * CFBModeTest
+ *
+ * A test class for CFBMode
+ * Copyright (c) 2007 Henri Torgemane
+ *
+ * See LICENSE.txt for full license information.
+ */
+package com.hurlant.crypto.tests
+{
+ import com.hurlant.crypto.symmetric.AESKey;
+ import com.hurlant.crypto.symmetric.CFBMode;
+ import com.hurlant.crypto.symmetric.NullPad;
+ import com.hurlant.util.Hex;
+
+ import flash.utils.ByteArray;
+
+ public class CFBModeTest extends TestCase
+ {
+ public function CFBModeTest(h:ITestHarness)
+ {
+ super(h, "CFBMode Test");
+ runTest(testCFB_AES128, "CFB AES-128 Test Vectors");
+ runTest(testCFB_AES192, "CFB AES-192 Test Vectors");
+ runTest(testCFB_AES256, "CFB AES-256 Test Vectors");
+ h.endTestCase();
+ }
+
+ /**
+ * http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
+ */
+ public function testCFB_AES128():void {
+ var key:ByteArray = Hex.toArray("2b7e151628aed2a6abf7158809cf4f3c");
+ var pt:ByteArray = Hex.toArray(
+ "6bc1bee22e409f96e93d7e117393172a" +
+ "ae2d8a571e03ac9c9eb76fac45af8e51" +
+ "30c81c46a35ce411e5fbc1191a0a52ef" +
+ "f69f2445df4f9b17ad2b417be66c3710");
+ var ct:ByteArray = Hex.toArray(
+ "3b3fd92eb72dad20333449f8e83cfb4a" +
+ "c8a64537a0b3a93fcde3cdad9f1ce58b" +
+ "26751f67a3cbb140b1808cf187a4f4df" +
+ "c04b05357c5d1c0eeac4c66f9ff7f2e6");
+ var cfb:CFBMode = new CFBMode(new AESKey(key), new NullPad);
+ cfb.IV = Hex.toArray("000102030405060708090a0b0c0d0e0f");
+ var src:ByteArray = new ByteArray;
+ src.writeBytes(pt);
+ cfb.encrypt(src);
+ assert("CFB_AES128 test 1", Hex.fromArray(src)==Hex.fromArray(ct));
+ cfb.decrypt(src);
+ assert("CFB_AES128 test 2", Hex.fromArray(src)==Hex.fromArray(pt));
+ }
+ public function testCFB_AES192():void {
+ var key:ByteArray = Hex.toArray("8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b");
+ var pt:ByteArray = Hex.toArray(
+ "6bc1bee22e409f96e93d7e117393172a" +
+ "ae2d8a571e03ac9c9eb76fac45af8e51" +
+ "30c81c46a35ce411e5fbc1191a0a52ef" +
+ "f69f2445df4f9b17ad2b417be66c3710");
+ var ct:ByteArray = Hex.toArray(
+ "cdc80d6fddf18cab34c25909c99a4174" +
+ "67ce7f7f81173621961a2b70171d3d7a" +
+ "2e1e8a1dd59b88b1c8e60fed1efac4c9" +
+ "c05f9f9ca9834fa042ae8fba584b09ff");
+ var cfb:CFBMode = new CFBMode(new AESKey(key), new NullPad);
+ cfb.IV = Hex.toArray("000102030405060708090a0b0c0d0e0f");
+ var src:ByteArray = new ByteArray;
+ src.writeBytes(pt);
+ cfb.encrypt(src);
+ assert("CFB_AES192 test 1", Hex.fromArray(src)==Hex.fromArray(ct));
+ cfb.decrypt(src);
+ assert("CFB_AES192 test 2", Hex.fromArray(src)==Hex.fromArray(pt));
+ }
+ public function testCFB_AES256():void {
+ var key:ByteArray = Hex.toArray(
+ "603deb1015ca71be2b73aef0857d7781" +
+ "1f352c073b6108d72d9810a30914dff4");
+ var pt:ByteArray = Hex.toArray(
+ "6bc1bee22e409f96e93d7e117393172a" +
+ "ae2d8a571e03ac9c9eb76fac45af8e51" +
+ "30c81c46a35ce411e5fbc1191a0a52ef" +
+ "f69f2445df4f9b17ad2b417be66c3710");
+ var ct:ByteArray = Hex.toArray(
+ "dc7e84bfda79164b7ecd8486985d3860" +
+ "39ffed143b28b1c832113c6331e5407b" +
+ "df10132415e54b92a13ed0a8267ae2f9" +
+ "75a385741ab9cef82031623d55b1e471");
+ var cfb:CFBMode = new CFBMode(new AESKey(key), new NullPad);
+ cfb.IV = Hex.toArray("000102030405060708090a0b0c0d0e0f");
+ var src:ByteArray = new ByteArray;
+ src.writeBytes(pt);
+ cfb.encrypt(src);
+ assert("CFB_AES256 test 1", Hex.fromArray(src)==Hex.fromArray(ct));
+ cfb.decrypt(src);
+ assert("CFB_AES256 test 2", Hex.fromArray(src)==Hex.fromArray(pt));
+ }
+ }
+}
\ No newline at end of file diff --git a/flash-src/third-party/com/hurlant/crypto/tests/CTRModeTest.as b/flash-src/third-party/com/hurlant/crypto/tests/CTRModeTest.as new file mode 100755 index 0000000..d82fda2 --- /dev/null +++ b/flash-src/third-party/com/hurlant/crypto/tests/CTRModeTest.as @@ -0,0 +1,109 @@ +/**
+ * CTRModeTest
+ *
+ * A test class for CTRMode
+ * Copyright (c) 2007 Henri Torgemane
+ *
+ * See LICENSE.txt for full license information.
+ */
+package com.hurlant.crypto.tests
+{
+ import flash.utils.ByteArray;
+ import com.hurlant.util.Hex;
+ import com.hurlant.crypto.symmetric.CTRMode;
+ import com.hurlant.crypto.symmetric.AESKey;
+ import com.hurlant.crypto.symmetric.NullPad;
+
+ public class CTRModeTest extends TestCase
+ {
+ public function CTRModeTest(h:ITestHarness)
+ {
+ super(h, "CTRMode Test");
+ runTest(testCTR_AES128, "CTR AES-128 Test Vectors");
+ runTest(testCTR_AES192, "CTR AES-192 Test Vectors");
+ runTest(testCTR_AES256, "CTR AES-256 Test Vectors");
+ h.endTestCase();
+ }
+
+ /**
+ * Vectors from http://csrc.nist.gov/CryptoToolkit/modes/800-38_Series_Publications/SP800-38A.pdf
+ * Section F.5.1 and below.
+ */
+ public function testCTR_AES128():void {
+ var key:ByteArray = Hex.toArray("2b7e151628aed2a6abf7158809cf4f3c");
+ var pt:ByteArray = Hex.toArray(
+ "6bc1bee22e409f96e93d7e117393172a" +
+ "ae2d8a571e03ac9c9eb76fac45af8e51" +
+ "30c81c46a35ce411e5fbc1191a0a52ef" +
+ "f69f2445df4f9b17ad2b417be66c3710");
+ var ct:ByteArray = Hex.toArray(
+ "874d6191b620e3261bef6864990db6ce" +
+ "9806f66b7970fdff8617187bb9fffdff" +
+ "5ae4df3edbd5d35e5b4f09020db03eab" +
+ "1e031dda2fbe03d1792170a0f3009cee");
+ var ctr:CTRMode = new CTRMode(new AESKey(key), new NullPad);
+ ctr.IV = Hex.toArray("f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff");
+ var src:ByteArray = new ByteArray;
+ src.writeBytes(pt);
+ ctr.encrypt(src);
+ var hsrc:String = Hex.fromArray(src);
+ var hct:String = Hex.fromArray(ct);
+ assert("CTR_AES128 test 1: "+hsrc+" != "+hct, hsrc==hct);
+ ctr.decrypt(src);
+ hsrc = Hex.fromArray(src);
+ var hpt:String = Hex.fromArray(pt);
+ assert("CTR_AES128 test 2: "+hsrc+" != "+hpt, hsrc==hpt);
+ }
+ public function testCTR_AES192():void {
+ var key:ByteArray = Hex.toArray("8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b");
+ var pt:ByteArray = Hex.toArray(
+ "6bc1bee22e409f96e93d7e117393172a" +
+ "ae2d8a571e03ac9c9eb76fac45af8e51" +
+ "30c81c46a35ce411e5fbc1191a0a52ef" +
+ "f69f2445df4f9b17ad2b417be66c3710");
+ var ct:ByteArray = Hex.toArray(
+ "1abc932417521ca24f2b0459fe7e6e0b" +
+ "090339ec0aa6faefd5ccc2c6f4ce8e94" +
+ "1e36b26bd1ebc670d1bd1d665620abf7" +
+ "4f78a7f6d29809585a97daec58c6b050");
+ var ctr:CTRMode = new CTRMode(new AESKey(key), new NullPad);
+ ctr.IV = Hex.toArray("f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff");
+ var src:ByteArray = new ByteArray;
+ src.writeBytes(pt);
+ ctr.encrypt(src);
+ var hsrc:String = Hex.fromArray(src);
+ var hct:String = Hex.fromArray(ct);
+ assert("CTR_AES192 test 1: "+hsrc+" != "+hct, hsrc==hct);
+ ctr.decrypt(src);
+ hsrc = Hex.fromArray(src);
+ var hpt:String = Hex.fromArray(pt);
+ assert("CTR_AES192 test 2: "+hsrc+" != "+hpt, hsrc==hpt);
+ }
+ public function testCTR_AES256():void {
+ var key:ByteArray = Hex.toArray("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4");
+ var pt:ByteArray = Hex.toArray(
+ "6bc1bee22e409f96e93d7e117393172a" +
+ "ae2d8a571e03ac9c9eb76fac45af8e51" +
+ "30c81c46a35ce411e5fbc1191a0a52ef" +
+ "f69f2445df4f9b17ad2b417be66c3710");
+ var ct:ByteArray = Hex.toArray(
+ "601ec313775789a5b7a7f504bbf3d228" +
+ "f443e3ca4d62b59aca84e990cacaf5c5" +
+ "2b0930daa23de94ce87017ba2d84988d" +
+ "dfc9c58db67aada613c2dd08457941a6");
+ var ctr:CTRMode = new CTRMode(new AESKey(key), new NullPad);
+ ctr.IV = Hex.toArray("f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff");
+ var src:ByteArray = new ByteArray;
+ src.writeBytes(pt);
+ ctr.encrypt(src);
+ var hsrc:String = Hex.fromArray(src);
+ var hct:String = Hex.fromArray(ct);
+ assert("CTR_AES256 test 1: "+hsrc+" != "+hct, hsrc==hct);
+ ctr.decrypt(src);
+ hsrc = Hex.fromArray(src);
+ var hpt:String = Hex.fromArray(pt);
+ assert("CTR_AES256 test 2: "+hsrc+" != "+hpt, hsrc==hpt);
+ }
+
+ }
+}
\ No newline at end of file diff --git a/flash-src/third-party/com/hurlant/crypto/tests/DESKeyTest.as b/flash-src/third-party/com/hurlant/crypto/tests/DESKeyTest.as new file mode 100755 index 0000000..5d09e01 --- /dev/null +++ b/flash-src/third-party/com/hurlant/crypto/tests/DESKeyTest.as @@ -0,0 +1,112 @@ +/**
+ * DesKeyTest
+ *
+ * A test class for DesKey
+ * Copyright (c) 2007 Henri Torgemane
+ *
+ * See LICENSE.txt for full license information.
+ */
+package com.hurlant.crypto.tests
+{
+ import com.hurlant.crypto.symmetric.DESKey;
+ import com.hurlant.util.Hex;
+ import flash.utils.ByteArray;
+
+ public class DESKeyTest extends TestCase
+ {
+ public function DESKeyTest(h:ITestHarness)
+ {
+ super(h, "DESKey Test");
+ runTest(testECB,"DES ECB Test Vectors");
+ h.endTestCase();
+ }
+
+ /**
+ * Test vectors mostly grabbed from
+ * http://csrc.nist.gov/publications/nistpubs/800-17/800-17.pdf
+ * (Appendix A and B)
+ * incomplete.
+ */
+ public function testECB():void {
+ var keys:Array = [
+ "3b3898371520f75e", // grabbed from the output of some js implementation out there
+ "10316E028C8F3B4A", // appendix A vector
+ "0101010101010101", // appendix B Table 1, round 0
+ "0101010101010101", // round 1
+ "0101010101010101", // 2
+ "0101010101010101",
+ "0101010101010101",
+ "0101010101010101",
+ "0101010101010101",
+ "0101010101010101",
+ "0101010101010101", // round 8
+ "8001010101010101", // app B, tbl 2, round 0
+ "4001010101010101",
+ "2001010101010101",
+ "1001010101010101",
+ "0801010101010101",
+ "0401010101010101",
+ "0201010101010101",
+ "0180010101010101",
+ "0140010101010101", // round 8
+ ];
+ var pts:Array = [
+ "0000000000000000", // js
+ "0000000000000000", // App A
+ "8000000000000000", // App B, tbl 1, rnd0
+ "4000000000000000",
+ "2000000000000000",
+ "1000000000000000",
+ "0800000000000000", // rnd 4
+ "0400000000000000",
+ "0200000000000000",
+ "0100000000000000",
+ "0080000000000000", // round 8
+ "0000000000000000", // App B, tbl2, rnd0
+ "0000000000000000",
+ "0000000000000000",
+ "0000000000000000",
+ "0000000000000000",
+ "0000000000000000",
+ "0000000000000000",
+ "0000000000000000",
+ "0000000000000000", // rnd 8
+ ];
+ var cts:Array = [
+ "83A1E814889253E0", // js
+ "82DCBAFBDEAB6602", // App A
+ "95F8A5E5DD31D900", // App b, tbl 1, rnd 0
+ "DD7F121CA5015619",
+ "2E8653104F3834EA",
+ "4BD388FF6CD81D4F",
+ "20B9E767B2FB1456",
+ "55579380D77138EF",
+ "6CC5DEFAAF04512F",
+ "0D9F279BA5D87260",
+ "D9031B0271BD5A0A", // rnd 8
+ "95A8D72813DAA94D", // App B, tbl 2, rnd 0
+ "0EEC1487DD8C26D5",
+ "7AD16FFB79C45926",
+ "D3746294CA6A6CF3",
+ "809F5F873C1FD761",
+ "C02FAFFEC989D1FC",
+ "4615AA1D33E72F10",
+ "2055123350C00858",
+ "DF3B99D6577397C8", // rnd 8
+ ];
+
+ for (var i:uint=0;i<keys.length;i++) {
+ var key:ByteArray = Hex.toArray(keys[i]);
+ var pt:ByteArray = Hex.toArray(pts[i]);
+ var des:DESKey = new DESKey(key);
+ des.encrypt(pt);
+ var out:String = Hex.fromArray(pt).toUpperCase();
+ assert("comparing "+cts[i]+" to "+out, cts[i]==out);
+ // now go back to plaintext
+ des.decrypt(pt);
+ out = Hex.fromArray(pt).toUpperCase();
+ assert("comparing "+pts[i]+" to "+out, pts[i]==out);
+ }
+ }
+ }
+}
\ No newline at end of file diff --git a/flash-src/third-party/com/hurlant/crypto/tests/ECBModeTest.as b/flash-src/third-party/com/hurlant/crypto/tests/ECBModeTest.as new file mode 100755 index 0000000..2f0179c --- /dev/null +++ b/flash-src/third-party/com/hurlant/crypto/tests/ECBModeTest.as @@ -0,0 +1,151 @@ +/**
+ * ECBModeTest
+ *
+ * A test class for ECBMode
+ * Copyright (c) 2007 Henri Torgemane
+ *
+ * See LICENSE.txt for full license information.
+ */
+package com.hurlant.crypto.tests
+{
+ import com.hurlant.crypto.symmetric.AESKey;
+ import com.hurlant.crypto.symmetric.ECBMode;
+ import com.hurlant.crypto.symmetric.NullPad;
+ import com.hurlant.crypto.symmetric.XTeaKey;
+ import com.hurlant.util.Hex;
+
+ import flash.utils.ByteArray;
+
+ public class ECBModeTest extends TestCase
+ {
+ public function ECBModeTest(h:ITestHarness) {
+ super(h, "ECBMode Test");
+ runTest(testAES,"ECB AES Test Vectors");
+ runTest(testXTea,"ECB XTea Test Vectors");
+ runTest(testECB_AES128,"ECB AES-128 Test Vectors");
+ runTest(testECB_AES192,"ECB AES-192 Test Vectors");
+ runTest(testECB_AES256,"ECB AES-256 Test Vectors");
+ h.endTestCase();
+ }
+ /**
+ * For now the main goal is to show we can decrypt what we encrypt in this mode.
+ * Eventually, this should get correlated with some well known vectors.
+ * yay. found hawt test vectors: http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
+ */
+ public function testECB_AES128():void {
+ var key:ByteArray = Hex.toArray("2b7e151628aed2a6abf7158809cf4f3c");
+ var pt:ByteArray = Hex.toArray(
+ "6bc1bee22e409f96e93d7e117393172a" +
+ "ae2d8a571e03ac9c9eb76fac45af8e51" +
+ "30c81c46a35ce411e5fbc1191a0a52ef" +
+ "f69f2445df4f9b17ad2b417be66c3710");
+ var ct:ByteArray = Hex.toArray(
+ "3ad77bb40d7a3660a89ecaf32466ef97" +
+ "f5d3d58503b9699de785895a96fdbaaf" +
+ "43b1cd7f598ece23881b00e3ed030688" +
+ "7b0c785e27e8ad3f8223207104725dd4");
+ var ecb:ECBMode = new ECBMode(new AESKey(key), new NullPad);
+ var src:ByteArray = new ByteArray;
+ src.writeBytes(pt);
+ ecb.encrypt(src);
+ assert("ECB_AES128 test 1", Hex.fromArray(src)==Hex.fromArray(ct));
+ ecb.decrypt(src);
+ assert("ECB_AES128 test 2", Hex.fromArray(src)==Hex.fromArray(pt));
+ }
+ public function testECB_AES192():void {
+ var key:ByteArray = Hex.toArray("8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b");
+ var pt:ByteArray = Hex.toArray(
+ "6bc1bee22e409f96e93d7e117393172a" +
+ "ae2d8a571e03ac9c9eb76fac45af8e51" +
+ "30c81c46a35ce411e5fbc1191a0a52ef" +
+ "f69f2445df4f9b17ad2b417be66c3710");
+ var ct:ByteArray = Hex.toArray(
+ "bd334f1d6e45f25ff712a214571fa5cc" +
+ "974104846d0ad3ad7734ecb3ecee4eef" +
+ "ef7afd2270e2e60adce0ba2face6444e" +
+ "9a4b41ba738d6c72fb16691603c18e0e");
+ var ecb:ECBMode = new ECBMode(new AESKey(key), new NullPad);
+ var src:ByteArray = new ByteArray;
+ src.writeBytes(pt);
+ ecb.encrypt(src);
+ assert("ECB_AES192 test 1", Hex.fromArray(src)==Hex.fromArray(ct));
+ ecb.decrypt(src);
+ assert("ECB_AES192 test 2", Hex.fromArray(src)==Hex.fromArray(pt));
+ }
+ public function testECB_AES256():void {
+ var key:ByteArray = Hex.toArray(
+ "603deb1015ca71be2b73aef0857d7781" +
+ "1f352c073b6108d72d9810a30914dff4");
+ var pt:ByteArray = Hex.toArray(
+ "6bc1bee22e409f96e93d7e117393172a" +
+ "ae2d8a571e03ac9c9eb76fac45af8e51" +
+ "30c81c46a35ce411e5fbc1191a0a52ef" +
+ "f69f2445df4f9b17ad2b417be66c3710");
+ var ct:ByteArray = Hex.toArray(
+ "f3eed1bdb5d2a03c064b5a7e3db181f8" +
+ "591ccb10d410ed26dc5ba74a31362870" +
+ "b6ed21b99ca6f4f9f153e7b1beafed1d" +
+ "23304b7a39f9f3ff067d8d8f9e24ecc7");
+ var ecb:ECBMode = new ECBMode(new AESKey(key), new NullPad);
+ var src:ByteArray = new ByteArray;
+ src.writeBytes(pt);
+ ecb.encrypt(src);
+ assert("ECB_AES256 test 1", Hex.fromArray(src)==Hex.fromArray(ct));
+ ecb.decrypt(src);
+ assert("ECB_AES256 test 2", Hex.fromArray(src)==Hex.fromArray(pt));
+ }
+ // crappier, older testing. keeping around for no good reason.
+ public function testAES():void {
+ var keys:Array = [
+ "00010203050607080A0B0C0D0F101112",
+ "14151617191A1B1C1E1F202123242526"];
+ var pts:Array = [
+ "506812A45F08C889B97F5980038B8359506812A45F08C889B97F5980038B8359506812A45F08C889B97F5980038B8359",
+ "5C6D71CA30DE8B8B00549984D2EC7D4B5C6D71CA30DE8B8B00549984D2EC7D4B5C6D71CA30DE8B8B00549984D2EC7D4B"];
+ var cts:Array = [
+ "D8F532538289EF7D06B506A4FD5BE9C9D8F532538289EF7D06B506A4FD5BE9C9D8F532538289EF7D06B506A4FD5BE9C96DE5F607AB7EB8202F3957703B04E8B5",
+ "59AB30F4D4EE6E4FF9907EF65B1FB68C59AB30F4D4EE6E4FF9907EF65B1FB68C59AB30F4D4EE6E4FF9907EF65B1FB68C2993487785CB1CFDA6BB4F0F345F76C7"];
+
+ for (var i:uint=0;i<keys.length;i++) {
+ var key:ByteArray = Hex.toArray(keys[i]);
+ var pt:ByteArray = Hex.toArray(pts[i]);
+ var aes:AESKey = new AESKey(key);
+ var ecb:ECBMode = new ECBMode(aes);
+ ecb.encrypt(pt);
+ var str:String = Hex.fromArray(pt).toUpperCase();
+ assert("comparing "+cts[i]+" to "+str, cts[i]==str);
+ // back to pt
+ ecb.decrypt(pt);
+ str = Hex.fromArray(pt).toUpperCase();
+ assert("comparing "+pts[i]+" to "+str, pts[i]==str);
+ }
+ }
+ public function testXTea():void {
+ var keys:Array=[
+ "00000000000000000000000000000000",
+ "2b02056806144976775d0e266c287843"];
+ var pts:Array=[
+ "0000000000000000000000000000000000000000000000000000000000000000",
+ "74657374206d652e74657374206d652e74657374206d652e74657374206d652e"];
+ var cts:Array=[
+ "2dc7e8d3695b05382dc7e8d3695b05382dc7e8d3695b05382dc7e8d3695b053820578a874233632d",
+ "79095821381987837909582138198783790958213819878379095821381987830e4dc3c48b2edf32"];
+ // self-fullfilling vectors.
+ // oh well, at least I can decrypt what I produce. :(
+
+ for (var i:uint=0;i<keys.length;i++) {
+ var key:ByteArray = Hex.toArray(keys[i]);
+ var pt:ByteArray = Hex.toArray(pts[i]);
+ var tea:XTeaKey = new XTeaKey(key);
+ var ecb:ECBMode = new ECBMode(tea);
+ ecb.encrypt(pt);
+ var str:String = Hex.fromArray(pt);
+ assert("comparing "+cts[i]+" to "+str, cts[i]==str);
+ // now go back to plaintext.
+ ecb.decrypt(pt);
+ str = Hex.fromArray(pt);
+ assert("comparing "+pts[i]+" to "+str, pts[i]==str);
+ }
+ }
+ }
+}
\ No newline at end of file diff --git a/flash-src/third-party/com/hurlant/crypto/tests/HMACTest.as b/flash-src/third-party/com/hurlant/crypto/tests/HMACTest.as new file mode 100755 index 0000000..340293f --- /dev/null +++ b/flash-src/third-party/com/hurlant/crypto/tests/HMACTest.as @@ -0,0 +1,184 @@ +/**
+ * HMACTest
+ *
+ * A test class for HMAC
+ * Copyright (c) 2007 Henri Torgemane
+ *
+ * See LICENSE.txt for full license information.
+ */
+package com.hurlant.crypto.tests
+{
+ import com.hurlant.crypto.hash.HMAC;
+ import com.hurlant.crypto.hash.MD5;
+ import com.hurlant.crypto.hash.SHA1;
+ import com.hurlant.crypto.hash.SHA224;
+ import com.hurlant.crypto.hash.SHA256;
+ import com.hurlant.util.Hex;
+
+ import flash.utils.ByteArray;
+
+ public class HMACTest extends TestCase
+ {
+ public function HMACTest(h:ITestHarness)
+ {
+ super(h, "HMAC Test");
+ runTest(testHMAC_MD5,"HMAC MD5 Test Vectors");
+ runTest(testHMAC_SHA_1,"HMAC SHA-1 Test Vectors");
+ runTest(testHMAC_SHA_2,"HMAC SHA-224/SHA-256 Test Vectors");
+ runTest(testHMAC96_MD5,"HMAC-96 MD5 Test Vectors");
+ runTest(testHMAC96_SHA_1,"HMAC-96 SHA-1 Test Vectors");
+ runTest(testHMAC128_SHA_2,"HMAC-128 SHA-224/SHA-256 Test Vectors");
+ h.endTestCase();
+ }
+ /**
+ * Test vectors taking from RFC2202
+ * http://tools.ietf.org/html/rfc2202
+ * Yes, it's from an RFC, jefe! Now waddayawant?
+ */
+ public function testHMAC_SHA_1():void {
+ var keys:Array = [
+ "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b",
+ Hex.fromString("Jefe"),
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
+ "0102030405060708090a0b0c0d0e0f10111213141516171819",
+ "0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c",
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"];
+ var pts:Array = [
+ Hex.fromString("Hi There"),
+ Hex.fromString("what do ya want for nothing?"),
+ "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd",
+ "cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ Hex.fromString("Test With Truncation"),
+ Hex.fromString("Test Using Larger Than Block-Size Key - Hash Key First"),
+ Hex.fromString("Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data")];
+ var cts:Array = [
+ "b617318655057264e28bc0b6fb378c8ef146be00",
+ "effcdf6ae5eb2fa2d27416d5f184df9c259a7c79",
+ "125d7342b9ac11cd91a39af48aa17b4f63f175d3",
+ "4c9007f4026250c6bc8414f9bf50c86c2d7235da",
+ "4c1a03424b55e07fe7f27be1d58bb9324a9a5a04",
+ "aa4ae5e15272d00e95705637ce8a3b55ed402112",
+ "e8e99d0f45237d786d6bbaa7965c7808bbff1a91"];
+
+ var hmac:HMAC = new HMAC(new SHA1());
+ for (var i:uint=0;i<keys.length;i++) {
+ var key:ByteArray = Hex.toArray(keys[i]);
+ var pt:ByteArray = Hex.toArray(pts[i]);
+ var digest:ByteArray = hmac.compute(key, pt);
+ assert("HMAC-SHA-1 test "+i, Hex.fromArray(digest) == cts[i]);
+ }
+ }
+ public function testHMAC96_SHA_1():void {
+ var hmac:HMAC = new HMAC(new SHA1, 96);
+ var key:ByteArray = Hex.toArray("0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c");
+ var pt:ByteArray = Hex.toArray(Hex.fromString("Test With Truncation"));
+ var ct:String = "4c1a03424b55e07fe7f27be1";
+ var digest:ByteArray = hmac.compute(key, pt);
+ assert("HMAC96-SHA-1 test", Hex.fromArray(digest) == ct);
+ }
+
+ public function testHMAC_MD5():void {
+ var keys:Array = [
+ Hex.fromString("Jefe"),
+ "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b",
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
+ "0102030405060708090a0b0c0d0e0f10111213141516171819",
+ "0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c",
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"];
+ var pts:Array = [
+ Hex.fromString("what do ya want for nothing?"),
+ Hex.fromString("Hi There"),
+ "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd",
+ "cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ Hex.fromString("Test With Truncation"),
+ Hex.fromString("Test Using Larger Than Block-Size Key - Hash Key First"),
+ Hex.fromString("Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data")];
+ var cts:Array = [
+ "750c783e6ab0b503eaa86e310a5db738",
+ "9294727a3638bb1c13f48ef8158bfc9d",
+ "56be34521d144c88dbb8c733f0e8b3f6",
+ "697eaf0aca3a3aea3a75164746ffaa79",
+ "56461ef2342edc00f9bab995690efd4c",
+ "6b1ab7fe4bd7bf8f0b62e6ce61b9d0cd",
+ "6f630fad67cda0ee1fb1f562db3aa53e"];
+
+ var hmac:HMAC = new HMAC(new MD5());
+ for (var i:uint=0;i<keys.length;i++) {
+ var key:ByteArray = Hex.toArray(keys[i]);
+ var pt:ByteArray = Hex.toArray(pts[i]);
+ var digest:ByteArray = hmac.compute(key, pt);
+ assert("HMAC-MD5 test "+i, Hex.fromArray(digest) == cts[i]);
+ }
+ }
+ public function testHMAC96_MD5():void {
+ var hmac:HMAC = new HMAC(new MD5, 96);
+ var key:ByteArray = Hex.toArray("0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c");
+ var pt:ByteArray = Hex.toArray(Hex.fromString("Test With Truncation"));
+ var ct:String = "56461ef2342edc00f9bab995";
+ var digest:ByteArray = hmac.compute(key, pt);
+ assert("HMAC96-MD5 test", Hex.fromArray(digest) == ct);
+ }
+
+ /**
+ * Test vectors for HMAC-SHA-2 taken from RFC4231
+ * http://www.ietf.org/rfc/rfc4231.txt
+ * Still the same lame strings, but hidden in hex. why not.
+ */
+ public function testHMAC_SHA_2():void {
+ var keys:Array = [
+ "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b",
+ "4a656665",
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
+ "0102030405060708090a0b0c0d0e0f10111213141516171819",
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"];
+ var pts:Array = [
+ "4869205468657265",
+ "7768617420646f2079612077616e7420666f72206e6f7468696e673f",
+ "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd",
+ "cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "54657374205573696e67204c6172676572205468616e20426c6f636b2d53697a65204b6579202d2048617368204b6579204669727374",
+ "5468697320697320612074657374207573696e672061206c6172676572207468616e20626c6f636b2d73697a65206b657920616e642061206c6172676572207468616e20626c6f636b2d73697a6520646174612e20546865206b6579206e6565647320746f20626520686173686564206265666f7265206265696e6720757365642062792074686520484d414320616c676f726974686d2e"];
+ var cts224:Array = [
+ "896fb1128abbdf196832107cd49df33f47b4b1169912ba4f53684b22",
+ "a30e01098bc6dbbf45690f3a7e9e6d0f8bbea2a39e6148008fd05e44",
+ "7fb3cb3588c6c1f6ffa9694d7d6ad2649365b0c1f65d69d1ec8333ea",
+ "6c11506874013cac6a2abc1bb382627cec6a90d86efc012de7afec5a",
+ "95e9a0db962095adaebe9b2d6f0dbce2d499f112f2d2b7273fa6870e",
+ "3a854166ac5d9f023f54d517d0b39dbd946770db9c2b95c9f6f565d1"];
+ var cts256:Array = [
+ "b0344c61d8db38535ca8afceaf0bf12b881dc200c9833da726e9376c2e32cff7",
+ "5bdcc146bf60754e6a042426089575c75a003f089d2739839dec58b964ec3843",
+ "773ea91e36800e46854db8ebd09181a72959098b3ef8c122d9635514ced565fe",
+ "82558a389a443c0ea4cc819899f2083a85f0faa3e578f8077a2e3ff46729665b",
+ "60e431591ee0b67f0d8a26aacbf5b77f8e0bc6213728c5140546040f0ee37f54",
+ "9b09ffa71b942fcb27635fbcd5b0e944bfdc63644f0713938a7f51535c3a35e2"];
+ // 384 and 512 will be added. someday. if I ever figure how to do 64bit computations half efficiently in as3
+
+ var hmac224:HMAC = new HMAC(new SHA224);
+ var hmac256:HMAC = new HMAC(new SHA256);
+ for (var i:uint=0;i<keys.length;i++) {
+ var key:ByteArray = Hex.toArray(keys[i]);
+ var pt:ByteArray = Hex.toArray(pts[i]);
+ var digest224:ByteArray = hmac224.compute(key, pt);
+ assert("HMAC-SHA-224 test "+i, Hex.fromArray(digest224) == cts224[i]);
+ var digest256:ByteArray = hmac256.compute(key, pt);
+ assert("HMAC-SHA-256 test "+i, Hex.fromArray(digest256) == cts256[i]);
+ }
+ }
+ public function testHMAC128_SHA_2():void {
+ var hmac224:HMAC = new HMAC(new SHA224,128);
+ var hmac256:HMAC = new HMAC(new SHA256,128);
+ var key:ByteArray = Hex.toArray("0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c");
+ var pt:ByteArray = Hex.toArray("546573742057697468205472756e636174696f6e");
+ var ct224:String = "0e2aea68a90c8d37c988bcdb9fca6fa8";
+ var ct256:String = "a3b6167473100ee06e0c796c2955552b";
+ var digest224:ByteArray = hmac224.compute(key, pt);
+ assert("HMAC128-SHA-224 test", Hex.fromArray(digest224) == ct224);
+ var digest256:ByteArray = hmac256.compute(key, pt);
+ assert("HMAC128-SHA-256 test", Hex.fromArray(digest256) == ct256);
+ }
+ }
+}
\ No newline at end of file diff --git a/flash-src/third-party/com/hurlant/crypto/tests/ITestHarness.as b/flash-src/third-party/com/hurlant/crypto/tests/ITestHarness.as new file mode 100755 index 0000000..3a8daab --- /dev/null +++ b/flash-src/third-party/com/hurlant/crypto/tests/ITestHarness.as @@ -0,0 +1,20 @@ +/**
+ * ITestHarness
+ *
+ * An interface to specify what's available for test cases to use.
+ * Copyright (c) 2007 Henri Torgemane
+ *
+ * See LICENSE.txt for full license information.
+ */
+package com.hurlant.crypto.tests
+{
+ public interface ITestHarness
+ {
+ function beginTestCase(name:String):void;
+ function endTestCase():void;
+
+ function beginTest(name:String):void;
+ function passTest():void;
+ function failTest(msg:String):void;
+ }
+}
\ No newline at end of file diff --git a/flash-src/third-party/com/hurlant/crypto/tests/MD2Test.as b/flash-src/third-party/com/hurlant/crypto/tests/MD2Test.as new file mode 100755 index 0000000..8b4106a --- /dev/null +++ b/flash-src/third-party/com/hurlant/crypto/tests/MD2Test.as @@ -0,0 +1,56 @@ +/**
+ * MD2Test
+ *
+ * A test class for MD2
+ * Copyright (c) 2007 Henri Torgemane
+ *
+ * See LICENSE.txt for full license information.
+ */
+package com.hurlant.crypto.tests
+{
+ import com.hurlant.crypto.hash.MD2;
+ import com.hurlant.util.Hex;
+
+ import flash.utils.ByteArray;
+
+ public class MD2Test extends TestCase
+ {
+ public function MD2Test(h:ITestHarness)
+ {
+ super(h, "MD2 Test");
+ runTest(testMd2, "MD2 Test Vectors");
+ h.endTestCase();
+ }
+
+ /**
+ * Test Vectors grabbed from
+ * http://www.faqs.org/rfcs/rfc1319.html
+ */
+ public function testMd2():void {
+ var srcs:Array = [
+ "",
+ Hex.fromString("a"),
+ Hex.fromString("abc"),
+ Hex.fromString("message digest"),
+ Hex.fromString("abcdefghijklmnopqrstuvwxyz"),
+ Hex.fromString("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"),
+ Hex.fromString("12345678901234567890123456789012345678901234567890123456789012345678901234567890")
+ ];
+ var hashes:Array = [
+ "8350e5a3e24c153df2275c9f80692773",
+ "32ec01ec4a6dac72c0ab96fb34c0b5d1",
+ "da853b0d3f88d99b30283a69e6ded6bb",
+ "ab4f496bfb2a530b219ff33031fe06b0",
+ "4e8ddff3650292ab5a4108c3aa47940b",
+ "da33def2a42df13975352846c30338cd",
+ "d5976f79d83d3a0dc9806c3c66f3efd8"
+ ];
+ var md2:MD2 = new MD2;
+ for (var i:uint=0;i<srcs.length;i++) {
+ var src:ByteArray = Hex.toArray(srcs[i]);
+ var digest:ByteArray = md2.hash(src);
+ assert("MD2 Test "+i, Hex.fromArray(digest) == hashes[i]);
+ }
+ }
+ }
+}
\ No newline at end of file diff --git a/flash-src/third-party/com/hurlant/crypto/tests/MD5Test.as b/flash-src/third-party/com/hurlant/crypto/tests/MD5Test.as new file mode 100755 index 0000000..14c3f2f --- /dev/null +++ b/flash-src/third-party/com/hurlant/crypto/tests/MD5Test.as @@ -0,0 +1,58 @@ +/**
+ * MD5Test
+ *
+ * A test class for MD5
+ * Copyright (c) 2007 Henri Torgemane
+ *
+ * See LICENSE.txt for full license information.
+ */
+package com.hurlant.crypto.tests
+{
+ import com.hurlant.crypto.hash.MD5;
+ import com.hurlant.util.Hex;
+
+ import flash.utils.ByteArray;
+
+ public class MD5Test extends TestCase
+ {
+ public function MD5Test(h:ITestHarness)
+ {
+ super(h, "MD5 Test");
+ runTest(testMd5,"MD5 Test Vectors");
+ h.endTestCase();
+ }
+
+ /**
+ * Test Vectors grabbed from
+ * http://www.faqs.org/rfcs/rfc1321.html
+ */
+ public function testMd5():void {
+ var srcs:Array = [
+ "",
+ Hex.fromString("a"),
+ Hex.fromString("abc"),
+ Hex.fromString("message digest"),
+ Hex.fromString("abcdefghijklmnopqrstuvwxyz"),
+ Hex.fromString("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"),
+ Hex.fromString("12345678901234567890123456789012345678901234567890123456789012345678901234567890")
+ ];
+ var hashes:Array = [
+ "d41d8cd98f00b204e9800998ecf8427e",
+ "0cc175b9c0f1b6a831c399e269772661",
+ "900150983cd24fb0d6963f7d28e17f72",
+ "f96b697d7cb7938d525a2f31aaf161d0",
+ "c3fcd3d76192e4007dfb496cca67e13b",
+ "d174ab98d277d9f5a5611c2c9f419d9f",
+ "57edf4a22be3c955ac49da2e2107b67a"
+ ];
+ var md5:MD5 = new MD5;
+ for (var i:uint=0;i<srcs.length;i++) {
+ var src:ByteArray = Hex.toArray(srcs[i]);
+ var digest:ByteArray = md5.hash(src);
+ assert("MD5 Test "+i, Hex.fromArray(digest) == hashes[i]);
+ }
+
+ }
+
+ }
+}
\ No newline at end of file diff --git a/flash-src/third-party/com/hurlant/crypto/tests/OFBModeTest.as b/flash-src/third-party/com/hurlant/crypto/tests/OFBModeTest.as new file mode 100755 index 0000000..979d20b --- /dev/null +++ b/flash-src/third-party/com/hurlant/crypto/tests/OFBModeTest.as @@ -0,0 +1,101 @@ +/**
+ * OFBModeTest
+ *
+ * A test class for OFBMode
+ * Copyright (c) 2007 Henri Torgemane
+ *
+ * See LICENSE.txt for full license information.
+ */
+package com.hurlant.crypto.tests
+{
+ import flash.utils.ByteArray;
+ import com.hurlant.util.Hex;
+ import com.hurlant.crypto.symmetric.OFBMode;
+ import com.hurlant.crypto.symmetric.AESKey;
+ import com.hurlant.crypto.symmetric.NullPad;
+
+ public class OFBModeTest extends TestCase
+ {
+ public function OFBModeTest(h:ITestHarness)
+ {
+ super(h, "OFBMode Test");
+ runTest(testOFB_AES128,"OFB AES-128 Test Vectors");
+ runTest(testOFB_AES192,"OFB AES-192 Test Vectors");
+ runTest(testOFB_AES256,"OFB AES-256 Test Vectors");
+ h.endTestCase();
+ }
+
+ /**
+ * Nist Vectors: http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
+ * Section F.4.1 and below.
+ */
+ public function testOFB_AES128():void {
+ var key:ByteArray = Hex.toArray("2b7e151628aed2a6abf7158809cf4f3c");
+ var pt:ByteArray = Hex.toArray(
+ "6bc1bee22e409f96e93d7e117393172a" +
+ "ae2d8a571e03ac9c9eb76fac45af8e51" +
+ "30c81c46a35ce411e5fbc1191a0a52ef" +
+ "f69f2445df4f9b17ad2b417be66c3710");
+ var ct:ByteArray = Hex.toArray(
+ "3b3fd92eb72dad20333449f8e83cfb4a" +
+ "7789508d16918f03f53c52dac54ed825" +
+ "9740051e9c5fecf64344f7a82260edcc" +
+ "304c6528f659c77866a510d9c1d6ae5e");
+ var ofb:OFBMode = new OFBMode(new AESKey(key), new NullPad);
+ ofb.IV = Hex.toArray("000102030405060708090a0b0c0d0e0f");
+ var src:ByteArray = new ByteArray;
+ src.writeBytes(pt);
+ ofb.encrypt(src);
+ assert("OFB_AES128 test 1", Hex.fromArray(src)==Hex.fromArray(ct));
+ ofb.decrypt(src);
+ assert("OFB_AES128 test 2", Hex.fromArray(src)==Hex.fromArray(pt));
+ }
+
+ public function testOFB_AES192():void {
+ var key:ByteArray = Hex.toArray("8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b");
+ var pt:ByteArray = Hex.toArray(
+ "6bc1bee22e409f96e93d7e117393172a" +
+ "ae2d8a571e03ac9c9eb76fac45af8e51" +
+ "30c81c46a35ce411e5fbc1191a0a52ef" +
+ "f69f2445df4f9b17ad2b417be66c3710");
+ var ct:ByteArray = Hex.toArray(
+ "cdc80d6fddf18cab34c25909c99a4174" +
+ "fcc28b8d4c63837c09e81700c1100401" +
+ "8d9a9aeac0f6596f559c6d4daf59a5f2" +
+ "6d9f200857ca6c3e9cac524bd9acc92a");
+ var ofb:OFBMode = new OFBMode(new AESKey(key), new NullPad);
+ ofb.IV = Hex.toArray("000102030405060708090a0b0c0d0e0f");
+ var src:ByteArray = new ByteArray;
+ src.writeBytes(pt);
+ ofb.encrypt(src);
+ assert("OFB_AES192 test 1", Hex.fromArray(src)==Hex.fromArray(ct));
+ ofb.decrypt(src);
+ assert("OFB_AES192 test 2", Hex.fromArray(src)==Hex.fromArray(pt));
+ }
+
+ public function testOFB_AES256():void {
+ var key:ByteArray = Hex.toArray(
+ "603deb1015ca71be2b73aef0857d7781" +
+ "1f352c073b6108d72d9810a30914dff4");
+ var pt:ByteArray = Hex.toArray(
+ "6bc1bee22e409f96e93d7e117393172a" +
+ "ae2d8a571e03ac9c9eb76fac45af8e51" +
+ "30c81c46a35ce411e5fbc1191a0a52ef" +
+ "f69f2445df4f9b17ad2b417be66c3710");
+ var ct:ByteArray = Hex.toArray(
+ "dc7e84bfda79164b7ecd8486985d3860" +
+ "4febdc6740d20b3ac88f6ad82a4fb08d" +
+ "71ab47a086e86eedf39d1c5bba97c408" +
+ "0126141d67f37be8538f5a8be740e484");
+ var ofb:OFBMode = new OFBMode(new AESKey(key), new NullPad);
+ ofb.IV = Hex.toArray("000102030405060708090a0b0c0d0e0f");
+ var src:ByteArray = new ByteArray;
+ src.writeBytes(pt);
+ ofb.encrypt(src);
+ assert("OFB_AES256 test 1", Hex.fromArray(src)==Hex.fromArray(ct));
+ ofb.decrypt(src);
+ assert("OFB_AES256 test 2", Hex.fromArray(src)==Hex.fromArray(pt));
+ }
+
+ }
+}
\ No newline at end of file diff --git a/flash-src/third-party/com/hurlant/crypto/tests/RSAKeyTest.as b/flash-src/third-party/com/hurlant/crypto/tests/RSAKeyTest.as new file mode 100755 index 0000000..6ada0fc --- /dev/null +++ b/flash-src/third-party/com/hurlant/crypto/tests/RSAKeyTest.as @@ -0,0 +1,92 @@ +/**
+ * RSAKeyTest
+ *
+ * A test class for RSAKey
+ * Copyright (c) 2007 Henri Torgemane
+ *
+ * See LICENSE.txt for full license information.
+ */
+package com.hurlant.crypto.tests
+{
+ import com.hurlant.crypto.rsa.RSAKey;
+ import flash.utils.ByteArray;
+ import com.hurlant.util.Hex;
+ import com.hurlant.util.der.PEM;
+
+ public class RSAKeyTest extends TestCase
+ {
+ public function RSAKeyTest(h:ITestHarness)
+ {
+ super(h, "RSA Testing");
+
+ runTest(testSmoke,"RSA smoke test");
+ runTest(testGenerate, "RSA Key Generation test");
+ runTest(testPEM, "RSA Private Key PEM parsing");
+ runTest(testPEM2, "RSA Public Key PEM parsing");
+ h.endTestCase();
+ }
+
+ public function testSmoke():void {
+ var N:String ="C4E3F7212602E1E396C0B6623CF11D26204ACE3E7D26685E037AD2507DCE82FC" +
+ "28F2D5F8A67FC3AFAB89A6D818D1F4C28CFA548418BD9F8E7426789A67E73E41";
+ var E:String = "10001";
+ var D:String = "7cd1745aec69096129b1f42da52ac9eae0afebbe0bc2ec89253598dcf454960e" +
+ "3e5e4ec9f8c87202b986601dd167253ee3fb3fa047e14f1dfd5ccd37e931b29d";
+ var P:String = "f0e4dd1eac5622bd3932860fc749bbc48662edabdf3d2826059acc0251ac0d3b";
+ var Q:String = "d13cb38fbcd06ee9bca330b4000b3dae5dae12b27e5173e4d888c325cda61ab3";
+ var DMP1:String = "b3d5571197fc31b0eb6b4153b425e24c033b054d22b9c8282254fe69d8c8c593";
+ var DMQ1:String = "968ffe89e50d7b72585a79b65cfdb9c1da0963cceb56c3759e57334de5a0ac3f";
+ var IQMP:String = "d9bc4f420e93adad9f007d0e5744c2fe051c9ed9d3c9b65f439a18e13d6e3908";
+ // create a key.
+ var rsa:RSAKey = RSAKey.parsePrivateKey(N,E,D, P,Q,DMP1,DMQ1,IQMP);
+ var txt:String = "hello";
+ var src:ByteArray = Hex.toArray(Hex.fromString(txt));
+ var dst:ByteArray = new ByteArray;
+ var dst2:ByteArray = new ByteArray;
+ rsa.encrypt(src, dst, src.length);
+ rsa.decrypt(dst, dst2, dst.length);
+ var txt2:String = Hex.toString(Hex.fromArray(dst2));
+ assert("rsa encrypt+decrypt", txt==txt2);
+ }
+
+ public function testGenerate():void {
+ var rsa:RSAKey = RSAKey.generate(256, "10001");
+ // same lame smoke test here.
+ var txt:String = "hello";
+ var src:ByteArray = Hex.toArray(Hex.fromString(txt));
+ var dst:ByteArray = new ByteArray;
+ var dst2:ByteArray = new ByteArray;
+ rsa.encrypt(src, dst, src.length);
+ rsa.decrypt(dst, dst2, dst.length);
+ var txt2:String = Hex.toString(Hex.fromArray(dst2));
+ assert("rsa encrypt+decrypt", txt==txt2);
+ }
+
+ public function testPEM():void {
+ var pem:String = "-----BEGIN RSA PRIVATE KEY-----\n" +
+ "MGQCAQACEQDJG3bkuB9Ie7jOldQTVdzPAgMBAAECEQCOGqcPhP8t8mX8cb4cQEaR\n" +
+ "AgkA5WTYuAGmH0cCCQDgbrto0i7qOQIINYr5btGrtccCCQCYy4qX4JDEMQIJAJll\n" +
+ "OnLVtCWk\n" +
+ "-----END RSA PRIVATE KEY-----";
+ var rsa:RSAKey = PEM.readRSAPrivateKey(pem);
+ //trace(rsa.dump());
+
+ // obligatory use
+ var txt:String = "hello";
+ var src:ByteArray = Hex.toArray(Hex.fromString(txt));
+ var dst:ByteArray = new ByteArray;
+ var dst2:ByteArray = new ByteArray;
+ rsa.encrypt(src, dst, src.length);
+ rsa.decrypt(dst, dst2, dst.length);
+ var txt2:String = Hex.toString(Hex.fromArray(dst2));
+ assert("rsa encrypt+decrypt", txt==txt2);
+ }
+ public function testPEM2():void {
+ var pem:String = "-----BEGIN PUBLIC KEY-----\n" +
+ "MCwwDQYJKoZIhvcNAQEBBQADGwAwGAIRAMkbduS4H0h7uM6V1BNV3M8CAwEAAQ==\n" +
+ "-----END PUBLIC KEY-----";
+ var rsa:RSAKey = PEM.readRSAPublicKey(pem);
+ //trace(rsa.dump());
+ }
+ }
+}
\ No newline at end of file diff --git a/flash-src/third-party/com/hurlant/crypto/tests/SHA1Test.as b/flash-src/third-party/com/hurlant/crypto/tests/SHA1Test.as new file mode 100755 index 0000000..dc216f9 --- /dev/null +++ b/flash-src/third-party/com/hurlant/crypto/tests/SHA1Test.as @@ -0,0 +1,198 @@ +/**
+ * SHA1Test
+ *
+ * A test class for SHA1
+ * Copyright (c) 2007 Henri Torgemane
+ *
+ * See LICENSE.txt for full license information.
+ */
+package com.hurlant.crypto.tests
+{
+ import com.hurlant.crypto.hash.SHA1;
+ import com.hurlant.util.Hex;
+
+ import flash.utils.ByteArray;
+
+ public class SHA1Test extends TestCase
+ {
+ public function SHA1Test(h:ITestHarness)
+ {
+ super(h, "SHA-1 Test");
+ runTest(testSha1,"SHA-1 Test Vectors");
+ runTest(testLongSha1,"SHA-1 Long Test Vectors");
+ h.endTestCase();
+ }
+
+ /**
+ * Test Vectors grabbed from
+ * http://csrc.nist.gov/cryptval/shs.htm
+ */
+ public function testSha1():void {
+ var srcs:Array = [
+ "",
+ "a8",
+ "3000",
+ "42749e",
+ "9fc3fe08",
+ "b5c1c6f1af",
+ "e47571e5022e",
+ "3e1b28839fb758",
+ "a81350cbb224cb90",
+ "c243d167923dec3ce1",
+ "50ac18c59d6a37a29bf4",
+ "98e2b611ad3b1cccf634f6",
+ "73fe9afb68e1e8712e5d4eec",
+ "9e701ed7d412a9226a2a130e66",
+ "6d3ee90413b0a7cbf69e5e6144ca",
+ "fae24d56514efcb530fd4802f5e71f",
+ "c5a22dd6eda3fe2bdc4ddb3ce6b35fd1",
+ "d98cded2adabf08fda356445c781802d95",
+ "bcc6d7087a84f00103ccb32e5f5487a751a2",
+ "36ecacb1055434190dbbc556c48bafcb0feb0d",
+ "5ff9edb69e8f6bbd498eb4537580b7fba7ad31d0",
+ "c95b441d8270822a46a798fae5defcf7b26abace36",
+ "83104c1d8a55b28f906f1b72cb53f68cbb097b44f860",
+ "755175528d55c39c56493d697b790f099a5ce741f7754b",
+ "088fc38128bbdb9fd7d65228b3184b3faac6c8715f07272f",
+ "a4a586eb9245a6c87e3adf1009ac8a49f46c07e14185016895",
+ "8e7c555270c006092c2a3189e2a526b873e2e269f0fb28245256",
+ "a5f3bfa6bb0ba3b59f6b9cbdef8a558ec565e8aa3121f405e7f2f0",
+ "589054f0d2bd3c2c85b466bfd8ce18e6ec3e0b87d944cd093ba36469",
+ "a0abb12083b5bbc78128601bf1cbdbc0fdf4b862b24d899953d8da0ff3",
+ "82143f4cea6fadbf998e128a8811dc75301cf1db4f079501ea568da68eeb",
+ "9f1231dd6df1ff7bc0b0d4f989d048672683ce35d956d2f57913046267e6f3",
+ "041c512b5eed791f80d3282f3a28df263bb1df95e1239a7650e5670fc2187919",
+ "17e81f6ae8c2e5579d69dafa6e070e7111461552d314b691e7a3e7a4feb3fae418",
+ "d15976b23a1d712ad28fad04d805f572026b54dd64961fda94d5355a0cc98620cf77",
+ "09fce4d434f6bd32a44e04b848ff50ec9f642a8a85b37a264dc73f130f22838443328f",
+ "f17af27d776ec82a257d8d46d2b46b639462c56984cc1be9c1222eadb8b26594a25c709d",
+ "b13ce635d6f8758143ffb114f2f601cb20b6276951416a2f94fbf4ad081779d79f4f195b22",
+ "5498793f60916ff1c918dde572cdea76da8629ba4ead6d065de3dfb48de94d234cc1c5002910",
+ "498a1e0b39fa49582ae688cd715c86fbaf8a81b8b11b4d1594c49c902d197c8ba8a621fd6e3be5",
+ "3a36ae71521f9af628b3e34dcb0d4513f84c78ee49f10416a98857150b8b15cb5c83afb4b570376e",
+ "dcc76b40ae0ea3ba253e92ac50fcde791662c5b6c948538cffc2d95e9de99cac34dfca38910db2678f",
+ "5b5ec6ec4fd3ad9c4906f65c747fd4233c11a1736b6b228b92e90cddabb0c7c2fcf9716d3fad261dff33",
+ "df48a37b29b1d6de4e94717d60cdb4293fcf170bba388bddf7a9035a15d433f20fd697c3e4c8b8c5f590ab",
+ "1f179b3b82250a65e1b0aee949e218e2f45c7a8dbfd6ba08de05c55acfc226b48c68d7f7057e5675cd96fcfc",
+ "ee3d72da3a44d971578972a8e6780ce64941267e0f7d0179b214fa97855e1790e888e09fbe3a70412176cb3b54",
+ "d4d4c7843d312b30f610b3682254c8be96d5f6684503f8fbfbcd15774fc1b084d3741afb8d24aaa8ab9c104f7258",
+ "32c094944f5936a190a0877fb9178a7bf60ceae36fd530671c5b38c5dbd5e6a6c0d615c2ac8ad04b213cc589541cf6",
+ "e5d3180c14bf27a5409fa12b104a8fd7e9639609bfde6ee82bbf9648be2546d29688a65e2e3f3da47a45ac14343c9c02",
+ "e7b6e4b69f724327e41e1188a37f4fe38b1dba19cbf5a7311d6e32f1038e97ab506ee05aebebc1eed09fc0e357109818b9",
+ "bc880cb83b8ac68ef2fedc2da95e7677ce2aa18b0e2d8b322701f67af7d5e7a0d96e9e33326ccb7747cfff0852b961bfd475",
+ "235ea9c2ba7af25400f2e98a47a291b0bccdaad63faa2475721fda5510cc7dad814bce8dabb611790a6abe56030b798b75c944",
+ "07e3e29fed63104b8410f323b975fd9fba53f636af8c4e68a53fb202ca35dd9ee07cb169ec5186292e44c27e5696a967f5e67709",
+ "65d2a1dd60a517eb27bfbf530cf6a5458f9d5f4730058bd9814379547f34241822bf67e6335a6d8b5ed06abf8841884c636a25733f",
+ "dcc86b3bd461615bab739d8daafac231c0f462e819ad29f9f14058f3ab5b75941d4241ea2f17ebb8a458831b37a9b16dead4a76a9b0e",
+ "4627d54f0568dc126b62a8c35fb46a9ac5024400f2995e51635636e1afc4373dbb848eb32df23914230560b82477e9c3572647a7f2bb92",
+ "ba531affd4381168ef24d8b275a84d9254c7f5cc55fded53aa8024b2c5c5c8aa7146fe1d1b83d62b70467e9a2e2cb67b3361830adbab28d7",
+ "8764dcbcf89dcf4282eb644e3d568bdccb4b13508bfa7bfe0ffc05efd1390be22109969262992d377691eb4f77f3d59ea8466a74abf57b2ef4",
+ "497d9df9ddb554f3d17870b1a31986c1be277bc44feff713544217a9f579623d18b5ffae306c25a45521d2759a72c0459b58957255ab592f3be4",
+ "72c3c2e065aefa8d9f7a65229e818176eef05da83f835107ba90ec2e95472e73e538f783b416c04654ba8909f26a12db6e5c4e376b7615e4a25819",
+ "7cc9894454d0055ab5069a33984e2f712bef7e3124960d33559f5f3b81906bb66fe64da13c153ca7f5cabc89667314c32c01036d12ecaf5f9a78de98",
+ "74e8404d5a453c5f4d306f2cfa338ca65501c840ddab3fb82117933483afd6913c56aaf8a0a0a6b2a342fc3d9dc7599f4a850dfa15d06c61966d74ea59",
+ "46fe5ed326c8fe376fcc92dc9e2714e2240d3253b105adfbb256ff7a19bc40975c604ad7c0071c4fd78a7cb64786e1bece548fa4833c04065fe593f6fb10",
+ "836dfa2524d621cf07c3d2908835de859e549d35030433c796b81272fd8bc0348e8ddbc7705a5ad1fdf2155b6bc48884ac0cd376925f069a37849c089c8645",
+ "7e3a4c325cb9c52b88387f93d01ae86d42098f5efa7f9457388b5e74b6d28b2438d42d8b64703324d4aa25ab6aad153ae30cd2b2af4d5e5c00a8a2d0220c6116"];
+ var hashes:Array = [
+ "da39a3ee5e6b4b0d3255bfef95601890afd80709",
+ "99f2aa95e36f95c2acb0eaf23998f030638f3f15",
+ "f944dcd635f9801f7ac90a407fbc479964dec024",
+ "a444319e9b6cc1e8464c511ec0969c37d6bb2619",
+ "16a0ff84fcc156fd5d3ca3a744f20a232d172253",
+ "fec9deebfcdedaf66dda525e1be43597a73a1f93",
+ "8ce051181f0ed5e9d0c498f6bc4caf448d20deb5",
+ "67da53837d89e03bf652ef09c369a3415937cfd3",
+ "305e4ff9888ad855a78573cddf4c5640cce7e946",
+ "5902b77b3265f023f9bbc396ba1a93fa3509bde7",
+ "fcade5f5d156bf6f9af97bdfa9c19bccfb4ff6ab",
+ "1d20fbe00533c10e3cbd6b27088a5de0c632c4b5",
+ "7e1b7e0f7a8f3455a9c03e9580fd63ae205a2d93",
+ "706f0677146307b20bb0e8d6311e329966884d13",
+ "a7241a703aaf0d53fe142f86bf2e849251fa8dff",
+ "400f53546916d33ad01a5e6df66822dfbdc4e9e6",
+ "fac8ab93c1ae6c16f0311872b984f729dc928ccd",
+ "fba6d750c18da58f6e2aab10112b9a5ef3301b3b",
+ "29d27c2d44c205c8107f0351b05753ac708226b6",
+ "b971bfc1ebd6f359e8d74cb7ecfe7f898d0ba845",
+ "96d08c430094b9fcc164ad2fb6f72d0a24268f68",
+ "a287ea752a593d5209e287881a09c49fa3f0beb1",
+ "a06c713779cbd88519ed4a585ac0cb8a5e9d612b",
+ "bff7d52c13a3688132a1d407b1ab40f5b5ace298",
+ "c7566b91d7b6f56bdfcaa9781a7b6841aacb17e9",
+ "ffa30c0b5c550ea4b1e34f8a60ec9295a1e06ac1",
+ "29e66ed23e914351e872aa761df6e4f1a07f4b81",
+ "b28cf5e5b806a01491d41f69bd9248765c5dc292",
+ "60224fb72c46069652cd78bcd08029ef64da62f3",
+ "b72c4a86f72608f24c05f3b9088ef92fba431df7",
+ "73779ad5d6b71b9b8328ef7220ff12eb167076ac",
+ "a09671d4452d7cf50015c914a1e31973d20cc1a0",
+ "e88cdcd233d99184a6fd260b8fca1b7f7687aee0",
+ "010def22850deb1168d525e8c84c28116cb8a269",
+ "aeaa40ba1717ed5439b1e6ea901b294ba500f9ad",
+ "c6433791238795e34f080a5f1f1723f065463ca0",
+ "e21e22b89c1bb944a32932e6b2a2f20d491982c3",
+ "575323a9661f5d28387964d2ba6ab92c17d05a8a",
+ "feb44494af72f245bfe68e86c4d7986d57c11db7",
+ "cff2290b3648ba2831b98dde436a72f9ebf51eee",
+ "9b4efe9d27b965905b0c3dab67b8d7c9ebacd56c",
+ "afedb0ff156205bcd831cbdbda43db8b0588c113",
+ "8deb1e858f88293a5e5e4d521a34b2a4efa70fc4",
+ "95cbdac0f74afa69cebd0e5c7defbc6faf0cbeaf",
+ "f0307bcb92842e5ae0cd4f4f14f3df7f877fbef2",
+ "7b13bb0dbf14964bd63b133ac85e22100542ef55",
+ "c314d2b6cf439be678d2a74e890d96cfac1c02ed",
+ "4d0be361e410b47a9d67d8ce0bb6a8e01c53c078",
+ "e5353431ffae097f675cbf498869f6fbb6e1c9f2",
+ "b8720a7068a085c018ab18961de2765aa6cd9ac4",
+ "b0732181568543ba85f2b6da602b4b065d9931aa",
+ "9c22674cf3222c3ba921672694aafee4ce67b96b",
+ "d128335f4cecca9066cdae08958ce656ff0b4cfc",
+ "0b67c57ac578de88a2ae055caeaec8bb9b0085a0",
+ "c766f912a89d4ccda88e0cce6a713ef5f178b596",
+ "9aa3925a9dcb177b15ccff9b78e70cf344858779",
+ "4811fa30042fc076acf37c8e2274d025307e5943",
+ "6743018450c9730761ee2b130df9b91c1e118150",
+ "71ad4a19d37d92a5e6ef3694ddbeb5aa61ada645",
+ "a7d9dc68dacefb7d6116186048cb355cc548e11d",
+ "142e429f0522ba5abf5131fa81df82d355b96909",
+ "ef72db70dcbcab991e9637976c6faf00d22caae9",
+ "f220a7457f4588d639dc21407c942e9843f8e26b",
+ "ddd2117b6e309c233ede85f962a0c2fc215e5c69",
+ "a3054427cdb13f164a610b348702724c808a0dcc"];
+ // ok. let's loop.
+ var sha1:SHA1 = new SHA1;
+ for (var i:uint=0;i<srcs.length;i++) {
+ var src:ByteArray = Hex.toArray(srcs[i]);
+ var digest:ByteArray = sha1.hash(src);
+ assert("SHA1 Test "+i, Hex.fromArray(digest) == hashes[i]);
+ }
+
+ }
+ /**
+ * A few long SHA-1, from the same page
+ */
+ public function testLongSha1():void {
+ var srcs:Array = [
+ "ec29561244ede706b6eb30a1c371d74450a105c3f9735f7fa9fe38cf67f304a5736a106e92e17139a6813b1c81a4f3d3fb9546ab4296fa9f722826c066869edacd73b2548035185813e22634a9da44000d95a281ff9f264ecce0a931222162d021cca28db5f3c2aa24945ab1e31cb413ae29810fd794cad5dfaf29ec43cb38d198fe4ae1da2359780221405bd6712a5305da4b1b737fce7cd21c0eb7728d08235a9011",
+ "5fc2c3f6a7e79dc94be526e5166a238899d54927ce470018fbfd668fd9dd97cbf64e2c91584d01da63be3cc9fdff8adfefc3ac728e1e335b9cdc87f069172e323d094b47fa1e652afe4d6aa147a9f46fda33cacb65f3aa12234746b9007a8c85fe982afed7815221e43dba553d8fe8a022cdac1b99eeeea359e5a9d2e72e382dffa6d19f359f4f27dc3434cd27daeeda8e38594873398678065fbb23665aba9309d946135da0e4a4afdadff14db18e85e71dd93c3bf9faf7f25c8194c4269b1ee3d9934097ab990025d9c3aaf63d5109f52335dd3959d38ae485050e4bbb6235574fc0102be8f7a306d6e8de6ba6becf80f37415b57f9898a5824e77414197422be3d36a6080",
+ "0f865f46a8f3aed2da18482aa09a8f390dc9da07d51d1bd10fe0bf5f3928d5927d08733d32075535a6d1c8ac1b2dc6ba0f2f633dc1af68e3f0fa3d85e6c60cb7b56c239dc1519a007ea536a07b518ecca02a6c31b46b76f021620ef3fc6976804018380e5ab9c558ebfc5cb1c9ed2d974722bf8ab6398f1f2b82fa5083f85c16a5767a3a07271d67743f00850ce8ec428c7f22f1cf01f99895c0c844845b06a06cecb0c6cf83eb55a1d4ebc44c2c13f6f7aa5e0e08abfd84e7864279057abc471ee4a45dbbb5774afa24e51791a0eada11093b88681fe30baa3b2e94113dc63342c51ca5d1a6096d0897b626e42cb91761058008f746f35465465540ad8c6b8b60f7e1461b3ce9e6529625984cb8c7d46f07f735be067588a0117f23e34ff57800e2bbe9a1605fde6087fb15d22c5d3ac47566b8c448b0cee40373e5ba6eaa21abee71366afbb27dbbd300477d70c371e7b8963812f5ed4fb784fb2f3bd1d3afe883cdd47ef32beaea",
+ "4893f1c763625f2c6ce53aacf28026f14b3cd8687e1a1d3b60a81e80fcd1e2b038f9145ab64a0718f948f7c3c9ac92e3d86fb669a5257da1a18c776291653688338210a3242120f101788e8acc9110db9258b1554bf3d26602516ea93606a25a7f566c0c758fb39ecd9d876bc5d8abc1c3205095382c2474cb1f8bbdb45c2c0e659cb0fc703ec607a5de6bcc7a28687db1ee1c8f34797bb2441d5706d210df8c2d7d65dbded36414d063c117b52a51f7a4eb9cac0782e008b47459ed5acac0bc1f20121087f992ad985511b33c866d18e63f585478ee5a5e654b19d81231d98683ae3f0533565aba43dce408d7e3c4c6be11d8f05165f29c9dcb2030c4ee31d3a04e7421aa92c3231a1fc07e50e95fea7389a5e65891afaba51cf55e36a9d089bf293accb356d5d06547307d6e41456d4ed146a056179971c56521c83109bf922866186e184a99a96c7bb96df8937e35970e438412a2b8d744cf2ad87cb605d4232e976f9f15169776e4e5b6b786132c966b25fc56d815c56c819af5e159aa39f8a93d38115f5580cda93bc073c30b39920e726fe861b72483a3f886269ab7a8eefe952f35d25c4eb7f443f4f3f26e43d51fb54591e6a6dad25fcdf5142033084e5624bdd51435e77dea86b8",
+ "cf494c18a4e17bf03910631471bca5ba7edea8b9a63381e3463517961749848eb03abefd4ce676dece3740860255f57c261a558aa9c7f11432f549a9e4ce31d8e17c79450ce2ccfc148ad904aedfb138219d7052088520495355dadd90f72e6f69f9c6176d3d45f113f275b7fbc2a295784d41384cd7d629b23d1459a22e45fd5097ec9bf65fa965d3555ec77367903c32141065fc24da5c56963d46a2da3c279e4035fb2fb1c0025d9dda5b9e3443d457d92401a0d3f58b48469ecb1862dc975cdbe75ca099526db8b0329b03928206f084c633c04eef5e8e377f118d30edf592504be9d2802651ec78aeb02aea167a03fc3e23e5fc907c324f283f89ab37e84687a9c74ccf055402db95c29ba2c8d79b2bd4fa96459f8e3b78e07e923b81198267492196ecb71e01c331f8df245ec5bdf8d0e05c91e63bb299f0f6324895304dda721d39410458f117c87b7dd6a0ee734b79fcbe482b2c9e9aa0cef03a39d4b0c86de3bc34b4aadabfa373fd2258f7c40c187744d237080762382f547a36adb117839ca72f8ebbc5a20a07e86f4c8bb923f5787698d278f6db0040e76e54645bb0f97083995b34b9aa445fc424455058795828dd00c32471ec402a307f5aa1b37b1a86d6dae3bcbfbe9ba41cab0beeabf489af0073d4b3837d3f14b815120bc3602d072b5aeefcdec655fe756b660eba7dcf34675acbce317746270599424b9248791a0780449c1eabbb9459cc1e588bfd74df9b1b711c85c09d8aa171b309281947e8f4b6ac438753158f4f36fa"];
+ var hashes:Array = [
+ "970111c4e77bcc88cc20459c02b69b4aa8f58217",
+ "0423dc76a8791107d14e13f5265b343f24cc0f19",
+ "6692a71d73e00f27df976bc56df4970650d90e45",
+ "dc5859dd5163c4354d5d577b855fa98e37f04384",
+ "4c17926feb6e87f5bca7890d8a5cde744f231dab"];
+ // ok. let's loop.
+ var sha1:SHA1 = new SHA1;
+ for (var i:uint=0;i<srcs.length;i++) {
+ var src:ByteArray = Hex.toArray(srcs[i]);
+ var digest:ByteArray = sha1.hash(src);
+ assert("SHA1 Long Test "+i, Hex.fromArray(digest) == hashes[i]);
+ }
+
+ }
+ }
+}
\ No newline at end of file diff --git a/flash-src/third-party/com/hurlant/crypto/tests/SHA224Test.as b/flash-src/third-party/com/hurlant/crypto/tests/SHA224Test.as new file mode 100755 index 0000000..12208a8 --- /dev/null +++ b/flash-src/third-party/com/hurlant/crypto/tests/SHA224Test.as @@ -0,0 +1,58 @@ +/**
+ * SHA224Test
+ *
+ * A test class for SHA224
+ * Copyright (c) 2007 Henri Torgemane
+ *
+ * See LICENSE.txt for full license information.
+ */
+package com.hurlant.crypto.tests
+{
+ import com.hurlant.crypto.hash.SHA224;
+ import com.hurlant.util.Hex;
+
+ import flash.utils.ByteArray;
+
+ public class SHA224Test extends TestCase
+ {
+ public function SHA224Test(h:ITestHarness)
+ {
+ super(h,"SHA-224 Test");
+ runTest(testSha224,"SHA-224 Test Vectors");
+ // takes a few seconds, but uncomment if you must.
+ //runTest(testLongSha224,"SHA-224 Long Test Vectors");
+ h.endTestCase();
+ }
+
+ /**
+ * Test vectors courtesy of
+ * http://www.ietf.org/rfc/rfc3874.txt
+ */
+ public function testSha224():void {
+ var srcs:Array = [
+ Hex.fromString("abc"),
+ Hex.fromString("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq")];
+ var hashes:Array = [
+ "23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7",
+ "75388b16512776cc5dba5da1fd890150b0c6455cb4f58b1952522525"];
+
+ var sha224:SHA224 = new SHA224;
+ for (var i:uint=0;i<srcs.length;i++) {
+ var src:ByteArray = Hex.toArray(srcs[i]);
+ var digest:ByteArray = sha224.hash(src);
+ assert("SHA224 Test "+i, Hex.fromArray(digest) == hashes[i]);
+ }
+ }
+ public function testLongSha224():void {
+ var src:ByteArray = new ByteArray;
+ var a:uint = "a".charCodeAt(0);
+ for (var i:uint=0;i<1e6;i++) {
+ src[i] = a;
+ }
+ var sha224:SHA224 = new SHA224;
+ var digest:ByteArray = sha224.hash(src);
+ var hash:String = "20794655980c91d8bbb4c1ea97618a4bf03f42581948b2ee4ee7ad67";
+ assert("SHA224 Long Test", Hex.fromArray(digest) == hash);
+ }
+ }
+}
\ No newline at end of file diff --git a/flash-src/third-party/com/hurlant/crypto/tests/SHA256Test.as b/flash-src/third-party/com/hurlant/crypto/tests/SHA256Test.as new file mode 100755 index 0000000..a2b4c6c --- /dev/null +++ b/flash-src/third-party/com/hurlant/crypto/tests/SHA256Test.as @@ -0,0 +1,60 @@ +/**
+ * SHA256Test
+ *
+ * A test class for SHA256
+ * Copyright (c) 2007 Henri Torgemane
+ *
+ * See LICENSE.txt for full license information.
+ */
+package com.hurlant.crypto.tests
+{
+ import com.hurlant.crypto.hash.SHA256;
+ import com.hurlant.util.Hex;
+
+ import flash.utils.ByteArray;
+
+ public class SHA256Test extends TestCase
+ {
+ public function SHA256Test(h:ITestHarness)
+ {
+ super(h,"SHA-256 Test");
+ runTest(testSha256,"SHA-256 Test Vectors");
+ h.endTestCase();
+ }
+
+ /**
+ * Test vectors courtesy of
+ * https://www.cosic.esat.kuleuven.be/nessie/testvectors/hash/sha/Sha-2-256.unverified.test-vectors
+ */
+ public function testSha256():void {
+ var srcs:Array = [
+ Hex.fromString(""),
+ Hex.fromString("a"),
+ Hex.fromString("abc"),
+ Hex.fromString("message digest"),
+ Hex.fromString("abcdefghijklmnopqrstuvwxyz"),
+ Hex.fromString("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"),
+ Hex.fromString("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"),
+ Hex.fromString("12345678901234567890123456789012345678901234567890123456789012345678901234567890"),
+ ];
+ var hashes:Array = [
+ "E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855",
+ "CA978112CA1BBDCAFAC231B39A23DC4DA786EFF8147C4E72B9807785AFEE48BB",
+ "BA7816BF8F01CFEA414140DE5DAE2223B00361A396177A9CB410FF61F20015AD",
+ "F7846F55CF23E14EEBEAB5B4E1550CAD5B509E3348FBC4EFA3A1413D393CB650",
+ "71C480DF93D6AE2F1EFAD1447C66C9525E316218CF51FC8D9ED832F2DAF18B73",
+ "248D6A61D20638B8E5C026930C3E6039A33CE45964FF2167F6ECEDD419DB06C1",
+ "DB4BFCBD4DA0CD85A60C3C37D3FBD8805C77F15FC6B1FDFE614EE0A7C8FDB4C0",
+ "F371BC4A311F2B009EEF952DD83CA80E2B60026C8E935592D0F9C308453C813E"];
+
+ // loop.
+ var sha256:SHA256 = new SHA256;
+ for (var i:uint=0;i<srcs.length;i++) {
+ var src:ByteArray = Hex.toArray(srcs[i]);
+ var digest:ByteArray = sha256.hash(src);
+ assert("SHA256 Test "+i, Hex.fromArray(digest) == hashes[i].toLowerCase());
+ }
+
+ }
+ }
+}
\ No newline at end of file diff --git a/flash-src/third-party/com/hurlant/crypto/tests/TLSPRFTest.as b/flash-src/third-party/com/hurlant/crypto/tests/TLSPRFTest.as new file mode 100755 index 0000000..07fe9c6 --- /dev/null +++ b/flash-src/third-party/com/hurlant/crypto/tests/TLSPRFTest.as @@ -0,0 +1,51 @@ +/**
+ * TLSPRFTest
+ *
+ * A test class for TLFPRF
+ * Copyright (c) 2007 Henri Torgemane
+ *
+ * See LICENSE.txt for full license information.
+ */
+package com.hurlant.crypto.tests
+{
+ import flash.utils.ByteArray;
+ import com.hurlant.crypto.prng.TLSPRF;
+ import com.hurlant.util.Hex;
+
+ public class TLSPRFTest extends TestCase
+ {
+ public function TLSPRFTest(h:ITestHarness) {
+ super(h, "TLS-PRF Testing");
+ runTest(testVector, "TLF-PRF Test Vector");
+ h.endTestCase()
+ }
+
+ /**
+ * Test Vector as defined in
+ * http://www.imc.org/ietf-tls/mail-archive/msg01589.html
+ */
+ private function testVector():void {
+ var secret:ByteArray = new ByteArray;
+ for (var i:uint=0;i<48;i++) {
+ secret[i]= 0xab;
+ }
+ var label:String = "PRF Testvector";
+ var seed:ByteArray = new ByteArray;
+ for (i=0;i<64;i++) {
+ seed[i] = 0xcd;
+ }
+ var prf:TLSPRF = new TLSPRF(secret, label, seed);
+ var out:ByteArray = new ByteArray;
+ prf.nextBytes(out, 104);
+ var expected:String = "D3 D4 D1 E3 49 B5 D5 15 04 46 66 D5 1D E3 2B AB" +
+ "25 8C B5 21 B6 B0 53 46 3E 35 48 32 FD 97 67 54" +
+ "44 3B CF 9A 29 65 19 BC 28 9A BC BC 11 87 E4 EB" +
+ "D3 1E 60 23 53 77 6C 40 8A AF B7 4C BC 85 EF F6" +
+ "92 55 F9 78 8F AA 18 4C BB 95 7A 98 19 D8 4A 5D" +
+ "7E B0 06 EB 45 9D 3A E8 DE 98 10 45 4B 8B 2D 8F" +
+ "1A FB C6 55 A8 C9 A0 13";
+ var expect:String = Hex.fromArray(Hex.toArray(expected));
+ assert("out == expected", Hex.fromArray(out)==expect);
+ }
+ }
+}
\ No newline at end of file diff --git a/flash-src/third-party/com/hurlant/crypto/tests/TestCase.as b/flash-src/third-party/com/hurlant/crypto/tests/TestCase.as new file mode 100755 index 0000000..4be402b --- /dev/null +++ b/flash-src/third-party/com/hurlant/crypto/tests/TestCase.as @@ -0,0 +1,42 @@ +/**
+ * TestCase
+ *
+ * Embryonic unit test support class.
+ * Copyright (c) 2007 Henri Torgemane
+ *
+ * See LICENSE.txt for full license information.
+ */
+package com.hurlant.crypto.tests
+{
+ public class TestCase
+ {
+ public var harness:ITestHarness;
+
+ public function TestCase(h:ITestHarness, title:String) {
+ harness = h;
+ harness.beginTestCase(title);
+ }
+
+
+ public function assert(msg:String, value:Boolean):void {
+ if (value) {
+// TestHarness.print("+ ",msg);
+ return;
+ }
+ throw new Error("Test Failure:"+msg);
+ }
+
+ public function runTest(f:Function, title:String):void {
+ harness.beginTest(title);
+ try {
+ f();
+ } catch (e:Error) {
+ trace("EXCEPTION THROWN: "+e);
+ trace(e.getStackTrace());
+ harness.failTest(e.toString());
+ return;
+ }
+ harness.passTest();
+ }
+ }
+}
\ No newline at end of file diff --git a/flash-src/third-party/com/hurlant/crypto/tests/TripleDESKeyTest.as b/flash-src/third-party/com/hurlant/crypto/tests/TripleDESKeyTest.as new file mode 100755 index 0000000..148451f --- /dev/null +++ b/flash-src/third-party/com/hurlant/crypto/tests/TripleDESKeyTest.as @@ -0,0 +1,59 @@ +/**
+ * TripleDESKeyTest
+ *
+ * A test class for TripleDESKey
+ * Copyright (c) 2007 Henri Torgemane
+ *
+ * See LICENSE.txt for full license information.
+ */
+package com.hurlant.crypto.tests
+{
+ import com.hurlant.crypto.symmetric.TripleDESKey;
+ import com.hurlant.util.Hex;
+ import flash.utils.ByteArray;
+ import com.hurlant.crypto.symmetric.ICipher;
+ import com.hurlant.crypto.symmetric.ECBMode;
+
+ public class TripleDESKeyTest extends TestCase
+ {
+ public function TripleDESKeyTest(h:ITestHarness)
+ {
+ super(h, "Triped Des Test");
+ runTest(testECB,"Triple DES ECB Test Vectors");
+ h.endTestCase();
+ }
+
+ /**
+ * Lots of vectors at http://csrc.nist.gov/publications/nistpubs/800-20/800-20.pdf
+ * XXX move them in here.
+ */
+ public function testECB():void {
+ var keys:Array = [
+ "010101010101010101010101010101010101010101010101",
+ "dd24b3aafcc69278d650dad234956b01e371384619492ac4",
+ ];
+ var pts:Array = [
+ "8000000000000000",
+ "F36B21045A030303",
+ ];
+ var cts:Array = [
+ "95F8A5E5DD31D900",
+ "E823A43DEEA4D0A4",
+ ];
+
+ for (var i:uint=0;i<keys.length;i++) {
+ var key:ByteArray = Hex.toArray(keys[i]);
+ var pt:ByteArray = Hex.toArray(pts[i]);
+ var ede:TripleDESKey = new TripleDESKey(key);
+ ede.encrypt(pt);
+ var out:String = Hex.fromArray(pt).toUpperCase();
+ assert("comparing "+cts[i]+" to "+out, cts[i]==out);
+ // now go back to plaintext
+ ede.decrypt(pt);
+ out = Hex.fromArray(pt).toUpperCase();
+ assert("comparing "+pts[i]+" to "+out, pts[i]==out);
+ }
+ }
+
+ }
+}
\ No newline at end of file diff --git a/flash-src/third-party/com/hurlant/crypto/tests/XTeaKeyTest.as b/flash-src/third-party/com/hurlant/crypto/tests/XTeaKeyTest.as new file mode 100755 index 0000000..90a0b48 --- /dev/null +++ b/flash-src/third-party/com/hurlant/crypto/tests/XTeaKeyTest.as @@ -0,0 +1,66 @@ +/**
+ * XTeaKeyTest
+ *
+ * A test class for XTeaKey
+ * Copyright (c) 2007 Henri Torgemane
+ *
+ * See LICENSE.txt for full license information.
+ */
+package com.hurlant.crypto.tests
+{
+ import com.hurlant.crypto.prng.Random;
+ import com.hurlant.crypto.symmetric.ECBMode;
+ import com.hurlant.crypto.symmetric.XTeaKey;
+ import com.hurlant.util.Hex;
+
+ import flash.utils.ByteArray;
+ import flash.utils.getTimer;
+
+ public class XTeaKeyTest extends TestCase
+ {
+ public function XTeaKeyTest(h:ITestHarness) {
+ super(h, "XTeaKey Test");
+ runTest(testGetBlockSize, "XTea Block Size");
+ runTest(testVectors, "XTea Test Vectors");
+
+ h.endTestCase();
+ }
+
+ public function testGetBlockSize():void {
+ var tea:XTeaKey = new XTeaKey(Hex.toArray("deadbabecafebeefdeadbabecafebeef"));
+ assert("tea blocksize", tea.getBlockSize()==8);
+ }
+
+ public function testVectors():void {
+ // blah.
+ // can't find working test vectors.
+ // algorithms should not get published without vectors :(
+ var keys:Array=[
+ "00000000000000000000000000000000",
+ "2b02056806144976775d0e266c287843"];
+ var pts:Array=[
+ "0000000000000000",
+ "74657374206d652e"];
+ var cts:Array=[
+ "2dc7e8d3695b0538",
+ "7909582138198783"];
+ // self-fullfilling vectors.
+ // oh well, at least I can decrypt what I produce. :(
+
+ for (var i:uint=0;i<keys.length;i++) {
+ var key:ByteArray = Hex.toArray(keys[i]);
+ var pt:ByteArray = Hex.toArray(pts[i]);
+ var tea:XTeaKey = new XTeaKey(key);
+ tea.encrypt(pt);
+ var out:String = Hex.fromArray(pt);
+ assert("comparing "+cts[i]+" to "+out, cts[i]==out);
+ // now go back to plaintext.
+ pt.position=0;
+ tea.decrypt(pt);
+ out = Hex.fromArray(pt);
+ assert("comparing "+pts[i]+" to "+out, pts[i]==out);
+ }
+ }
+
+ }
+}
\ No newline at end of file diff --git a/flash-src/third-party/com/hurlant/crypto/tls/BulkCiphers.as b/flash-src/third-party/com/hurlant/crypto/tls/BulkCiphers.as new file mode 100644 index 0000000..2b1e717 --- /dev/null +++ b/flash-src/third-party/com/hurlant/crypto/tls/BulkCiphers.as @@ -0,0 +1,102 @@ +/** + * BulkCiphers + * + * An enumeration of bulk ciphers available for TLS, along with their properties, + * with a few convenience methods to go with it. + * Copyright (c) 2007 Henri Torgemane + * + * See LICENSE.txt for full license information. + */ +package com.hurlant.crypto.tls { + import com.hurlant.crypto.Crypto; + import flash.utils.ByteArray; + import com.hurlant.crypto.symmetric.ICipher; + import com.hurlant.crypto.symmetric.TLSPad; + import com.hurlant.crypto.symmetric.SSLPad; + + public class BulkCiphers { + public static const STREAM_CIPHER:uint = 0; + public static const BLOCK_CIPHER:uint = 1; + + public static const NULL:uint = 0; + public static const RC4_40:uint = 1; + public static const RC4_128:uint = 2 + public static const RC2_CBC_40:uint = 3; // XXX I don't have that one. + public static const DES_CBC:uint = 4; + public static const DES3_EDE_CBC:uint = 5; + public static const DES40_CBC:uint = 6; + public static const IDEA_CBC:uint = 7; // XXX I don't have that one. + public static const AES_128:uint = 8; + public static const AES_256:uint = 9; + + private static const algos:Array = + ['', 'rc4', 'rc4', '', 'des-cbc', '3des-cbc', 'des-cbc', '', 'aes', 'aes']; + + private static var _props:Array; + + init(); + private static function init():void { + _props = []; + _props[NULL] = new BulkCiphers(STREAM_CIPHER, 0, 0, 0, 0, 0); + _props[RC4_40] = new BulkCiphers(STREAM_CIPHER, 5, 16, 40, 0, 0); + _props[RC4_128] = new BulkCiphers(STREAM_CIPHER, 16, 16, 128, 0, 0); + _props[RC2_CBC_40] = new BulkCiphers( BLOCK_CIPHER, 5, 16, 40, 8, 8); + _props[DES_CBC] = new BulkCiphers( BLOCK_CIPHER, 8, 8, 56, 8, 8); + _props[DES3_EDE_CBC] = new BulkCiphers( BLOCK_CIPHER, 24, 24, 168, 8, 8); + _props[DES40_CBC] = new BulkCiphers( BLOCK_CIPHER, 5, 8, 40, 8, 8); + _props[IDEA_CBC] = new BulkCiphers( BLOCK_CIPHER, 16, 16, 128, 8, 8); + _props[AES_128] = new BulkCiphers( BLOCK_CIPHER, 16, 16, 128, 16, 16); + _props[AES_256] = new BulkCiphers( BLOCK_CIPHER, 32, 32, 256, 16, 16); + } + + private static function getProp(cipher:uint):BulkCiphers { + var p:BulkCiphers = _props[cipher]; + if (p==null) { + throw new Error("Unknown bulk cipher "+cipher.toString(16)); + } + return p; + } + public static function getType(cipher:uint):uint { + return getProp(cipher).type; + } + public static function getKeyBytes(cipher:uint):uint { + return getProp(cipher).keyBytes; + } + public static function getExpandedKeyBytes(cipher:uint):uint { + return getProp(cipher).expandedKeyBytes; + } + public static function getEffectiveKeyBits(cipher:uint):uint { + return getProp(cipher).effectiveKeyBits; + } + public static function getIVSize(cipher:uint):uint { + return getProp(cipher).IVSize; + } + public static function getBlockSize(cipher:uint):uint { + return getProp(cipher).blockSize; + } + public static function getCipher(cipher:uint, key:ByteArray, proto:uint):ICipher { + if (proto == TLSSecurityParameters.PROTOCOL_VERSION) { + return Crypto.getCipher(algos[cipher], key, new TLSPad); + } else { + return Crypto.getCipher(algos[cipher], key, new SSLPad); + } + } + + + private var type:uint; + private var keyBytes:uint; + private var expandedKeyBytes:uint; + private var effectiveKeyBits:uint; + private var IVSize:uint; + private var blockSize:uint; + + public function BulkCiphers(t:uint, kb:uint, ekb:uint, fkb:uint, ivs:uint, bs:uint) { + type = t; + keyBytes = kb; + expandedKeyBytes = ekb; + effectiveKeyBits = fkb; + IVSize = ivs; + blockSize = bs; + } + } +} diff --git a/flash-src/third-party/com/hurlant/crypto/tls/CipherSuites.as b/flash-src/third-party/com/hurlant/crypto/tls/CipherSuites.as new file mode 100644 index 0000000..e9beb0a --- /dev/null +++ b/flash-src/third-party/com/hurlant/crypto/tls/CipherSuites.as @@ -0,0 +1,117 @@ +/**
+ * CipherSuites
+ *
+ * An enumeration of cipher-suites available for TLS to use, along with
+ * their properties, and some convenience methods
+ * Copyright (c) 2007 Henri Torgemane
+ *
+ * See LICENSE.txt for full license information.
+ */
+package com.hurlant.crypto.tls {
+ import com.hurlant.crypto.hash.MD5;
+ import com.hurlant.crypto.hash.SHA1;
+
+ public class CipherSuites {
+
+
+ // only the lines marked "ok" are currently implemented.
+
+ // rfc 2246
+
+ public static const TLS_NULL_WITH_NULL_NULL:uint = 0x0000; // ok
+ public static const TLS_RSA_WITH_NULL_MD5:uint = 0x0001; // ok
+ public static const TLS_RSA_WITH_NULL_SHA:uint = 0x0002; // ok
+ public static const TLS_RSA_WITH_RC4_128_MD5:uint = 0x0004; // ok
+ public static const TLS_RSA_WITH_RC4_128_SHA:uint = 0x0005; // ok
+ public static const TLS_RSA_WITH_IDEA_CBC_SHA:uint = 0x0007;
+ public static const TLS_RSA_WITH_DES_CBC_SHA:uint = 0x0009; // ok
+ public static const TLS_RSA_WITH_3DES_EDE_CBC_SHA:uint = 0x000A; // ok
+
+ public static const TLS_DH_DSS_WITH_DES_CBC_SHA:uint = 0x000C;
+ public static const TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA:uint = 0x000D;
+ public static const TLS_DH_RSA_WITH_DES_CBC_SHA:uint = 0x000F;
+ public static const TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA:uint = 0x0010;
+ public static const TLS_DHE_DSS_WITH_DES_CBC_SHA:uint = 0x0012;
+ public static const TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA:uint = 0x0013;
+ public static const TLS_DHE_RSA_WITH_DES_CBC_SHA:uint = 0x0015;
+ public static const TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA:uint = 0x0016;
+
+ public static const TLS_DH_anon_WITH_RC4_128_MD5:uint = 0x0018;
+ public static const TLS_DH_anon_WITH_DES_CBC_SHA:uint = 0x001A;
+ public static const TLS_DH_anon_WITH_3DES_EDE_CBC_SHA:uint = 0x001B;
+
+ // rfc3268
+
+ public static const TLS_RSA_WITH_AES_128_CBC_SHA:uint = 0x002F; // ok
+ public static const TLS_DH_DSS_WITH_AES_128_CBC_SHA:uint = 0x0030;
+ public static const TLS_DH_RSA_WITH_AES_128_CBC_SHA:uint = 0x0031;
+ public static const TLS_DHE_DSS_WITH_AES_128_CBC_SHA:uint = 0x0032;
+ public static const TLS_DHE_RSA_WITH_AES_128_CBC_SHA:uint = 0x0033;
+ public static const TLS_DH_anon_WITH_AES_128_CBC_SHA:uint = 0x0034;
+
+ public static const TLS_RSA_WITH_AES_256_CBC_SHA:uint = 0x0035; // ok
+ public static const TLS_DH_DSS_WITH_AES_256_CBC_SHA:uint = 0x0036;
+ public static const TLS_DH_RSA_WITH_AES_256_CBC_SHA:uint = 0x0037;
+ public static const TLS_DHE_DSS_WITH_AES_256_CBC_SHA:uint = 0x0038;
+ public static const TLS_DHE_RSA_WITH_AES_256_CBC_SHA:uint = 0x0039;
+ public static const TLS_DH_anon_WITH_AES_256_CBC_SHA:uint = 0x003A;
+
+ private static var _props:Array;
+
+ init();
+ private static function init():void {
+ _props = [];
+ _props[TLS_NULL_WITH_NULL_NULL] = new CipherSuites(BulkCiphers.NULL, MACs.NULL, KeyExchanges.NULL);
+ _props[TLS_RSA_WITH_NULL_MD5] = new CipherSuites(BulkCiphers.NULL, MACs.MD5, KeyExchanges.RSA);
+ _props[TLS_RSA_WITH_NULL_SHA] = new CipherSuites(BulkCiphers.NULL, MACs.SHA1, KeyExchanges.RSA);
+ _props[TLS_RSA_WITH_RC4_128_MD5] = new CipherSuites(BulkCiphers.RC4_128, MACs.MD5, KeyExchanges.RSA);
+ _props[TLS_RSA_WITH_RC4_128_SHA] = new CipherSuites(BulkCiphers.RC4_128, MACs.SHA1, KeyExchanges.RSA);
+ _props[TLS_RSA_WITH_DES_CBC_SHA] = new CipherSuites(BulkCiphers.DES_CBC, MACs.SHA1, KeyExchanges.RSA);
+ _props[TLS_RSA_WITH_3DES_EDE_CBC_SHA] = new CipherSuites(BulkCiphers.DES3_EDE_CBC, MACs.SHA1, KeyExchanges.RSA);
+ _props[TLS_RSA_WITH_AES_128_CBC_SHA] = new CipherSuites(BulkCiphers.AES_128, MACs.SHA1, KeyExchanges.RSA);
+ _props[TLS_RSA_WITH_AES_256_CBC_SHA] = new CipherSuites(BulkCiphers.AES_256, MACs.SHA1, KeyExchanges.RSA);
+
+ // ...
+ // more later
+ }
+
+ private static function getProp(cipher:uint):CipherSuites {
+ var p:CipherSuites = _props[cipher];
+ if (p==null) {
+ throw new Error("Unknown cipher "+cipher.toString(16));
+ }
+ return p;
+ }
+ public static function getBulkCipher(cipher:uint):uint {
+ return getProp(cipher).cipher;
+ }
+ public static function getMac(cipher:uint):uint {
+ return getProp(cipher).hash;
+ }
+ public static function getKeyExchange(cipher:uint):uint {
+ return getProp(cipher).key;
+ }
+
+ public static function getDefaultSuites():Array {
+ // a list of acceptable ciphers, sorted by preference.
+ return [
+ TLS_RSA_WITH_AES_256_CBC_SHA,
+ TLS_RSA_WITH_3DES_EDE_CBC_SHA,
+ TLS_RSA_WITH_AES_128_CBC_SHA,
+ TLS_RSA_WITH_RC4_128_SHA,
+ TLS_RSA_WITH_RC4_128_MD5,
+ TLS_RSA_WITH_DES_CBC_SHA
+ ];
+ }
+
+ public var cipher:uint;
+ public var hash:uint;
+ public var key:uint;
+
+ public function CipherSuites(cipher:uint, hash:uint, key:uint) {
+ this.cipher = cipher;
+ this.hash = hash;
+ this.key = key;
+ }
+ }
+}
diff --git a/flash-src/third-party/com/hurlant/crypto/tls/IConnectionState.as b/flash-src/third-party/com/hurlant/crypto/tls/IConnectionState.as new file mode 100644 index 0000000..a5f0e11 --- /dev/null +++ b/flash-src/third-party/com/hurlant/crypto/tls/IConnectionState.as @@ -0,0 +1,14 @@ +/**
+ * IConnectionState
+ *
+ * Interface for TLS/SSL Connection states.
+ *
+ * See LICENSE.txt for full license information.
+ */
+package com.hurlant.crypto.tls {
+ import flash.utils.ByteArray;
+ public interface IConnectionState {
+ function decrypt(type:uint, length:uint, p:ByteArray) : ByteArray;
+ function encrypt(type:uint, p:ByteArray) : ByteArray;
+ }
+}
\ No newline at end of file diff --git a/flash-src/third-party/com/hurlant/crypto/tls/ISecurityParameters.as b/flash-src/third-party/com/hurlant/crypto/tls/ISecurityParameters.as new file mode 100755 index 0000000..3c18aa3 --- /dev/null +++ b/flash-src/third-party/com/hurlant/crypto/tls/ISecurityParameters.as @@ -0,0 +1,29 @@ +/**
+ * ISecurityParameters
+ *
+ * This class encapsulates all the security parameters that get negotiated
+ * during the TLS handshake. It also holds all the key derivation methods.
+ * Copyright (c) 2007 Henri Torgemane
+ *
+ * See LICENSE.txt for full license information.
+ */
+package com.hurlant.crypto.tls {
+ import flash.utils.ByteArray;
+
+ public interface ISecurityParameters {
+ function get version() : uint;
+ function reset():void;
+ function getBulkCipher():uint;
+ function getCipherType():uint;
+ function getMacAlgorithm():uint;
+ function setCipher(cipher:uint):void;
+ function setCompression(algo:uint):void;
+ function setPreMasterSecret(secret:ByteArray):void;
+ function setClientRandom(secret:ByteArray):void;
+ function setServerRandom(secret:ByteArray):void;
+ function get useRSA():Boolean;
+ function computeVerifyData(side:uint, handshakeMessages:ByteArray):ByteArray;
+ function computeCertificateVerify( side:uint, handshakeRecords:ByteArray):ByteArray;
+ function getConnectionStates():Object;
+ }
+}
\ No newline at end of file diff --git a/flash-src/third-party/com/hurlant/crypto/tls/KeyExchanges.as b/flash-src/third-party/com/hurlant/crypto/tls/KeyExchanges.as new file mode 100644 index 0000000..8b9fd0d --- /dev/null +++ b/flash-src/third-party/com/hurlant/crypto/tls/KeyExchanges.as @@ -0,0 +1,24 @@ +/**
+ * KeyExchanges
+ *
+ * An enumeration of key exchange methods defined by TLS
+ * ( right now, only RSA is actually implemented )
+ * Copyright (c) 2007 Henri Torgemane
+ *
+ * See LICENSE.txt for full license information.
+ */
+package com.hurlant.crypto.tls {
+ public class KeyExchanges {
+ public static const NULL:uint = 0;
+ public static const RSA:uint = 1;
+ public static const DH_DSS:uint = 2;
+ public static const DH_RSA:uint = 3;
+ public static const DHE_DSS:uint = 4;
+ public static const DHE_RSA:uint = 5;
+ public static const DH_anon:uint = 6;
+
+ public static function useRSA(p:uint):Boolean {
+ return (p==RSA);
+ }
+ }
+}
\ No newline at end of file diff --git a/flash-src/third-party/com/hurlant/crypto/tls/MACs.as b/flash-src/third-party/com/hurlant/crypto/tls/MACs.as new file mode 100644 index 0000000..09d79e7 --- /dev/null +++ b/flash-src/third-party/com/hurlant/crypto/tls/MACs.as @@ -0,0 +1,38 @@ +/**
+ * MACs
+ *
+ * An enumeration of MACs implemented for TLS 1.0/SSL 3.0
+ * Copyright (c) 2007 Henri Torgemane
+ *
+ * See LICENSE.txt for full license information.
+ */
+package com.hurlant.crypto.tls {
+ import com.hurlant.crypto.Crypto;
+ import com.hurlant.crypto.hash.HMAC;
+ import com.hurlant.crypto.hash.MAC;
+
+ public class MACs {
+ public static const NULL:uint = 0;
+ public static const MD5:uint = 1;
+ public static const SHA1:uint = 2;
+
+ public static function getHashSize(hash:uint):uint {
+ return [0,16,20][hash];
+ }
+
+ public static function getPadSize(hash:uint):int {
+ return [0, 48, 40][hash];
+ }
+
+ public static function getHMAC(hash:uint):HMAC {
+ if (hash==NULL) return null;
+ return Crypto.getHMAC(['',"md5","sha1"][hash]);
+ }
+
+ public static function getMAC(hash:uint):MAC {
+ return Crypto.getMAC(['', "md5", "sha1"][hash]);
+ }
+
+
+ }
+}
\ No newline at end of file diff --git a/flash-src/third-party/com/hurlant/crypto/tls/SSLConnectionState.as b/flash-src/third-party/com/hurlant/crypto/tls/SSLConnectionState.as new file mode 100644 index 0000000..1ef9c38 --- /dev/null +++ b/flash-src/third-party/com/hurlant/crypto/tls/SSLConnectionState.as @@ -0,0 +1,171 @@ +/** + * TLSConnectionState + * + * This class encapsulates the read or write state of a TLS connection, + * and implementes the encrypting and hashing of packets. + * Copyright (c) 2007 Henri Torgemane + * + * See LICENSE.txt for full license information. + */ +package com.hurlant.crypto.tls { + import flash.utils.IDataInput; + import flash.utils.ByteArray; + import com.hurlant.crypto.hash.MD5; + import com.hurlant.crypto.hash.MAC; + import com.hurlant.crypto.hash.IHash; + import com.hurlant.crypto.symmetric.ICipher; + import com.hurlant.crypto.symmetric.IVMode; + import com.hurlant.util.Hex; + import com.hurlant.util.ArrayUtil; + + public class SSLConnectionState implements IConnectionState { + + // compression state + + // cipher state + private var bulkCipher:uint; + private var cipherType:uint; + private var CIPHER_key:ByteArray; + private var CIPHER_IV:ByteArray; + private var cipher:ICipher; + private var ivmode:IVMode; + + // mac secret + private var macAlgorithm:uint; + private var MAC_write_secret:ByteArray; + private var mac:MAC; + + // sequence number. uint64 + + private var seq_lo:uint = 0x0; + private var seq_hi:uint = 0x0; + + public function SSLConnectionState( + bulkCipher:uint=0, cipherType:uint=0, macAlgorithm:uint=0, + mac_enc:ByteArray=null, key:ByteArray=null, IV:ByteArray=null) { + this.bulkCipher = bulkCipher; + this.cipherType = cipherType; + this.macAlgorithm = macAlgorithm; + MAC_write_secret = mac_enc; + mac = MACs.getMAC(macAlgorithm); + + CIPHER_key = key; + CIPHER_IV = IV; + cipher = BulkCiphers.getCipher(bulkCipher, key, 0x0300); + if (cipher is IVMode) { + ivmode = cipher as IVMode; + ivmode.IV = IV; + } + + } + + public function decrypt(type:uint, length:uint, p:ByteArray):ByteArray { + // decompression is a nop. + + if (cipherType == BulkCiphers.STREAM_CIPHER) { + if (bulkCipher == BulkCiphers.NULL) { + // no-op + } else { + cipher.decrypt(p); + } + } else { + p.position = 0; + // block cipher + if (bulkCipher == BulkCiphers.NULL) { + + } else { + var nextIV:ByteArray = new ByteArray; + nextIV.writeBytes(p, p.length-CIPHER_IV.length, CIPHER_IV.length); + p.position = 0; + cipher.decrypt(p); + + CIPHER_IV = nextIV; + ivmode.IV = nextIV; + } + } + + if (macAlgorithm!=MACs.NULL) { + // there will be CTX delay here as well, + // I should probably optmize the hell out of it + var data:ByteArray = new ByteArray; + var len:uint = p.length - mac.getHashSize(); + data.writeUnsignedInt(seq_hi); + data.writeUnsignedInt(seq_lo); + + data.writeByte(type); + data.writeShort(len); + if (len!=0) { + data.writeBytes(p, 0, len); + } + var mac_enc:ByteArray = mac.compute(MAC_write_secret, data); + // compare "mac" with the last X bytes of p. + var mac_received:ByteArray = new ByteArray; + mac_received.writeBytes(p, len, mac.getHashSize()); + if (ArrayUtil.equals(mac_enc, mac_received)) { + // happy happy joy joy + } else { + throw new TLSError("Bad Mac Data", TLSError.bad_record_mac); + } + p.length = len; + p.position = 0; + } + // increment seq + seq_lo++; + if (seq_lo==0) seq_hi++; + return p; + } + public function encrypt(type:uint, p:ByteArray):ByteArray { + var mac_enc:ByteArray = null; + if (macAlgorithm!=MACs.NULL) { + var data:ByteArray = new ByteArray; + // data.writeUnsignedInt(seq); + + // Sequence + data.writeUnsignedInt(seq_hi); + data.writeUnsignedInt(seq_lo); + + // Type + data.writeByte(type); + + // Length + data.writeShort(p.length); + + // The data + if (p.length!=0) { + data.writeBytes(p); + } + + // trace("data for the MAC: " + Hex.fromArray(data)); + mac_enc = mac.compute(MAC_write_secret, data); + // trace("MAC: " + Hex.fromArray( mac_enc )); + p.position = p.length; + p.writeBytes(mac_enc); + } + + // trace("Record to encrypt: " + Hex.fromArray(p)); + + p.position = 0; + if (cipherType == BulkCiphers.STREAM_CIPHER) { + // stream cipher + if (bulkCipher == BulkCiphers.NULL) { + // no-op + } else { + cipher.encrypt(p); + } + } else { + // block cipher + cipher.encrypt(p); + // adjust IV + var nextIV:ByteArray = new ByteArray; + nextIV.writeBytes(p, p.length-CIPHER_IV.length, CIPHER_IV.length); + CIPHER_IV = nextIV; + ivmode.IV = nextIV; + } + // increment seq + seq_lo++; + if (seq_lo==0) seq_hi++; + return p; + } + + } +}
\ No newline at end of file diff --git a/flash-src/third-party/com/hurlant/crypto/tls/SSLEvent.as b/flash-src/third-party/com/hurlant/crypto/tls/SSLEvent.as new file mode 100755 index 0000000..9a63521 --- /dev/null +++ b/flash-src/third-party/com/hurlant/crypto/tls/SSLEvent.as @@ -0,0 +1,26 @@ +/**
+ * SSLEvent
+ *
+ * This is used by TLSEngine to let the application layer know
+ * when we're ready for sending, or have received application data
+ * This Event was created by Bobby Parker to support SSL 3.0.
+ *
+ * See LICENSE.txt for full license information.
+ */
+package com.hurlant.crypto.tls {
+ import flash.events.Event;
+ import flash.utils.ByteArray;
+
+ public class SSLEvent extends Event {
+
+ static public const DATA:String = "data";
+ static public const READY:String = "ready";
+
+ public var data:ByteArray;
+
+ public function SSLEvent(type:String, data:ByteArray = null) {
+ this.data = data;
+ super(type, false, false);
+ }
+ }
+}
\ No newline at end of file diff --git a/flash-src/third-party/com/hurlant/crypto/tls/SSLSecurityParameters.as b/flash-src/third-party/com/hurlant/crypto/tls/SSLSecurityParameters.as new file mode 100755 index 0000000..3549461 --- /dev/null +++ b/flash-src/third-party/com/hurlant/crypto/tls/SSLSecurityParameters.as @@ -0,0 +1,340 @@ +/**
+ * TLSSecurityParameters
+ *
+ * This class encapsulates all the security parameters that get negotiated
+ * during the TLS handshake. It also holds all the key derivation methods.
+ * Copyright (c) 2007 Henri Torgemane
+ *
+ * See LICENSE.txt for full license information.
+ */
+package com.hurlant.crypto.tls {
+ import com.hurlant.crypto.hash.MD5;
+ import com.hurlant.crypto.hash.SHA1;
+ import com.hurlant.util.Hex;
+
+ import flash.utils.ByteArray;
+
+ public class SSLSecurityParameters implements ISecurityParameters {
+
+ // COMPRESSION
+ public static const COMPRESSION_NULL:uint = 0;
+
+ private var entity:uint; // SERVER | CLIENT
+ private var bulkCipher:uint; // BULK_CIPHER_*
+ private var cipherType:uint; // STREAM_CIPHER | BLOCK_CIPHER
+ private var keySize:uint;
+ private var keyMaterialLength:uint;
+ private var keyBlock:ByteArray;
+ private var IVSize:uint;
+ private var MAC_length:uint;
+ private var macAlgorithm:uint; // MAC_*
+ private var hashSize:uint;
+ private var compression:uint; // COMPRESSION_NULL
+ private var masterSecret:ByteArray; // 48 bytes
+ private var clientRandom:ByteArray; // 32 bytes
+ private var serverRandom:ByteArray; // 32 bytes
+ private var pad_1:ByteArray; // varies
+ private var pad_2:ByteArray; // varies
+ private var ignoreCNMismatch:Boolean = true;
+ private var trustAllCerts:Boolean = false;
+ private var trustSelfSigned:Boolean = false;
+ public static const PROTOCOL_VERSION:uint = 0x0300;
+
+ // not strictly speaking part of this, but yeah.
+ public var keyExchange:uint;
+
+ public function get version() : uint {
+ return PROTOCOL_VERSION;
+ }
+ public function SSLSecurityParameters(entity:uint, localCert:ByteArray = null, localKey:ByteArray = null) {
+ this.entity = entity;
+ reset();
+ }
+
+ public function reset():void {
+ bulkCipher = BulkCiphers.NULL;
+ cipherType = BulkCiphers.BLOCK_CIPHER;
+ macAlgorithm = MACs.NULL;
+ compression = COMPRESSION_NULL;
+ masterSecret = null;
+ }
+
+ public function getBulkCipher():uint {
+ return bulkCipher;
+ }
+ public function getCipherType():uint {
+ return cipherType;
+ }
+ public function getMacAlgorithm():uint {
+ return macAlgorithm;
+ }
+
+ public function setCipher(cipher:uint):void {
+ bulkCipher = CipherSuites.getBulkCipher(cipher);
+ cipherType = BulkCiphers.getType(bulkCipher);
+ keySize = BulkCiphers.getExpandedKeyBytes(bulkCipher); // 8
+ keyMaterialLength = BulkCiphers.getKeyBytes(bulkCipher); // 5
+ IVSize = BulkCiphers.getIVSize(bulkCipher);
+
+
+ keyExchange = CipherSuites.getKeyExchange(cipher);
+
+ macAlgorithm = CipherSuites.getMac(cipher);
+ hashSize = MACs.getHashSize(macAlgorithm);
+ pad_1 = new ByteArray();
+ pad_2 = new ByteArray();
+ for (var x:int = 0; x < 48; x++) {
+ pad_1.writeByte(0x36);
+ pad_2.writeByte(0x5c);
+ }
+ }
+ public function setCompression(algo:uint):void {
+ compression = algo;
+ }
+
+ public function setPreMasterSecret(secret:ByteArray):void {
+ /* Warning! Following code may cause madness
+ Tread not here, unless ye be men of valor.
+
+ ***** Official Prophylactic Comment ******
+ (to protect the unwary...this code actually works, that's all you need to know)
+
+ This does two things, computes the master secret, and generates the keyBlock
+
+
+ To compute the master_secret, the following algorithm is used.
+ for SSL 3, this means
+ master = MD5( premaster + SHA1('A' + premaster + client_random + server_random ) ) +
+ MD5( premaster + SHA1('BB' + premaster + client_random + server_random ) ) +
+ MD5( premaster + SHA1('CCC' + premaster + client_random + server_random ) )
+ */
+ var tempHashA:ByteArray = new ByteArray(); // temporary hash, gets reused a lot
+ var tempHashB:ByteArray = new ByteArray(); // temporary hash, gets reused a lot
+
+ var shaHash:ByteArray;
+ var mdHash:ByteArray;
+
+ var i:int;
+ var j:int;
+
+ var sha:SHA1 = new SHA1();
+ var md:MD5 = new MD5();
+
+ var k:ByteArray = new ByteArray();
+
+ k.writeBytes(secret);
+ k.writeBytes(clientRandom);
+ k.writeBytes(serverRandom);
+
+ masterSecret = new ByteArray();
+ var pad_char:uint = 0x41;
+
+ for ( i = 0; i < 3; i++) {
+ // SHA portion
+ tempHashA.position = 0;
+
+ for ( j = 0; j < i + 1; j++) {
+ tempHashA.writeByte(pad_char);
+ }
+ pad_char++;
+
+ tempHashA.writeBytes(k);
+ shaHash = sha.hash(tempHashA);
+
+ // MD5 portion
+ tempHashB.position = 0;
+ tempHashB.writeBytes(secret);
+ tempHashB.writeBytes(shaHash);
+ mdHash = md.hash(tempHashB);
+
+ // copy into my key
+ masterSecret.writeBytes(mdHash);
+ }
+
+ // *************** END MASTER SECRET **************
+
+ // More prophylactic comments
+ // *************** START KEY BLOCK ****************
+
+ // So here, I'm setting up the keyBlock array that I will derive MACs, keys, and IVs from.
+ // Rebuild k (hash seed)
+
+ k.position = 0;
+ k.writeBytes(masterSecret);
+ k.writeBytes(serverRandom);
+ k.writeBytes(clientRandom);
+
+ keyBlock = new ByteArray();
+
+ tempHashA = new ByteArray();
+ tempHashB = new ByteArray();
+ // now for 16 iterations to get 256 bytes (16 * 16), better to have more than not enough
+ pad_char = 0x41;
+ for ( i = 0; i < 16; i++) {
+ tempHashA.position = 0;
+
+ for ( j = 0; j < i + 1; j++) {
+ tempHashA.writeByte(pad_char);
+ }
+ pad_char++;
+ tempHashA.writeBytes(k);
+ shaHash = sha.hash(tempHashA);
+
+ tempHashB.position = 0;
+ tempHashB.writeBytes(masterSecret);
+ tempHashB.writeBytes(shaHash, 0);
+ mdHash = md.hash(tempHashB);
+
+ keyBlock.writeBytes(mdHash);
+ }
+ }
+
+ public function setClientRandom(secret:ByteArray):void {
+ clientRandom = secret;
+ }
+ public function setServerRandom(secret:ByteArray):void {
+ serverRandom = secret;
+ }
+
+ public function get useRSA():Boolean {
+ return KeyExchanges.useRSA(keyExchange);
+ }
+
+ // This is the Finished message
+ // if you value your sanity, stay away...far away
+ public function computeVerifyData(side:uint, handshakeMessages:ByteArray):ByteArray {
+ // for SSL 3.0, this consists of
+ // finished = md5( masterSecret + pad2 + md5( handshake + sender + masterSecret + pad1 ) ) +
+ // sha1( masterSecret + pad2 + sha1( handshake + sender + masterSecret + pad1 ) )
+
+ // trace("Handshake messages: " + Hex.fromArray(handshakeMessages));
+ var sha:SHA1 = new SHA1();
+ var md:MD5 = new MD5();
+ var k:ByteArray = new ByteArray(); // handshake + sender + masterSecret + pad1
+ var j:ByteArray = new ByteArray(); // masterSecret + pad2 + k
+
+ var innerKey:ByteArray;
+ var outerKey:ByteArray = new ByteArray();
+
+ var hashSha:ByteArray;
+ var hashMD:ByteArray;
+
+ var sideBytes:ByteArray = new ByteArray();
+ if (side == TLSEngine.CLIENT) {
+ sideBytes.writeUnsignedInt(0x434C4E54);
+ } else {
+ sideBytes.writeUnsignedInt(0x53525652);
+ }
+
+ // Do the SHA1 part of the routine first
+ masterSecret.position = 0;
+ k.writeBytes(handshakeMessages);
+ k.writeBytes(sideBytes);
+ k.writeBytes(masterSecret);
+ k.writeBytes(pad_1, 0, 40); // limited to 40 chars for SHA1
+
+ innerKey = sha.hash(k);
+ // trace("Inner SHA Key: " + Hex.fromArray(innerKey));
+
+ j.writeBytes(masterSecret);
+ j.writeBytes(pad_2, 0, 40); // limited to 40 chars for SHA1
+ j.writeBytes(innerKey);
+
+ hashSha = sha.hash(j);
+ // trace("Outer SHA Key: " + Hex.fromArray(hashSha));
+
+ // Rebuild k for MD5
+ k = new ByteArray();
+
+ k.writeBytes(handshakeMessages);
+ k.writeBytes(sideBytes);
+ k.writeBytes(masterSecret);
+ k.writeBytes(pad_1); // Take the whole length of pad_1 & pad_2 for MD5
+
+ innerKey = md.hash(k);
+ // trace("Inner MD5 Key: " + Hex.fromArray(innerKey));
+
+ j = new ByteArray();
+ j.writeBytes(masterSecret);
+ j.writeBytes(pad_2); // see above re: 48 byte pad
+ j.writeBytes(innerKey);
+
+ hashMD = md.hash(j);
+ // trace("Outer MD5 Key: " + Hex.fromArray(hashMD));
+
+ outerKey.writeBytes(hashMD, 0, hashMD.length);
+ outerKey.writeBytes(hashSha, 0, hashSha.length);
+ var out:String = Hex.fromArray(outerKey);
+ // trace("Finished Message: " + out);
+ outerKey.position = 0;
+
+ return outerKey;
+
+ }
+
+ public function computeCertificateVerify( side:uint, handshakeMessages:ByteArray ):ByteArray {
+ // TODO: Implement this, but I don't forsee it being necessary at this point in time, since for purposes
+ // of the override, I'm only going to use TLS
+ return null;
+ }
+
+ public function getConnectionStates():Object {
+
+ if (masterSecret != null) {
+ // so now, I have to derive the actual keys from the keyblock that I generated in setPremasterSecret.
+ // for MY purposes, I need RSA-AES 128/256 + SHA
+ // so I'm gonna have keylen = 32, minlen = 32, mac_length = 20, iv_length = 16
+ // but...I can get this data from the settings returned in the constructor when this object is
+ // It strikes me that TLS does this more elegantly...
+
+ var mac_length:int = hashSize as Number;
+ var key_length:int = keySize as Number;
+ var iv_length:int = IVSize as Number;
+
+ var client_write_MAC:ByteArray = new ByteArray();
+ var server_write_MAC:ByteArray = new ByteArray();
+ var client_write_key:ByteArray = new ByteArray();
+ var server_write_key:ByteArray = new ByteArray();
+ var client_write_IV:ByteArray = new ByteArray();
+ var server_write_IV:ByteArray = new ByteArray();
+
+ // Derive the keys from the keyblock
+ // Get the MACs first
+ keyBlock.position = 0;
+ keyBlock.readBytes(client_write_MAC, 0, mac_length);
+ keyBlock.readBytes(server_write_MAC, 0, mac_length);
+
+ // keyBlock.position is now at MAC_length * 2
+ // then get the keys
+ keyBlock.readBytes(client_write_key, 0, key_length);
+ keyBlock.readBytes(server_write_key, 0, key_length);
+
+ // keyBlock.position is now at (MAC_length * 2) + (keySize * 2)
+ // and then the IVs
+ keyBlock.readBytes(client_write_IV, 0, iv_length);
+ keyBlock.readBytes(server_write_IV, 0, iv_length);
+
+ // reset this in case it's needed, for some reason or another, but I doubt it
+ keyBlock.position = 0;
+
+ var client_write:SSLConnectionState = new SSLConnectionState(
+ bulkCipher, cipherType, macAlgorithm,
+ client_write_MAC, client_write_key, client_write_IV);
+ var server_write:SSLConnectionState = new SSLConnectionState(
+ bulkCipher, cipherType, macAlgorithm,
+ server_write_MAC, server_write_key, server_write_IV);
+
+ if (entity == TLSEngine.CLIENT) {
+ return {read:server_write, write:client_write};
+ } else {
+ return {read:client_write, write:server_write};
+ }
+
+
+ } else {
+ return {read:new SSLConnectionState, write:new SSLConnectionState};
+ }
+ }
+
+ }
+}
\ No newline at end of file diff --git a/flash-src/third-party/com/hurlant/crypto/tls/TLSConfig.as b/flash-src/third-party/com/hurlant/crypto/tls/TLSConfig.as new file mode 100644 index 0000000..2cd1d27 --- /dev/null +++ b/flash-src/third-party/com/hurlant/crypto/tls/TLSConfig.as @@ -0,0 +1,70 @@ +/**
+ * TLSConfig
+ *
+ * A set of configuration parameters for use by a TLSSocket or a TLSEngine.
+ * Most parameters are optional and will be set to appropriate default values for most use.
+ *
+ * Copyright (c) 2007 Henri Torgemane
+ *
+ * See LICENSE.txt for full license information.
+ */
+package com.hurlant.crypto.tls {
+ import flash.utils.ByteArray;
+ import com.hurlant.util.der.PEM;
+ import com.hurlant.crypto.rsa.RSAKey;
+ import com.hurlant.crypto.cert.X509CertificateCollection;
+ import com.hurlant.crypto.cert.MozillaRootCertificates;
+
+ public class TLSConfig {
+ public var entity:uint; // SERVER | CLIENT
+
+ public var certificate:ByteArray;
+ public var privateKey:RSAKey;
+
+ public var cipherSuites:Array;
+
+ public var compressions:Array;
+ public var ignoreCommonNameMismatch:Boolean = false;
+ public var trustAllCertificates:Boolean = false;
+ public var trustSelfSignedCertificates:Boolean = false;
+ public var promptUserForAcceptCert:Boolean = false;
+ public var CAStore:X509CertificateCollection;
+ public var localKeyStore:X509CertificateCollection;
+ public var version:uint;
+
+ public function TLSConfig( entity:uint, cipherSuites:Array = null, compressions:Array = null,
+ certificate:ByteArray = null, privateKey:RSAKey = null, CAStore:X509CertificateCollection = null, ver:uint = 0x00) {
+ this.entity = entity;
+ this.cipherSuites = cipherSuites;
+ this.compressions = compressions;
+ this.certificate = certificate;
+ this.privateKey = privateKey;
+ this.CAStore = CAStore;
+ this.version = ver;
+ // default settings.
+ if (cipherSuites==null) {
+ this.cipherSuites = CipherSuites.getDefaultSuites();
+ }
+ if (compressions==null) {
+ this.compressions = [TLSSecurityParameters.COMPRESSION_NULL];
+ }
+
+ if (CAStore==null) {
+ this.CAStore = new MozillaRootCertificates;
+ }
+
+ if (ver==0x00) {
+ // Default to TLS
+ this.version = TLSSecurityParameters.PROTOCOL_VERSION;
+ }
+ }
+
+ public function setPEMCertificate(cert:String, key:String = null):void {
+ if (key == null) {
+ key = cert; // for folks who like to concat those two in one file.
+ }
+ certificate = PEM.readCertIntoArray(cert);
+ privateKey = PEM.readRSAPrivateKey(key);
+ }
+ }
+}
diff --git a/flash-src/third-party/com/hurlant/crypto/tls/TLSConnectionState.as b/flash-src/third-party/com/hurlant/crypto/tls/TLSConnectionState.as new file mode 100644 index 0000000..0d09a6c --- /dev/null +++ b/flash-src/third-party/com/hurlant/crypto/tls/TLSConnectionState.as @@ -0,0 +1,151 @@ +/**
+ * TLSConnectionState
+ *
+ * This class encapsulates the read or write state of a TLS connection,
+ * and implementes the encrypting and hashing of packets.
+ * Copyright (c) 2007 Henri Torgemane
+ *
+ * See LICENSE.txt for full license information.
+ */
+package com.hurlant.crypto.tls {
+ import flash.utils.IDataInput;
+ import flash.utils.ByteArray;
+ import com.hurlant.crypto.hash.MD5;
+ import com.hurlant.crypto.hash.HMAC;
+ import com.hurlant.crypto.hash.IHash;
+ import com.hurlant.crypto.symmetric.ICipher;
+ import com.hurlant.crypto.symmetric.IVMode;
+ import com.hurlant.util.Hex;
+ import com.hurlant.util.ArrayUtil;
+
+ public class TLSConnectionState implements IConnectionState {
+
+
+ // compression state
+
+ // cipher state
+ private var bulkCipher:uint;
+ private var cipherType:uint;
+ private var CIPHER_key:ByteArray;
+ private var CIPHER_IV:ByteArray;
+ private var cipher:ICipher;
+ private var ivmode:IVMode;
+
+ // mac secret
+ private var macAlgorithm:uint;
+ private var MAC_write_secret:ByteArray;
+ private var hmac:HMAC;
+
+ // sequence number. uint64
+ private var seq_lo:uint;
+ private var seq_hi:uint;
+
+
+
+ public function TLSConnectionState(
+ bulkCipher:uint=0, cipherType:uint=0, macAlgorithm:uint=0,
+ mac:ByteArray=null, key:ByteArray=null, IV:ByteArray=null) {
+ this.bulkCipher = bulkCipher;
+ this.cipherType = cipherType;
+ this.macAlgorithm = macAlgorithm;
+ MAC_write_secret = mac;
+ hmac = MACs.getHMAC(macAlgorithm);
+ CIPHER_key = key;
+ CIPHER_IV = IV;
+ cipher = BulkCiphers.getCipher(bulkCipher, key, 0x0301);
+ if (cipher is IVMode) {
+ ivmode = cipher as IVMode;
+ ivmode.IV = IV;
+ }
+ }
+
+ public function decrypt(type:uint, length:uint, p:ByteArray):ByteArray {
+ // decompression is a nop.
+
+ if (cipherType == BulkCiphers.STREAM_CIPHER) {
+ if (bulkCipher == BulkCiphers.NULL) {
+ // no-op
+ } else {
+ cipher.decrypt(p);
+ }
+ } else {
+ // block cipher
+ var nextIV:ByteArray = new ByteArray;
+ nextIV.writeBytes(p, p.length-CIPHER_IV.length, CIPHER_IV.length);
+
+ cipher.decrypt(p);
+
+
+ CIPHER_IV = nextIV;
+ ivmode.IV = nextIV;
+ }
+ if (macAlgorithm!=MACs.NULL) {
+ var data:ByteArray = new ByteArray;
+ var len:uint = p.length - hmac.getHashSize();
+ data.writeUnsignedInt(seq_hi);
+ data.writeUnsignedInt(seq_lo);
+ data.writeByte(type);
+ data.writeShort(TLSSecurityParameters.PROTOCOL_VERSION);
+ data.writeShort(len);
+ if (len!=0) {
+ data.writeBytes(p, 0, len);
+ }
+ var mac:ByteArray = hmac.compute(MAC_write_secret, data);
+ // compare "mac" with the last X bytes of p.
+ var mac_received:ByteArray = new ByteArray;
+ mac_received.writeBytes(p, len, hmac.getHashSize());
+ if (ArrayUtil.equals(mac, mac_received)) {
+ // happy happy joy joy
+ } else {
+ throw new TLSError("Bad Mac Data", TLSError.bad_record_mac);
+ }
+ p.length = len;
+ p.position = 0;
+ }
+ // increment seq
+ seq_lo++;
+ if (seq_lo==0) seq_hi++;
+ return p;
+ }
+ public function encrypt(type:uint, p:ByteArray):ByteArray {
+ var mac:ByteArray = null;
+ if (macAlgorithm!=MACs.NULL) {
+ var data:ByteArray = new ByteArray;
+ data.writeUnsignedInt(seq_hi);
+ data.writeUnsignedInt(seq_lo);
+ data.writeByte(type);
+ data.writeShort(TLSSecurityParameters.PROTOCOL_VERSION);
+ data.writeShort(p.length);
+ if (p.length!=0) {
+ data.writeBytes(p, 0, p.length);
+ }
+ mac = hmac.compute(MAC_write_secret, data);
+ p.position = p.length;
+ p.writeBytes(mac);
+ }
+ p.position = 0;
+ if (cipherType == BulkCiphers.STREAM_CIPHER) {
+ // stream cipher
+ if (bulkCipher == BulkCiphers.NULL) {
+ // no-op
+ } else {
+ cipher.encrypt(p);
+ }
+ } else {
+ // block cipher
+ cipher.encrypt(p);
+ // adjust IV
+ var nextIV:ByteArray = new ByteArray;
+ nextIV.writeBytes(p, p.length-CIPHER_IV.length, CIPHER_IV.length);
+ CIPHER_IV = nextIV;
+ ivmode.IV = nextIV;
+ }
+ // increment seq
+ seq_lo++;
+ if (seq_lo==0) seq_hi++;
+ // compression is a nop.
+ return p;
+ }
+
+ }
+}
\ No newline at end of file diff --git a/flash-src/third-party/com/hurlant/crypto/tls/TLSEngine.as b/flash-src/third-party/com/hurlant/crypto/tls/TLSEngine.as new file mode 100644 index 0000000..72f3941 --- /dev/null +++ b/flash-src/third-party/com/hurlant/crypto/tls/TLSEngine.as @@ -0,0 +1,895 @@ +/** + * TLSEngine + * + * A TLS protocol implementation. + * See comment below for some details. + * Copyright (c) 2007 Henri Torgemane + * + * Patched(heavily) by Bobby Parker (shortwave@gmail.com) + * + * See LICENSE.txt for full license information. + */ +package com.hurlant.crypto.tls { + import com.hurlant.crypto.cert.X509Certificate; + import com.hurlant.crypto.cert.X509CertificateCollection; + import com.hurlant.crypto.prng.Random; + import com.hurlant.util.ArrayUtil; + import com.hurlant.util.Hex; + + import flash.events.Event; + import flash.events.EventDispatcher; + import flash.events.ProgressEvent; + import flash.utils.ByteArray; + import flash.utils.IDataInput; + import flash.utils.IDataOutput; + import flash.utils.clearTimeout; + import flash.utils.setTimeout; + import com.hurlant.crypto.prng.ARC4; + + + [Event(name="close", type="flash.events.Event")] + [Event(name="socketData", type="flash.events.ProgressEvent")] + [Event(name="ready", type="com.hurlant.crypto.tls.TLSEvent")] + [Event(name="data", type="com.hurlant.crypto.tls.TLSEvent")] + + /** + * The heart of the TLS protocol. + * This class can work in server or client mode. + * + * This doesn't fully implement the TLS protocol. + * + * Things missing that I'd like to add: + * - support for client-side certificates + * - general code clean-up to make sure we don't have gaping securite holes + * + * Things that aren't there that I won't add: + * - support for "export" cypher suites (deprecated in later TLS versions) + * - support for "anon" cypher suites (deprecated in later TLS versions) + * + * Things that I'm unsure about adding later: + * - compression. Compressing encrypted streams is barely worth the CPU cycles. + * - diffie-hellman based key exchange mechanisms. Nifty, but would we miss it? + * + * @author henri + * + */ + public class TLSEngine extends EventDispatcher { + + public static const SERVER:uint = 0; + public static const CLIENT:uint = 1; + public var protocol_version:uint; + + + + private static const PROTOCOL_HANDSHAKE:uint = 22; + private static const PROTOCOL_ALERT:uint = 21; + private static const PROTOCOL_CHANGE_CIPHER_SPEC:uint = 20; + private static const PROTOCOL_APPLICATION_DATA:uint = 23; + + + private static const STATE_NEW:uint = 0; // brand new. nothing happened yet + private static const STATE_NEGOTIATING:uint = 1; // we're figuring out what to use + private static const STATE_READY:uint = 2; // we're ready for AppData stuff to go over us. + private static const STATE_CLOSED:uint = 3; // we're done done. + + private var _entity:uint; // SERVER | CLIENT + private var _config:TLSConfig; + + private var _state:uint; + + private var _securityParameters:ISecurityParameters; + + private var _currentReadState:IConnectionState; + private var _currentWriteState:IConnectionState; + private var _pendingReadState:IConnectionState; + private var _pendingWriteState:IConnectionState; + + private var _handshakePayloads:ByteArray; + private var _handshakeRecords:ByteArray; // For client-side certificate verify + + private var _iStream:IDataInput; + private var _oStream:IDataOutput; + + // temporary store for X509 certs received by this engine. + private var _store:X509CertificateCollection; + // the main certificate received from the other side. + private var _otherCertificate:X509Certificate; + + public function get peerCertificate() : X509Certificate { + return _otherCertificate; + } + // If this isn't null, we expect this identity to be found in the Cert's Subject CN. + private var _otherIdentity:String; + + // The client-side cert + private var _myCertficate:X509Certificate; + // My Identity + private var _myIdentity:String; + + /** + * + * @param config A TLSConfig instance describing how we're supposed to work + * @param iStream An input stream to read TLS data from + * @param oStream An output stream to write TLS data to + * @param otherIdentity An optional identifier. If set, this will be checked against the Subject CN of the other side's certificate. + * + */ + function TLSEngine(config:TLSConfig, iStream:IDataInput, oStream:IDataOutput, otherIdentity:String = null) { + _entity = config.entity; + _config = config; + _iStream = iStream; + _oStream = oStream; + _otherIdentity = otherIdentity; + + _state = STATE_NEW; + + // Pick the right set of callbacks + _entityHandshakeHandlers = _entity == CLIENT ? handshakeHandlersClient : handshakeHandlersServer; + + // setting up new security parameters needs to be controlled by...something. + if (_config.version == SSLSecurityParameters.PROTOCOL_VERSION) { + _securityParameters = new SSLSecurityParameters(_entity); + } else { + _securityParameters = new TLSSecurityParameters(_entity, _config.certificate, _config.privateKey); + } + protocol_version = _config.version; + + // So this...why is it here, other than to preclude a possible null pointer situation? + var states:Object = _securityParameters.getConnectionStates(); + + _currentReadState = states.read; + _currentWriteState = states.write; + + _handshakePayloads = new ByteArray; + + _store = new X509CertificateCollection; + } + + /** + * This starts the TLS negotiation for a TLS Client. + * + * This is a no-op for a TLS Server. + * + */ + public function start():void { + if (_entity == CLIENT) { + try { + startHandshake(); + } catch (e:TLSError) { + handleTLSError(e); + } + } + } + + + public function dataAvailable(e:* = null):void { + if (_state == STATE_CLOSED) return; // ignore + try { + parseRecord(_iStream); + } catch (e:TLSError) { + handleTLSError(e); + } + } + + public function close(e:TLSError = null):void { + if (_state == STATE_CLOSED) return; // ignore + // ok. send an Alert to let the peer know + var rec:ByteArray = new ByteArray; + if (e==null && _state != STATE_READY) { + // use canceled while handshaking. be nice about it + rec[0] = 1; + rec[1] = TLSError.user_canceled; + sendRecord(PROTOCOL_ALERT, rec); + } + rec[0] = 2; + if (e == null) { + rec[1] = TLSError.close_notify; + } else { + rec[1] = e.errorID; + trace("TLSEngine shutdown triggered by "+e); + } + sendRecord(PROTOCOL_ALERT, rec); + + _state = STATE_CLOSED; + dispatchEvent(new Event(Event.CLOSE)); + } + + private var _packetQueue:Array = []; + private function parseRecord(stream:IDataInput):void { + var p:ByteArray; + while(_state!=STATE_CLOSED && stream.bytesAvailable>4) { + + if (_packetQueue.length>0) { + var packet:Object = _packetQueue.shift(); + p = packet.data; + if (stream.bytesAvailable+p.length>=packet.length) { + // we have a whole packet. put together. + stream.readBytes(p, p.length, packet.length-p.length); + parseOneRecord(packet.type, packet.length, p); + // do another loop to parse any leftover record + continue; + } else { + // not enough. grab the data and park it. + stream.readBytes(p, p.length, stream.bytesAvailable); + _packetQueue.push(packet); + continue; + } + } + + + var type:uint = stream.readByte(); + var ver:uint = stream.readShort(); + var length:uint = stream.readShort(); + if (length>16384+2048) { // support compression and encryption overhead. + throw new TLSError("Excessive TLS Record length: "+length, TLSError.record_overflow); + } + // Can pretty much assume that if I'm here, I've got a default config, so let's use it. + if (ver != _securityParameters.version ) { + throw new TLSError("Unsupported TLS version: "+ver.toString(16), TLSError.protocol_version); + } + + p = new ByteArray; + var actualLength:uint = Math.min(stream.bytesAvailable, length); + stream.readBytes(p, 0, actualLength); + if (actualLength == length) { + parseOneRecord(type, length, p); + } else { + _packetQueue.push({type:type, length:length, data:p}); + } + } + } + + + // Protocol handler map, provides a mapping of protocol types to individual packet handlers + private var protocolHandlers:Object = { 23 : parseApplicationData, // PROTOCOL_APPLICATION_DATA + 22 : parseHandshake, // PROTOCOL_HANDSHAKE + 21 : parseAlert, // PROTOCOL_ALERT + 20 : parseChangeCipherSpec }; // PROTOCOL_CHANGE_CIPHER_SPEC + + /** + * Modified to support the notion of a handler map(see above ), since it makes for better clarity (IMHO of course). + */ + private function parseOneRecord(type:uint, length:uint, p:ByteArray):void { + p = _currentReadState.decrypt(type, length, p); + if (p.length>16384) { + throw new TLSError("Excessive Decrypted TLS Record length: "+p.length, TLSError.record_overflow); + } + if (protocolHandlers.hasOwnProperty( type )) { + while( p != null) + p = protocolHandlers[ type ]( p ); + } else { + throw new TLSError("Unsupported TLS Record Content Type: "+type.toString( 16 ), TLSError.unexpected_message); + } + } + + ///////// handshake handling + // session identifier + // peer certificate + // compression method + // cipher spec + // master secret + // is resumable + private static const HANDSHAKE_HELLO_REQUEST:uint = 0; + private static const HANDSHAKE_CLIENT_HELLO:uint = 1; + private static const HANDSHAKE_SERVER_HELLO:uint = 2; + private static const HANDSHAKE_CERTIFICATE:uint = 11; + private static const HANDSHAKE_SERVER_KEY_EXCHANGE:uint = 12; + private static const HANDSHAKE_CERTIFICATE_REQUEST:uint = 13; + private static const HANDSHAKE_HELLO_DONE:uint = 14; + private static const HANDSHAKE_CERTIFICATE_VERIFY:uint = 15; + private static const HANDSHAKE_CLIENT_KEY_EXCHANGE:uint = 16; + private static const HANDSHAKE_FINISHED:uint = 20; + + // Server handshake handler map + private var handshakeHandlersServer:Object = { 0 : notifyStateError, // HANDSHAKE_HELLO_REQUEST + 1 : parseHandshakeClientHello, // HANDSHAKE_CLIENT_HELLO + 2 : notifyStateError, // HANDSHAKE_SERVER_HELLO + 11 : loadCertificates, // HANDSHAKE_CERTIFICATE + 12 : notifyStateError, // HANDSHAKE_SERVER_KEY_EXCHANGE + 13 : notifyStateError, // HANDSHAKE_CERTIFICATE_REQUEST + 14 : notifyStateError, // HANDSHAKE_HELLO_DONE + 15 : notifyStateError, // HANDSHAKE_CERTIFICATE_VERIFY + 16 : parseHandshakeClientKeyExchange, // HANDSHAKE_CLIENT_KEY_EXCHANGE + 20 : verifyHandshake // HANDSHAKE_FINISHED + }; + + // Client handshake handler map + private var handshakeHandlersClient:Object = { 0 : parseHandshakeHello, // HANDSHAKE_HELLO_REQUEST + 1 : notifyStateError, // HANDSHAKE_CLIENT_HELLO + 2 : parseHandshakeServerHello, // HANDSHAKE_SERVER_HELLO + 11 : loadCertificates, // HANDSHAKE_CERTIFICATE + 12 : parseServerKeyExchange, // HANDSHAKE_SERVER_KEY_EXCHANGE + 13 : setStateRespondWithCertificate, // HANDSHAKE_CERTIFICATE + 14 : sendClientAck, // HANDSHAKE_HELLO_DONE + 15 : notifyStateError, // HANDSHAKE_CERTIFICATE_VERIFY + 16 : notifyStateError, // HANDSHAKE_CLIENT_KEY_EXCHANGE + 20 : verifyHandshake // HANDSHAKE_FINISHED + }; + private var _entityHandshakeHandlers:Object; + private var _handshakeCanContinue:Boolean = true; // For handling cases where I might need to pause processing during a handshake (cert issues, etc.). + private var _handshakeQueue:Array = []; + /** + * The handshake is always started by the client. + */ + private function startHandshake():void { + _state = STATE_NEGOTIATING; + // reset some other handshake state. XXX + sendClientHello(); + } + + /** + * Handle the incoming handshake packet. + * + */ + private function parseHandshake(p:ByteArray):ByteArray { + + if (p.length<4) { + trace("Handshake packet is way too short. bailing."); + return null; + } + + p.position = 0; + + var rec:ByteArray = p; + var type:uint = rec.readUnsignedByte(); + var tmp:uint = rec.readUnsignedByte(); + var length:uint = (tmp<<16) | rec.readUnsignedShort(); + if (length+4>p.length) { + // partial read. + trace("Handshake packet is incomplete. bailing."); + return null; + } + + // we need to copy the record, to have a valid FINISHED exchange. + if (type!=HANDSHAKE_FINISHED) { + _handshakePayloads.writeBytes(p, 0, length+4); + } + + // Surf the handler map and find the right handler for this handshake packet type. + // I modified the individual handlers so they encapsulate all possible knowledge + // about the incoming packet type, so no previous handling or massaging of the data + // is required, as was the case using the switch statement. BP + if (_entityHandshakeHandlers.hasOwnProperty( type )) { + if (_entityHandshakeHandlers[ type ] is Function) + _entityHandshakeHandlers[ type ]( rec ); + } else { + throw new TLSError( "Unimplemented or unknown handshake type!", TLSError.internal_error ); + } + + // Get set up for the next packet. + if (length+4<p.length) { + var n:ByteArray = new ByteArray; + n.writeBytes(p,length+4, p.length-(length+4)); + return n; + } else { + return null; + } + } + + /** + * Throw an error when the detected handshake state isn't a valid state for the given entity type (client vs. server, etc. ). + * This really should abort the handshake, since there's no case in which a server should EVER be confused about the type of entity it is. BP + */ + private function notifyStateError( rec:ByteArray ) : void { + throw new TLSError( "Invalid handshake state for a TLS Entity type of " + _entity, TLSError.internal_error ); + } + + /** + * two unimplemented functions + */ + private function parseClientKeyExchange( rec:ByteArray ) : void { + throw new TLSError( "ClientKeyExchange is currently unimplemented!", TLSError.internal_error ); + } + + private function parseServerKeyExchange( rec:ByteArray ) : void { + throw new TLSError( "ServerKeyExchange is currently unimplemented!", TLSError.internal_error ); + } + + /** + * Test the server's Finished message for validity against the data we know about. Only slightly rewritten. BP + */ + private function verifyHandshake( rec:ByteArray):void { + // Get the Finished message + var verifyData:ByteArray = new ByteArray; + // This, in the vain hope that noboby is using SSL 2 anymore + if (_securityParameters.version == SSLSecurityParameters.PROTOCOL_VERSION) { + rec.readBytes(verifyData, 0, 36); // length should be (in fact, better be) 16 + 20 (md5-size + sha1-size) + } else { // presuming TLS + rec.readBytes(verifyData, 0, 12); + } + + var data:ByteArray = _securityParameters.computeVerifyData(1-_entity, _handshakePayloads); + + if (ArrayUtil.equals(verifyData, data)) { + _state = STATE_READY; + dispatchEvent(new TLSEvent(TLSEvent.READY)); + } else { + throw new TLSError("Invalid Finished mac.", TLSError.bad_record_mac); + } + } + + // enforceClient/enforceServer removed in favor of state-driven function maps + + /** + * Handle a HANDSHAKE_HELLO + */ + private function parseHandshakeHello( rec:ByteArray ) : void { + if (_state != STATE_READY) { + trace("Received an HELLO_REQUEST before being in state READY. ignoring."); + return; + } + _handshakePayloads = new ByteArray; + startHandshake(); + } + + /** + * Handle a HANDSHAKE_CLIENT_KEY_EXCHANGE + */ + private function parseHandshakeClientKeyExchange(rec:ByteArray):void { + if (_securityParameters.useRSA) { + // skip 2 bytes for length. + var len:uint = rec.readShort(); + var cipher:ByteArray = new ByteArray; + rec.readBytes(cipher, 0, len); + var preMasterSecret:ByteArray = new ByteArray; + _config.privateKey.decrypt(cipher, preMasterSecret, len); + _securityParameters.setPreMasterSecret(preMasterSecret); + + // now is a good time to get our pending states + var o:Object = _securityParameters.getConnectionStates(); + _pendingReadState = o.read; + _pendingWriteState = o.write; + + } else { + throw new TLSError("parseHandshakeClientKeyExchange not implemented for DH modes.", TLSError.internal_error); + } + + } + + /** + * Handle HANDSHAKE_SERVER_HELLO - client-side + */ + private function parseHandshakeServerHello( rec:IDataInput ) : void { + + var ver:uint = rec.readShort(); + if (ver != _securityParameters.version) { + throw new TLSError("Unsupported TLS version: "+ver.toString(16), TLSError.protocol_version); + } + var random:ByteArray = new ByteArray; + rec.readBytes(random, 0, 32); + var session_length:uint = rec.readByte(); + var session:ByteArray = new ByteArray; + if (session_length > 0) { + // some implementations don't assign a session ID + rec.readBytes(session, 0, session_length); + } + + _securityParameters.setCipher(rec.readShort()); + _securityParameters.setCompression(rec.readByte()); + _securityParameters.setServerRandom(random); + } + + /** + * Handle HANDSHAKE_CLIENT_HELLO - server side + */ + private function parseHandshakeClientHello( rec:IDataInput ) : void { + var ret:Object; + var ver:uint = rec.readShort(); + if (ver != _securityParameters.version) { + throw new TLSError("Unsupported TLS version: "+ver.toString(16), TLSError.protocol_version); + } + + var random:ByteArray = new ByteArray; + rec.readBytes(random, 0, 32); + var session_length:uint = rec.readByte(); + var session:ByteArray = new ByteArray; + if (session_length > 0) { + // some implementations don't assign a session ID + rec.readBytes(session, 0, session_length); + } + var suites:Array = []; + + var suites_length:uint = rec.readShort(); + for (var i:uint=0;i<suites_length/2;i++) { + suites.push(rec.readShort()); + } + + var compressions:Array = []; + + var comp_length:uint = rec.readByte(); + for (i=0;i<comp_length;i++) { + compressions.push(rec.readByte()); + } + + ret = {random:random, session:session, suites:suites, compressions:compressions}; + + var sofar:uint = 2+32+1+session_length+2+suites_length+1+comp_length; + var extensions:Array = []; + if (sofar<length) { + // we have extensions. great. + var ext_total_length:uint = rec.readShort(); + while (ext_total_length>0) { + var ext_type:uint = rec.readShort(); + var ext_length:uint = rec.readShort(); + var ext_data:ByteArray = new ByteArray; + rec.readBytes(ext_data, 0, ext_length); + ext_total_length -= 4+ext_length; + extensions.push({type:ext_type, length:ext_length, data:ext_data}); + } + } + ret.ext = extensions; + + sendServerHello(ret); + sendCertificate(); + // TODO: Modify to handle case of requesting a certificate from the client, for "client authentication", + // and testing purposes, will probably never actually need it. + sendServerHelloDone(); + } + + private function sendClientHello():void { + var rec:ByteArray = new ByteArray; + // version - modified to support version attribute from ISecurityParameters + rec.writeShort(_securityParameters.version); + // random + var prng:Random = new Random; + var clientRandom:ByteArray = new ByteArray; + prng.nextBytes(clientRandom, 32); + _securityParameters.setClientRandom(clientRandom); + rec.writeBytes(clientRandom,0,32); + // session + rec.writeByte(32); + prng.nextBytes(rec, 32); + // Cipher suites + var cs:Array = _config.cipherSuites; + rec.writeShort(2* cs.length); + for (var i:int=0;i<cs.length;i++) { + rec.writeShort(cs[i]); + } + // Compression + cs = _config.compressions; + rec.writeByte(cs.length); + for (i=0;i<cs.length;i++) { + rec.writeByte(cs[i]); + } + // no extensions, yet. + rec.position = 0; + sendHandshake(HANDSHAKE_CLIENT_HELLO, rec.length, rec); + } + + private function findMatch(a1:Array, a2:Array):int { + for (var i:int=0;i<a1.length;i++) { + var e:uint = a1[i]; + if (a2.indexOf(e)>-1) { + return e; + } + } + return -1; + } + + private function sendServerHello(v:Object):void { + var cipher:int = findMatch(_config.cipherSuites, v.suites); + if (cipher == -1) { + throw new TLSError("No compatible cipher found.", TLSError.handshake_failure); + } + _securityParameters.setCipher(cipher); + + var comp:int = findMatch(_config.compressions, v.compressions); + if (comp == 01) { + throw new TLSError("No compatible compression method found.", TLSError.handshake_failure); + } + _securityParameters.setCompression(comp); + _securityParameters.setClientRandom(v.random); + + + var rec:ByteArray = new ByteArray; + rec.writeShort(_securityParameters.version); + var prng:Random = new Random; + var serverRandom:ByteArray = new ByteArray; + prng.nextBytes(serverRandom, 32); + _securityParameters.setServerRandom(serverRandom); + rec.writeBytes(serverRandom,0,32); + // session + rec.writeByte(32); + prng.nextBytes(rec, 32); + // Cipher suite + rec.writeShort(v.suites[0]); + // Compression + rec.writeByte(v.compressions[0]); + rec.position = 0; + sendHandshake(HANDSHAKE_SERVER_HELLO, rec.length, rec); + } + + private var sendClientCert:Boolean = false; + private function setStateRespondWithCertificate( r:ByteArray = null) : void { + sendClientCert = true; + } + + private function sendCertificate( r:ByteArray = null ):void { + var cert:ByteArray = _config.certificate; + var len:uint; + var len2:uint; + var rec:ByteArray = new ByteArray; + // Look for a certficate chain, if we have one, send it, if we don't, send an empty record. + if (cert != null) { + len = cert.length; + len2 = cert.length + 3; + rec.writeByte(len2>>16); + rec.writeShort(len2&65535); + rec.writeByte(len>>16); + rec.writeShort(len&65535); + rec.writeBytes(cert); + } else { + rec.writeShort( 0 ); + rec.writeByte( 0 ); + } + rec.position = 0; + sendHandshake(HANDSHAKE_CERTIFICATE, rec.length, rec); + } + + private function sendCertificateVerify():void { + var rec:ByteArray = new ByteArray(); + // Encrypt the handshake payloads here + var data:ByteArray = _securityParameters.computeCertificateVerify(_entity, _handshakePayloads); + data.position=0; + sendHandshake(HANDSHAKE_CERTIFICATE_VERIFY, data.length, data); + } + + private function sendServerHelloDone():void { + var rec:ByteArray = new ByteArray; + sendHandshake(HANDSHAKE_HELLO_DONE, rec.length, rec); + } + + private function sendClientKeyExchange():void { + if (_securityParameters.useRSA) { + var p:ByteArray = new ByteArray; + p.writeShort(_securityParameters.version); + var prng:Random = new Random; + prng.nextBytes(p, 46); + p.position = 0; + + var preMasterSecret:ByteArray = new ByteArray; + preMasterSecret.writeBytes(p, 0, p.length); + preMasterSecret.position = 0; + _securityParameters.setPreMasterSecret(preMasterSecret); + + var enc_key:ByteArray = new ByteArray; + _otherCertificate.getPublicKey().encrypt(preMasterSecret, enc_key, preMasterSecret.length); + + enc_key.position = 0; + var rec:ByteArray = new ByteArray; + + // TLS requires the size of the premaster key be sent BUT + // SSL 3.0 does not + if (_securityParameters.version > 0x0300) { + rec.writeShort(enc_key.length); + } + rec.writeBytes(enc_key, 0, enc_key.length); + + rec.position=0; + + sendHandshake(HANDSHAKE_CLIENT_KEY_EXCHANGE, rec.length, rec); + + // now is a good time to get our pending states + var o:Object = _securityParameters.getConnectionStates(); + _pendingReadState = o.read; + _pendingWriteState = o.write; + + } else { + throw new TLSError("Non-RSA Client Key Exchange not implemented.", TLSError.internal_error); + } + } + private function sendFinished():void { + var data:ByteArray = _securityParameters.computeVerifyData(_entity, _handshakePayloads); + data.position=0; + sendHandshake(HANDSHAKE_FINISHED, data.length, data); + } + + private function sendHandshake(type:uint, len:uint, payload:IDataInput):void { + var rec:ByteArray = new ByteArray; + rec.writeByte(type); + rec.writeByte(0); + rec.writeShort(len); + payload.readBytes(rec, rec.position, len); + _handshakePayloads.writeBytes(rec, 0, rec.length); + sendRecord(PROTOCOL_HANDSHAKE, rec); + } + + private function sendChangeCipherSpec():void { + var rec:ByteArray = new ByteArray; + rec[0] = 1; + sendRecord(PROTOCOL_CHANGE_CIPHER_SPEC, rec); + + // right after, switch the cipher for writing. + _currentWriteState = _pendingWriteState; + _pendingWriteState = null; + } + + public function sendApplicationData(data:ByteArray, offset:uint=0, length:uint=0):void { + var rec:ByteArray = new ByteArray; + var len:uint = length; + // BIG FAT WARNING: Patch from Arlen Cuss ALA As3crypto group on Google code. + // This addresses data overflow issues when the packet size hits the max length boundary. + if (len == 0) len = data.length; + while (len>16384) { + rec.position = 0; + rec.writeBytes(data, offset, 16384); + rec.position = 0; + sendRecord(PROTOCOL_APPLICATION_DATA, rec); + offset += 16384; + len -= 16384; + } + rec.position = 0; + rec.writeBytes(data, offset, len); + // trace("Data I'm sending..." + Hex.fromArray( data )); + rec.position = 0; + sendRecord(PROTOCOL_APPLICATION_DATA, rec); + } + private function sendRecord(type:uint, payload:ByteArray):void { + // encrypt + payload = _currentWriteState.encrypt(type, payload); + + _oStream.writeByte(type); + _oStream.writeShort(_securityParameters.version); + _oStream.writeShort(payload.length); + _oStream.writeBytes(payload, 0, payload.length); + + scheduleWrite(); + } + + private var _writeScheduler:uint; + private function scheduleWrite():void { + if (_writeScheduler!=0) return; + _writeScheduler = setTimeout(commitWrite, 0); + } + private function commitWrite():void { + clearTimeout(_writeScheduler); + _writeScheduler = 0; + if (_state != STATE_CLOSED) { + dispatchEvent(new ProgressEvent(ProgressEvent.SOCKET_DATA)); + } + } + + private function sendClientAck( rec:ByteArray ):void { + if ( _handshakeCanContinue ) { + // If I have a pending cert request, send it + if (sendClientCert) + sendCertificate(); + // send a client key exchange + sendClientKeyExchange(); + // Send the certificate verify, if we have one + if (_config.certificate != null) + sendCertificateVerify(); + // send a change cipher spec + sendChangeCipherSpec(); + // send a finished + sendFinished(); + } + } + + /** + * Vaguely gross function that parses a RSA key out of a certificate. + * + * As long as that certificate looks just the way we expect it to. + * + */ + private function loadCertificates( rec:ByteArray ):void { + var tmp:uint = rec.readByte(); + var certs_len:uint = (tmp<<16) | rec.readShort(); + var certs:Array = []; + + while (certs_len>0) { + tmp = rec.readByte(); + var cert_len:uint = (tmp<<16) | rec.readShort(); + var cert:ByteArray = new ByteArray; + rec.readBytes(cert, 0, cert_len); + certs.push(cert); + certs_len -= 3 + cert_len; + } + + var firstCert:X509Certificate = null; + for (var i:int=0;i<certs.length;i++) { + var x509:X509Certificate = new X509Certificate(certs[i]); + _store.addCertificate(x509); + if (firstCert==null) { + firstCert = x509; + } + } + + + // Test first for trust override parameters + // This nice trust override stuff comes from Joey Parrish via As3crypto forums + var certTrusted:Boolean; + if (_config.trustAllCertificates) { + certTrusted = true; // Blatantly trust everything + } else if (_config.trustSelfSignedCertificates ) { + // Self-signed certs + certTrusted = firstCert.isSelfSigned(new Date); + } else { + // Certs with a signer in the CA store - realistically, I should setup an event chain to handle this + certTrusted = firstCert.isSigned(_store, _config.CAStore ); + } + + // Good so far + if (certTrusted) { + // ok, that's encouraging. now for the hostname match. + if (_otherIdentity==null || _config.ignoreCommonNameMismatch ) { + // we don't care who we're talking with. groovy. + _otherCertificate = firstCert; + } else { + // use regex to handle wildcard certs + var commonName:String = firstCert.getCommonName(); + // replace all regex special characters with escaped version, except for asterisk + // replace the asterisk with a regex sequence to match one or more non-dot characters + var commonNameRegex:RegExp = new RegExp( commonName.replace(/[\^\\\-$.[\]|()?+{}]/g, "\\$&").replace(/\*/g, "[^.]+"), "gi"); + if (commonNameRegex.exec(_otherIdentity)) { + _otherCertificate = firstCert; + } else { + if (_config.promptUserForAcceptCert ) { + _handshakeCanContinue = false; + dispatchEvent( new TLSEvent( TLSEvent.PROMPT_ACCEPT_CERT )); + } else { + throw new TLSError("Invalid common name: "+firstCert.getCommonName()+", expected "+_otherIdentity, TLSError.bad_certificate); + } + } + } + + } else { + // Let's ask the user if we can accept this cert. I'm not certain of the behaviour in case of timeouts, + // so I probably need to handle the case by killing and restarting the connection rather than continuing if it becomes + // an issue. We shall see. BP + if (_config.promptUserForAcceptCert) { + _handshakeCanContinue = false; + dispatchEvent( new TLSEvent( TLSEvent.PROMPT_ACCEPT_CERT )); + } else { + // Cannot continue, die. + throw new TLSError("Cannot verify certificate", TLSError.bad_certificate); + } + } + } + + // Accept the peer cert, and keep going + public function acceptPeerCertificate() : void { + _handshakeCanContinue = true; + sendClientAck( null ); + } + + // Step off biotch! No trust for you! + public function rejectPeerCertificate() : void { + throw new TLSError("Peer certificate not accepted!", TLSError.bad_certificate); + } + + + private function parseAlert(p:ByteArray):void { + //throw new Error("Alert not implemented."); + // 7.2 + trace("GOT ALERT! type="+p[1]); + close(); + } + private function parseChangeCipherSpec(p:ByteArray):void { + p.readUnsignedByte(); + if (_pendingReadState==null) { + throw new TLSError("Not ready to Change Cipher Spec, damnit.", TLSError.unexpected_message); + } + _currentReadState = _pendingReadState; + _pendingReadState = null; + // 7.1 + } + private function parseApplicationData(p:ByteArray):void { + if (_state != STATE_READY) { + throw new TLSError("Too soon for data!", TLSError.unexpected_message); + return; + } + dispatchEvent(new TLSEvent(TLSEvent.DATA, p)); + } + + private function handleTLSError(e:TLSError):void { + // basic rules to keep things simple: + // - Make a good faith attempt at notifying peers + // - TLSErrors are always fatal. + // BP: Meh...not always. Common Name mismatches appear to be common on servers. Instead of closing, let's pause, and ask for confirmation + // before we tear the connection down. + + close(e); + } + } +} diff --git a/flash-src/third-party/com/hurlant/crypto/tls/TLSError.as b/flash-src/third-party/com/hurlant/crypto/tls/TLSError.as new file mode 100644 index 0000000..16fac6d --- /dev/null +++ b/flash-src/third-party/com/hurlant/crypto/tls/TLSError.as @@ -0,0 +1,39 @@ +/**
+ * TLSError
+ *
+ * A error that can be thrown when something wrong happens in the TLS protocol.
+ * This is handled in TLSEngine by generating a TLS ALERT as appropriate.
+ * Copyright (c) 2007 Henri Torgemane
+ *
+ * See LICENSE.txt for full license information.
+ */
+package com.hurlant.crypto.tls {
+ public class TLSError extends Error {
+ public static const close_notify:uint = 0;
+ public static const unexpected_message:uint = 10;
+ public static const bad_record_mac:uint = 20;
+ public static const decryption_failed:uint = 21;
+ public static const record_overflow:uint = 22;
+ public static const decompression_failure:uint = 30;
+ public static const handshake_failure:uint = 40;
+ public static const bad_certificate:uint = 42;
+ public static const unsupported_certificate:uint = 43;
+ public static const certificate_revoked:uint = 44;
+ public static const certificate_expired:uint = 45;
+ public static const certificate_unknown:uint = 46;
+ public static const illegal_parameter:uint = 47;
+ public static const unknown_ca:uint = 48;
+ public static const access_denied:uint = 49;
+ public static const decode_error:uint = 50;
+ public static const decrypt_error:uint = 51;
+ public static const protocol_version:uint = 70;
+ public static const insufficient_security:uint = 71;
+ public static const internal_error:uint = 80;
+ public static const user_canceled:uint = 90;
+ public static const no_renegotiation:uint = 100;
+
+ public function TLSError(message:String, id:int) {
+ super(message,id);
+ }
+ }
+}
\ No newline at end of file diff --git a/flash-src/third-party/com/hurlant/crypto/tls/TLSEvent.as b/flash-src/third-party/com/hurlant/crypto/tls/TLSEvent.as new file mode 100644 index 0000000..d988d1e --- /dev/null +++ b/flash-src/third-party/com/hurlant/crypto/tls/TLSEvent.as @@ -0,0 +1,27 @@ +/**
+ * TLSEvent
+ *
+ * This is used by TLSEngine to let the application layer know
+ * when we're ready for sending, or have received application data
+ * Copyright (c) 2007 Henri Torgemane
+ *
+ * See LICENSE.txt for full license information.
+ */
+package com.hurlant.crypto.tls {
+ import flash.events.Event;
+ import flash.utils.ByteArray;
+
+ public class TLSEvent extends Event {
+
+ static public const DATA:String = "data";
+ static public const READY:String = "ready";
+ static public const PROMPT_ACCEPT_CERT:String = "promptAcceptCert";
+
+ public var data:ByteArray;
+
+ public function TLSEvent(type:String, data:ByteArray = null) {
+ this.data = data;
+ super(type, false, false);
+ }
+ }
+}
\ No newline at end of file diff --git a/flash-src/third-party/com/hurlant/crypto/tls/TLSSecurityParameters.as b/flash-src/third-party/com/hurlant/crypto/tls/TLSSecurityParameters.as new file mode 100644 index 0000000..2637811 --- /dev/null +++ b/flash-src/third-party/com/hurlant/crypto/tls/TLSSecurityParameters.as @@ -0,0 +1,197 @@ +/**
+ * TLSSecurityParameters
+ *
+ * This class encapsulates all the security parameters that get negotiated
+ * during the TLS handshake. It also holds all the key derivation methods.
+ * Copyright (c) 2007 Henri Torgemane
+ *
+ * Patched by Bobby Parker (sh0rtwave@gmail.com)
+ *
+ * See LICENSE.txt for full license information.
+ */
+package com.hurlant.crypto.tls {
+ import com.hurlant.crypto.hash.MD5;
+ import com.hurlant.crypto.hash.SHA1;
+ import com.hurlant.crypto.prng.TLSPRF;
+ import com.hurlant.util.Hex;
+
+ import flash.utils.ByteArray; + import com.hurlant.crypto.rsa.RSAKey;
+
+ public class TLSSecurityParameters implements ISecurityParameters {
+
+ // COMPRESSION
+ public static const COMPRESSION_NULL:uint = 0;
+
+ // This is probably not smart. Revise this to use all settings from TLSConfig, since this shouldn't really know about
+ // user settings, those are best handled from the engine at a session level.
+ public static var IGNORE_CN_MISMATCH:Boolean = true;
+ public static var ENABLE_USER_CLIENT_CERTIFICATE:Boolean = false;
+ public static var USER_CERTIFICATE:String;
+
+
+ private var cert:ByteArray; // Local Cert
+ private var key:RSAKey; // local key
+ private var entity:uint; // SERVER | CLIENT
+ private var bulkCipher:uint; // BULK_CIPHER_*
+ private var cipherType:uint; // STREAM_CIPHER | BLOCK_CIPHER
+ private var keySize:uint;
+ private var keyMaterialLength:uint;
+ private var IVSize:uint;
+ private var macAlgorithm:uint; // MAC_*
+ private var hashSize:uint;
+ private var compression:uint; // COMPRESSION_NULL
+ private var masterSecret:ByteArray; // 48 bytes
+ private var clientRandom:ByteArray; // 32 bytes
+ private var serverRandom:ByteArray; // 32 bytes
+ private var ignoreCNMismatch:Boolean = true;
+ private var trustAllCerts:Boolean = false;
+ private var trustSelfSigned:Boolean = false;
+ public static const PROTOCOL_VERSION:uint = 0x0301; + private var tlsDebug:Boolean = false;
+ +
+ // not strictly speaking part of this, but yeah.
+ public var keyExchange:uint;
+ public function TLSSecurityParameters(entity:uint, localCert:ByteArray = null, localKey:RSAKey = null) {
+ this.entity = entity;
+ reset();
+ key = localKey;
+ cert = localCert;
+ }
+
+ public function get version() : uint {
+ return PROTOCOL_VERSION;
+ }
+
+ public function reset():void {
+ bulkCipher = BulkCiphers.NULL;
+ cipherType = BulkCiphers.BLOCK_CIPHER;
+ macAlgorithm = MACs.NULL;
+ compression = COMPRESSION_NULL;
+ masterSecret = null;
+ }
+
+ public function getBulkCipher():uint {
+ return bulkCipher;
+ }
+ public function getCipherType():uint {
+ return cipherType;
+ }
+ public function getMacAlgorithm():uint {
+ return macAlgorithm;
+ }
+
+ public function setCipher(cipher:uint):void {
+ bulkCipher = CipherSuites.getBulkCipher(cipher);
+ cipherType = BulkCiphers.getType(bulkCipher);
+ keySize = BulkCiphers.getExpandedKeyBytes(bulkCipher); // 8
+ keyMaterialLength = BulkCiphers.getKeyBytes(bulkCipher); // 5
+ IVSize = BulkCiphers.getIVSize(bulkCipher);
+
+ keyExchange = CipherSuites.getKeyExchange(cipher);
+
+ macAlgorithm = CipherSuites.getMac(cipher);
+ hashSize = MACs.getHashSize(macAlgorithm);
+ }
+ public function setCompression(algo:uint):void {
+ compression = algo;
+ }
+ public function setPreMasterSecret(secret:ByteArray):void {
+ // compute master_secret
+ var seed:ByteArray = new ByteArray;
+ seed.writeBytes(clientRandom, 0, clientRandom.length);
+ seed.writeBytes(serverRandom, 0, serverRandom.length);
+ var prf:TLSPRF = new TLSPRF(secret, "master secret", seed);
+ masterSecret = new ByteArray;
+ prf.nextBytes(masterSecret, 48);
+ if (tlsDebug)
+ trace("Master Secret: " + Hex.fromArray( masterSecret, true ));
+ }
+ public function setClientRandom(secret:ByteArray):void {
+ clientRandom = secret;
+ }
+ public function setServerRandom(secret:ByteArray):void {
+ serverRandom = secret;
+ }
+
+ public function get useRSA():Boolean {
+ return KeyExchanges.useRSA(keyExchange);
+ }
+
+ public function computeVerifyData(side:uint, handshakeMessages:ByteArray):ByteArray {
+ var seed:ByteArray = new ByteArray;
+ var md5:MD5 = new MD5;
+ if (tlsDebug)
+ trace("Handshake value: " + Hex.fromArray(handshakeMessages, true ));
+ seed.writeBytes(md5.hash(handshakeMessages),0,md5.getHashSize());
+ var sha:SHA1 = new SHA1;
+ seed.writeBytes(sha.hash(handshakeMessages),0,sha.getHashSize());
+ if (tlsDebug)
+ trace("Seed in: " + Hex.fromArray(seed, true ));
+ var prf:TLSPRF = new TLSPRF(masterSecret, (side==TLSEngine.CLIENT) ? "client finished" : "server finished", seed);
+ var out:ByteArray = new ByteArray;
+ prf.nextBytes(out, 12);
+ if (tlsDebug)
+ trace("Finished out: " + Hex.fromArray(out, true ));
+ out.position = 0;
+ return out;
+ }
+
+ // client side certficate check - This is probably incorrect somehow
+ public function computeCertificateVerify( side:uint, handshakeMessages:ByteArray ):ByteArray {
+ var seed:ByteArray = new ByteArray;
+ var md5:MD5 = new MD5;
+ seed.writeBytes(md5.hash(handshakeMessages),0,md5.getHashSize());
+ var sha:SHA1 = new SHA1;
+ seed.writeBytes(sha.hash(handshakeMessages),0,sha.getHashSize());
+
+ // Now that I have my hashes of existing handshake messages (which I'm not sure about the length of yet) then
+ // Sign that with my private key
+ seed.position = 0;
+ var out:ByteArray = new ByteArray();
+ key.sign( seed, out, seed.bytesAvailable);
+ out.position = 0;
+ return out;
+ }
+
+ public function getConnectionStates():Object {
+ if (masterSecret != null) {
+ var seed:ByteArray = new ByteArray;
+ seed.writeBytes(serverRandom, 0, serverRandom.length);
+ seed.writeBytes(clientRandom, 0, clientRandom.length);
+ var prf:TLSPRF = new TLSPRF(masterSecret, "key expansion", seed);
+
+ var client_write_MAC:ByteArray = new ByteArray;
+ prf.nextBytes(client_write_MAC, hashSize);
+ var server_write_MAC:ByteArray = new ByteArray;
+ prf.nextBytes(server_write_MAC, hashSize);
+ var client_write_key:ByteArray = new ByteArray;
+ prf.nextBytes(client_write_key, keyMaterialLength);
+ var server_write_key:ByteArray = new ByteArray;
+ prf.nextBytes(server_write_key, keyMaterialLength);
+ var client_write_IV:ByteArray = new ByteArray;
+ prf.nextBytes(client_write_IV, IVSize);
+ var server_write_IV:ByteArray = new ByteArray;
+ prf.nextBytes(server_write_IV, IVSize);
+
+ var client_write:TLSConnectionState = new TLSConnectionState(
+ bulkCipher, cipherType, macAlgorithm,
+ client_write_MAC, client_write_key, client_write_IV);
+ var server_write:TLSConnectionState = new TLSConnectionState(
+ bulkCipher, cipherType, macAlgorithm,
+ server_write_MAC, server_write_key, server_write_IV);
+
+ if (entity == TLSEngine.CLIENT) {
+ return {read:server_write, write:client_write};
+ } else {
+ return {read:client_write, write:server_write};
+ }
+
+ } else {
+ return {read:new TLSConnectionState, write:new TLSConnectionState};
+ }
+ }
+
+ }
+}
\ No newline at end of file diff --git a/flash-src/third-party/com/hurlant/crypto/tls/TLSSocket.as b/flash-src/third-party/com/hurlant/crypto/tls/TLSSocket.as new file mode 100644 index 0000000..10004a7 --- /dev/null +++ b/flash-src/third-party/com/hurlant/crypto/tls/TLSSocket.as @@ -0,0 +1,370 @@ +/**
+ * TLSSocket
+ *
+ * This is the "end-user" TLS class.
+ * It works just like a Socket, by encapsulating a Socket and
+ * wrapping the TLS protocol around the data that passes over it.
+ * This class can either create a socket connection, or reuse an
+ * existing connected socket. The later is useful for STARTTLS flows.
+ *
+ * Copyright (c) 2007 Henri Torgemane
+ *
+ * See LICENSE.txt for full license information.
+ */
+package com.hurlant.crypto.tls {
+ import flash.events.Event;
+ import flash.events.EventDispatcher;
+ import flash.events.IOErrorEvent;
+ import flash.events.ProgressEvent;
+ import flash.events.SecurityErrorEvent;
+ import flash.net.ObjectEncoding;
+ import flash.net.Socket;
+ import flash.utils.ByteArray;
+ import flash.utils.Endian;
+ import flash.utils.IDataInput;
+ import flash.utils.IDataOutput;
+ import flash.utils.clearTimeout;
+ import flash.utils.setTimeout; + import com.hurlant.crypto.cert.X509Certificate; +
+
+ [Event(name="close", type="flash.events.Event")]
+ [Event(name="connect", type="flash.events.Event")]
+ [Event(name="ioError", type="flash.events.IOErrorEvent")]
+ [Event(name="securityError", type="flash.events.SecurityErrorEvent")]
+ [Event(name="socketData", type="flash.events.ProgressEvent")]
+ [Event(name="acceptPeerCertificatePrompt", type="flash.events.Event")]
+
+ /**
+ * It feels like a socket, but it wraps the stream
+ * over TLS 1.0
+ *
+ * That's all.
+ *
+ */
+ public class TLSSocket extends Socket implements IDataInput, IDataOutput {
+
+ private var _endian:String;
+ private var _objectEncoding:uint;
+
+ private var _iStream:ByteArray;
+ private var _oStream:ByteArray;
+ private var _iStream_cursor:uint;
+
+ private var _socket:Socket;
+ private var _config:TLSConfig;
+ private var _engine:TLSEngine;
+ public static const ACCEPT_PEER_CERT_PROMPT:String = "acceptPeerCertificatePrompt"
+
+ public function TLSSocket(host:String = null, port:int = 0, config:TLSConfig = null) {
+ _config = config;
+ if (host!=null && port!=0) {
+ connect(host, port);
+ }
+ }
+
+ override public function get bytesAvailable():uint {
+ return _iStream.bytesAvailable;
+ }
+ override public function get connected():Boolean {
+ return _socket.connected;
+ }
+ override public function get endian():String {
+ return _endian;
+ }
+ override public function set endian(value:String):void {
+ _endian = value;
+ _iStream.endian = value;
+ _oStream.endian = value;
+ }
+ override public function get objectEncoding():uint {
+ return _objectEncoding;
+ }
+ override public function set objectEncoding(value:uint):void {
+ _objectEncoding = value;
+ _iStream.objectEncoding = value;
+ _oStream.objectEncoding = value;
+ }
+
+
+ private function onTLSData(event:TLSEvent):void {
+ if (_iStream.position == _iStream.length) {
+ _iStream.position = 0;
+ _iStream.length = 0;
+ _iStream_cursor = 0;
+ }
+ var cursor:uint = _iStream.position;
+ _iStream.position = _iStream_cursor;
+ _iStream.writeBytes(event.data);
+ _iStream_cursor = _iStream.position;
+ _iStream.position = cursor;
+ dispatchEvent(new ProgressEvent(ProgressEvent.SOCKET_DATA, false, false, event.data.length));
+ }
+
+ private function onTLSReady(event:TLSEvent):void {
+ _ready = true;
+ scheduleWrite();
+ }
+
+ private function onTLSClose(event:Event):void {
+ dispatchEvent(event);
+ // trace("Received TLS close");
+ close();
+ }
+
+ private var _ready:Boolean;
+ private var _writeScheduler:uint;
+ private function scheduleWrite():void {
+ if (_writeScheduler!=0) return;
+ _writeScheduler = setTimeout(commitWrite, 0);
+ }
+ private function commitWrite():void {
+ clearTimeout(_writeScheduler);
+ _writeScheduler = 0;
+ if (_ready) {
+ _engine.sendApplicationData(_oStream);
+ _oStream.length = 0;
+ }
+ }
+
+
+ override public function close():void {
+ _ready = false;
+ _engine.close();
+ if (_socket.connected) {
+ _socket.flush();
+ _socket.close();
+ }
+ }
+ public function setTLSConfig( config:TLSConfig) : void {
+ _config = config;
+ }
+
+ override public function connect(host:String, port:int):void {
+ init(new Socket, _config, host);
+ _socket.connect(host, port);
+ _engine.start();
+ }
+
+ public function releaseSocket() : void {
+ _socket.removeEventListener(Event.CONNECT, dispatchEvent);
+ _socket.removeEventListener(IOErrorEvent.IO_ERROR, dispatchEvent);
+ _socket.removeEventListener(SecurityErrorEvent.SECURITY_ERROR, dispatchEvent);
+ _socket.removeEventListener(Event.CLOSE, dispatchEvent);
+ _socket.removeEventListener(ProgressEvent.SOCKET_DATA, _engine.dataAvailable);
+ _socket = null;
+ }
+
+ public function reinitialize(host:String, config:TLSConfig) : void {
+ // Reinitialize the connection using new values
+ // but re-use the existing socket
+ // Doubt this is useful in any valid context other than my specific case (VMWare)
+ var ba:ByteArray = new ByteArray;
+
+ if (_socket.bytesAvailable > 0) {
+ _socket.readBytes(ba, 0, _socket.bytesAvailable);
+ }
+ // Do nothing with it.
+ _iStream = new ByteArray;
+ _oStream = new ByteArray;
+ _iStream_cursor = 0;
+ objectEncoding = ObjectEncoding.DEFAULT;
+ endian = Endian.BIG_ENDIAN;
+ /*
+ _socket.addEventListener(Event.CONNECT, dispatchEvent);
+ _socket.addEventListener(IOErrorEvent.IO_ERROR, dispatchEvent);
+ _socket.addEventListener(SecurityErrorEvent.SECURITY_ERROR, dispatchEvent);
+ _socket.addEventListener(Event.CLOSE, dispatchEvent);
+ */
+
+ if (config == null) {
+ config = new TLSConfig(TLSEngine.CLIENT);
+ }
+
+ _engine = new TLSEngine(config, _socket, _socket, host);
+ _engine.addEventListener(TLSEvent.DATA, onTLSData);
+ _engine.addEventListener(TLSEvent.READY, onTLSReady);
+ _engine.addEventListener(Event.CLOSE, onTLSClose);
+ _engine.addEventListener(ProgressEvent.SOCKET_DATA, function(e:*):void { _socket.flush(); });
+ _socket.addEventListener(ProgressEvent.SOCKET_DATA, _engine.dataAvailable);
+ _engine.addEventListener( TLSEvent.PROMPT_ACCEPT_CERT, onAcceptCert );
+
+ _ready = false;
+ _engine.start();
+ }
+
+ public function startTLS(socket:Socket, host:String, config:TLSConfig = null):void {
+ if (!socket.connected) {
+ throw new Error("Cannot STARTTLS on a socket that isn't connected.");
+ }
+ init(socket, config, host);
+ _engine.start();
+ }
+
+ private function init(socket:Socket, config:TLSConfig, host:String):void {
+ _iStream = new ByteArray;
+ _oStream = new ByteArray;
+ _iStream_cursor = 0;
+ objectEncoding = ObjectEncoding.DEFAULT;
+ endian = Endian.BIG_ENDIAN;
+ _socket = socket;
+ _socket.addEventListener(Event.CONNECT, dispatchEvent);
+ _socket.addEventListener(IOErrorEvent.IO_ERROR, dispatchEvent);
+ _socket.addEventListener(SecurityErrorEvent.SECURITY_ERROR, dispatchEvent);
+ _socket.addEventListener(Event.CLOSE, dispatchEvent);
+
+ if (config == null) {
+ config = new TLSConfig(TLSEngine.CLIENT);
+ }
+ _engine = new TLSEngine(config, _socket, _socket, host);
+ _engine.addEventListener(TLSEvent.DATA, onTLSData);
+ _engine.addEventListener( TLSEvent.PROMPT_ACCEPT_CERT, onAcceptCert );
+ _engine.addEventListener(TLSEvent.READY, onTLSReady);
+ _engine.addEventListener(Event.CLOSE, onTLSClose);
+ _engine.addEventListener(ProgressEvent.SOCKET_DATA, function(e:*):void { if(connected) _socket.flush(); });
+ _socket.addEventListener(ProgressEvent.SOCKET_DATA, _engine.dataAvailable);
+
+ _ready = false;
+ }
+
+ override public function flush():void {
+ commitWrite();
+ _socket.flush();
+ }
+
+ override public function readBoolean():Boolean {
+ return _iStream.readBoolean();
+ }
+
+ override public function readByte():int {
+ return _iStream.readByte();
+ }
+
+ override public function readBytes(bytes:ByteArray, offset:uint = 0, length:uint = 0):void {
+ return _iStream.readBytes(bytes, offset, length);
+ }
+
+ override public function readDouble():Number {
+ return _iStream.readDouble();
+ }
+
+ override public function readFloat():Number {
+ return _iStream.readFloat();
+ }
+
+ override public function readInt():int {
+ return _iStream.readInt();
+ }
+
+ override public function readMultiByte(length:uint, charSet:String):String {
+ return _iStream.readMultiByte(length, charSet);
+ }
+
+ override public function readObject():* {
+ return _iStream.readObject();
+ }
+
+ override public function readShort():int {
+ return _iStream.readShort();
+ }
+
+ override public function readUnsignedByte():uint {
+ return _iStream.readUnsignedByte();
+ }
+
+ override public function readUnsignedInt():uint {
+ return _iStream.readUnsignedInt();
+ }
+
+ override public function readUnsignedShort():uint {
+ return _iStream.readUnsignedShort();
+ }
+
+ override public function readUTF():String {
+ return _iStream.readUTF();
+ }
+
+ override public function readUTFBytes(length:uint):String {
+ return _iStream.readUTFBytes(length);
+ }
+
+ override public function writeBoolean(value:Boolean):void {
+ _oStream.writeBoolean(value);
+ scheduleWrite();
+ }
+
+ override public function writeByte(value:int):void {
+ _oStream.writeByte(value);
+ scheduleWrite();
+ }
+
+ override public function writeBytes(bytes:ByteArray, offset:uint = 0, length:uint = 0):void {
+ _oStream.writeBytes(bytes, offset, length);
+ scheduleWrite();
+ }
+
+ override public function writeDouble(value:Number):void {
+ _oStream.writeDouble(value);
+ scheduleWrite();
+ }
+
+ override public function writeFloat(value:Number):void {
+ _oStream.writeFloat(value);
+ scheduleWrite();
+ }
+
+ override public function writeInt(value:int):void {
+ _oStream.writeInt(value);
+ scheduleWrite();
+ }
+
+ override public function writeMultiByte(value:String, charSet:String):void {
+ _oStream.writeMultiByte(value, charSet);
+ scheduleWrite();
+ }
+
+ override public function writeObject(object:*):void {
+ _oStream.writeObject(object);
+ scheduleWrite();
+ }
+
+ override public function writeShort(value:int):void {
+ _oStream.writeShort(value);
+ scheduleWrite();
+ }
+
+ override public function writeUnsignedInt(value:uint):void {
+ _oStream.writeUnsignedInt(value);
+ scheduleWrite();
+ }
+
+ override public function writeUTF(value:String):void {
+ _oStream.writeUTF(value);
+ scheduleWrite();
+ }
+
+ override public function writeUTFBytes(value:String):void {
+ _oStream.writeUTFBytes(value);
+ scheduleWrite();
+ }
+
+ public function getPeerCertificate() : X509Certificate {
+ return _engine.peerCertificate;
+ }
+
+ public function onAcceptCert( event:TLSEvent ) : void {
+ dispatchEvent( new TLSSocketEvent( _engine.peerCertificate ) );
+ }
+
+ // These are just a passthroughs to the engine. Encapsulation, et al
+ public function acceptPeerCertificate( event:Event ) : void {
+ _engine.acceptPeerCertificate();
+ }
+
+ public function rejectPeerCertificate( event:Event ) : void {
+ _engine.rejectPeerCertificate();
+ }
+
+ }
+}
+
diff --git a/flash-src/third-party/com/hurlant/crypto/tls/TLSSocketEvent.as b/flash-src/third-party/com/hurlant/crypto/tls/TLSSocketEvent.as new file mode 100644 index 0000000..c38f0dc --- /dev/null +++ b/flash-src/third-party/com/hurlant/crypto/tls/TLSSocketEvent.as @@ -0,0 +1,26 @@ +/**
+ * TLSEvent
+ *
+ * This is used by TLSEngine to let the application layer know
+ * when we're ready for sending, or have received application data
+ * Copyright (c) 2007 Henri Torgemane
+ *
+ * See LICENSE.txt for full license information.
+ */
+package com.hurlant.crypto.tls {
+ import flash.events.Event;
+ import flash.utils.ByteArray; + import com.hurlant.crypto.cert.X509Certificate;
+
+ public class TLSSocketEvent extends Event {
+
+ static public const PROMPT_ACCEPT_CERT:String = "promptAcceptCert";
+
+ public var cert:X509Certificate;
+
+ public function TLSSocketEvent( cert:X509Certificate = null) {
+ super(PROMPT_ACCEPT_CERT, false, false);
+ this.cert = cert;
+ }
+ }
+}
\ No newline at end of file diff --git a/flash-src/third-party/com/hurlant/crypto/tls/TLSTest.as b/flash-src/third-party/com/hurlant/crypto/tls/TLSTest.as new file mode 100644 index 0000000..d7c70f3 --- /dev/null +++ b/flash-src/third-party/com/hurlant/crypto/tls/TLSTest.as @@ -0,0 +1,180 @@ +/** + * TLSTest + * + * A test class for TLS. Not a finished product. + * Copyright (c) 2007 Henri Torgemane + * + * See LICENSE.txt for full license information. + */ +package com.hurlant.crypto.tls { + import com.hurlant.crypto.cert.X509Certificate; + import com.hurlant.crypto.cert.X509CertificateCollection; + import com.hurlant.util.Hex; + import com.hurlant.util.der.PEM; + + import flash.events.Event; + import flash.events.ProgressEvent; + import flash.net.Socket; + import flash.utils.ByteArray; + import flash.utils.getTimer; + + public class TLSTest { + + + public var myDebugData:String; + + //[Embed(source="/src/host.cert",mimeType="application/octet-stream")] + public var myCert:Class; + //[Embed(source="/src/host.key",mimeType="application/octet-stream")] + public var myKey:Class; + + public function TLSTest(host:String = null, port:int = 0, type:int = 0 ) { + //loopback(); + if (host != null) { + if (type == 0) { // SSL 3.0 + connectLoginYahooCom(); + // connectLocalSSL(host, port); + } else { + connectLocalTLS(host, port); + } + } else { + testSocket(); + } + } + + public function connectLoginYahooCom():void { + trace("Connecting test socket"); + var s:Socket = new Socket("esx.bluebearllc.net", 903); + + var clientConfig:TLSConfig = new TLSConfig(TLSEngine.CLIENT, + null, + null, + null, + null, + null, + SSLSecurityParameters.PROTOCOL_VERSION); + + var client:TLSEngine = new TLSEngine(clientConfig, s, s); + // hook some events. + s.addEventListener(ProgressEvent.SOCKET_DATA, client.dataAvailable); + client.addEventListener(ProgressEvent.SOCKET_DATA, function(e:*):void { s.flush(); }); + client.start(); + + } + public function connectLocalTLS(host:String, port:int):void { + var s:Socket = new Socket(host, port); + + var clientConfig:TLSConfig = new TLSConfig(TLSEngine.CLIENT); + + var client:TLSEngine = new TLSEngine(clientConfig, s, s); + // hook some events. + s.addEventListener(ProgressEvent.SOCKET_DATA, client.dataAvailable); + client.addEventListener(ProgressEvent.SOCKET_DATA, function(e:*):void { s.flush(); }); + + client.start(); + + } + public function connectLocalSSL(host:String, port:int):void { + var s:Socket = new Socket(host, port); + + var clientConfig:TLSConfig = new TLSConfig(TLSEngine.CLIENT, + null, + null, + null, + null, + null, + SSLSecurityParameters.PROTOCOL_VERSION); + + var client:TLSEngine = new TLSEngine(clientConfig, s, s); + // hook some events. + s.addEventListener(ProgressEvent.SOCKET_DATA, client.dataAvailable); + client.addEventListener(ProgressEvent.SOCKET_DATA, function(e:*):void { s.flush(); }); + + client.start(); + } + + public function loopback():void { + + var server_write:ByteArray = new ByteArray; + var client_write:ByteArray = new ByteArray; + var server_write_cursor:uint = 0; + var client_write_cursor:uint = 0; + + var clientConfig:TLSConfig = new TLSConfig(TLSEngine.CLIENT, null, null, null, null, null, SSLSecurityParameters.PROTOCOL_VERSION); + var serverConfig:TLSConfig = new TLSConfig(TLSEngine.SERVER, null, null, null, null, null, SSLSecurityParameters.PROTOCOL_VERSION); + + + var cert:ByteArray = new myCert; + var key:ByteArray = new myKey; + serverConfig.setPEMCertificate(cert.readUTFBytes(cert.length), key.readUTFBytes(key.length)); + // tmp, for debugging. currently useless + cert.position = 0; + key.position = 0; + clientConfig.setPEMCertificate(cert.readUTFBytes(cert.length), key.readUTFBytes(key.length)); + // put the server cert in the client's trusted store, to keep things happy. + clientConfig.CAStore = new X509CertificateCollection; + cert.position = 0; + var x509:X509Certificate = new X509Certificate(PEM.readCertIntoArray(cert.readUTFBytes(cert.length))); + clientConfig.CAStore.addCertificate(x509); + + + var server:TLSEngine = new TLSEngine(serverConfig, client_write, server_write); + var client:TLSEngine = new TLSEngine(clientConfig, server_write, client_write); + + server.addEventListener(ProgressEvent.SOCKET_DATA, function(e:*=null):void { + trace("server wrote something!"); + trace(Hex.fromArray(server_write)); + var l:uint = server_write.position; + server_write.position = server_write_cursor; + client.dataAvailable(e); + server_write.position = l; + server_write_cursor = l; + }); + client.addEventListener(ProgressEvent.SOCKET_DATA, function(e:*=null):void { + trace("client wrote something!"); + trace(Hex.fromArray(client_write)); + var l:uint = client_write.position; + client_write.position = client_write_cursor; + server.dataAvailable(e); + client_write.position = l; + client_write_cursor = l; + }); + + server.start(); + client.start(); + } + + public function testSocket():void { + var hosts:Array = [ + "bugs.adobe.com", // apache + "login.yahoo.com", // apache, bigger response + "login.live.com", // IIS-6, chain of 3 certs + "banking.wellsfargo.com", // custom, sends its CA cert along for the ride. + "www.bankofamerica.com" // sun-one, chain of 3 certs + ]; + var i:int =0; + (function next():void { + testHost(hosts[i++], next); + })(); + } + + private function testHost(host:String, next:Function):void { + if (host==null) return; + var t1:int = getTimer(); + + var host:String = host; + var t:TLSSocket = new TLSSocket; + t.connect(host, 4433); + t.writeUTFBytes("GET / HTTP/1.0\nHost: "+host+"\n\n"); + t.addEventListener(Event.CLOSE, function(e:*):void { + var s:String = t.readUTFBytes(t.bytesAvailable); + trace("Response from "+host+": "+s.length+" characters"); + var bytes:ByteArray = new ByteArray(); + t.readBytes(bytes, 0, t.bytesAvailable); + trace(Hex.fromArray(bytes)); + trace("Time used = "+(getTimer()-t1)+"ms"); + next(); + }); + } + } +} diff --git a/flash-src/third-party/com/hurlant/math/BarrettReduction.as b/flash-src/third-party/com/hurlant/math/BarrettReduction.as new file mode 100755 index 0000000..48d1563 --- /dev/null +++ b/flash-src/third-party/com/hurlant/math/BarrettReduction.as @@ -0,0 +1,90 @@ +package com.hurlant.math
+{
+ use namespace bi_internal;
+
+ internal class BarrettReduction implements IReduction
+ {
+ private var m:BigInteger;
+ private var r2:BigInteger;
+ private var q3:BigInteger;
+ private var mu:BigInteger;
+
+ public function BarrettReduction(m:BigInteger) {
+ // setup Barrett
+ r2 = new BigInteger;
+ q3 = new BigInteger;
+ BigInteger.ONE.dlShiftTo(2*m.t, r2);
+ mu = r2.divide(m);
+ this.m = m;
+ }
+
+ public function revert(x:BigInteger):BigInteger
+ {
+ return x;
+ }
+
+ /**
+ *
+ * @param x
+ * @param y
+ * @param r = x*y mod m; x != r
+ *
+ */
+ public function mulTo(x:BigInteger, y:BigInteger, r:BigInteger):void
+ {
+ x.multiplyTo(y, r);
+ reduce(r);
+ }
+
+ /**
+ *
+ * @param x
+ * @param r = x^2 mod m; x != r
+ *
+ */
+ public function sqrTo(x:BigInteger, r:BigInteger):void
+ {
+ x.squareTo(r);
+ reduce(r);
+ }
+
+ public function convert(x:BigInteger):BigInteger
+ {
+ if (x.s<0 || x.t>2*m.t) {
+ return x.mod(m);
+ } else if (x.compareTo(m)<0) {
+ return x;
+ } else {
+ var r:BigInteger = new BigInteger;
+ x.copyTo(r);
+ reduce(r);
+ return r;
+ }
+ }
+
+ /**
+ *
+ * @param x = x mod m (HAC 14.42)
+ *
+ */
+ public function reduce(lx:BigInteger):void
+ {
+ var x:BigInteger = lx as BigInteger;
+ x.drShiftTo(m.t-1,r2);
+ if (x.t>m.t+1) {
+ x.t = m.t+1;
+ x.clamp();
+ }
+ mu.multiplyUpperTo(r2, m.t+1, q3);
+ m.multiplyLowerTo(q3, m.t+1, r2);
+ while (x.compareTo(r2)<0) {
+ x.dAddOffset(1, m.t+1);
+ }
+ x.subTo(r2,x);
+ while (x.compareTo(m)>=0) {
+ x.subTo(m,x);
+ }
+ }
+
+ }
+}
\ No newline at end of file diff --git a/flash-src/third-party/com/hurlant/math/BigInteger.as b/flash-src/third-party/com/hurlant/math/BigInteger.as new file mode 100644 index 0000000..119db17 --- /dev/null +++ b/flash-src/third-party/com/hurlant/math/BigInteger.as @@ -0,0 +1,1543 @@ +/**
+ * BigInteger
+ *
+ * An ActionScript 3 implementation of BigInteger (light version)
+ * Copyright (c) 2007 Henri Torgemane
+ *
+ * Derived from:
+ * The jsbn library, Copyright (c) 2003-2005 Tom Wu
+ *
+ * See LICENSE.txt for full license information.
+ */
+package com.hurlant.math
+{
+
+ import com.hurlant.crypto.prng.Random;
+ import com.hurlant.util.Hex;
+ import com.hurlant.util.Memory;
+
+ import flash.utils.ByteArray;
+ use namespace bi_internal;
+
+ public class BigInteger
+ {
+ public static const DB:int = 30; // number of significant bits per chunk
+ public static const DV:int = (1<<DB);
+ public static const DM:int = (DV-1); // Max value in a chunk
+
+ public static const BI_FP:int = 52;
+ public static const FV:Number = Math.pow(2, BI_FP);
+ public static const F1:int = BI_FP - DB;
+ public static const F2:int = 2*DB - BI_FP;
+
+ public static const ZERO:BigInteger = nbv(0);
+ public static const ONE:BigInteger = nbv(1);
+
+ /*bi_internal */public var t:int; // number of chunks.
+ bi_internal var s:int; // sign
+ bi_internal var a:Array; // chunks
+
+ /**
+ *
+ * @param value
+ * @param radix WARNING: If value is ByteArray, this holds the number of bytes to use.
+ * @param unsigned
+ *
+ */
+ public function BigInteger(value:* = null, radix:int = 0, unsigned:Boolean = false) {
+ a = new Array;
+ if (value is String) {
+ if (radix&&radix!=16) throw new Error("BigInteger construction with radix!=16 is not supported.");
+ value = Hex.toArray(value);
+ radix=0;
+ }
+ if (value is ByteArray) {
+ var array:ByteArray = value as ByteArray;
+ var length:int = radix || (array.length - array.position);
+ fromArray(array, length, unsigned);
+ }
+ }
+ public function dispose():void {
+ var r:Random = new Random;
+ for (var i:uint=0;i<a.length;i++) {
+ a[i] = r.nextByte();
+ delete a[i];
+ }
+ a=null;
+ t=0;
+ s=0;
+ Memory.gc();
+ }
+
+ public function toString(radix:Number=16):String {
+ if (s<0) return "-"+negate().toString(radix);
+ var k:int;
+ switch (radix) {
+ case 2: k=1; break;
+ case 4: k=2; break;
+ case 8: k=3; break;
+ case 16: k=4; break;
+ case 32: k=5; break;
+ default:
+// return toRadix(radix);
+ }
+ var km:int = (1<<k)-1;
+ var d:int = 0;
+ var m:Boolean = false;
+ var r:String = "";
+ var i:int = t;
+ var p:int = DB-(i*DB)%k;
+ if (i-->0) {
+ if (p<DB && (d=a[i]>>p)>0) {
+ m = true;
+ r = d.toString(36);
+ }
+ while (i >= 0) {
+ if (p<k) {
+ d = (a[i]&((1<<p)-1))<<(k-p);
+ d|= a[--i]>>(p+=DB-k);
+ } else {
+ d = (a[i]>>(p-=k))&km;
+ if (p<=0) {
+ p += DB;
+ --i;
+ }
+ }
+ if (d>0) {
+ m = true;
+ }
+ if (m) {
+ r += d.toString(36);
+ }
+ }
+ }
+ return m?r:"0";
+ }
+ public function toArray(array:ByteArray):uint {
+ const k:int = 8;
+ const km:int = (1<<8)-1;
+ var d:int = 0;
+ var i:int = t;
+ var p:int = DB-(i*DB)%k;
+ var m:Boolean = false;
+ var c:int = 0;
+ if (i-->0) {
+ if (p<DB && (d=a[i]>>p)>0) {
+ m = true;
+ array.writeByte(d);
+ c++;
+ }
+ while (i >= 0) {
+ if (p<k) {
+ d = (a[i]&((1<<p)-1))<<(k-p);
+ d|= a[--i]>>(p+=DB-k);
+ } else {
+ d = (a[i]>>(p-=k))&km;
+ if (p<=0) {
+ p += DB;
+ --i;
+ }
+ }
+ if (d>0) {
+ m = true;
+ }
+ if (m) {
+ array.writeByte(d);
+ c++;
+ }
+ }
+ }
+ return c;
+ }
+ /**
+ * best-effort attempt to fit into a Number.
+ * precision can be lost if it just can't fit.
+ */
+ public function valueOf():Number {
+ if (s==-1) {
+ return -negate().valueOf();
+ }
+ var coef:Number = 1;
+ var value:Number = 0;
+ for (var i:uint=0;i<t;i++) {
+ value += a[i]*coef;
+ coef *= DV;
+ }
+ return value;
+ }
+ /**
+ * -this
+ */
+ public function negate():BigInteger {
+ var r:BigInteger = nbi();
+ ZERO.subTo(this, r);
+ return r;
+ }
+ /**
+ * |this|
+ */
+ public function abs():BigInteger {
+ return (s<0)?negate():this;
+ }
+ /**
+ * return + if this > v, - if this < v, 0 if equal
+ */
+ public function compareTo(v:BigInteger):int {
+ var r:int = s - v.s;
+ if (r!=0) {
+ return r;
+ }
+ var i:int = t;
+ r = i-v.t;
+ if (r!=0) {
+ return r;
+ }
+ while (--i >=0) {
+ r=a[i]-v.a[i];
+ if (r != 0) return r;
+ }
+ return 0;
+ }
+ /**
+ * returns bit length of the integer x
+ */
+ bi_internal function nbits(x:int):int {
+ var r:int = 1;
+ var t:int;
+ if ((t=x>>>16) != 0) { x = t; r += 16; }
+ if ((t=x>>8) != 0) { x = t; r += 8; }
+ if ((t=x>>4) != 0) { x = t; r += 4; }
+ if ((t=x>>2) != 0) { x = t; r += 2; }
+ if ((t=x>>1) != 0) { x = t; r += 1; }
+ return r;
+ }
+ /**
+ * returns the number of bits in this
+ */
+ public function bitLength():int {
+ if (t<=0) return 0;
+ return DB*(t-1)+nbits(a[t-1]^(s&DM));
+ }
+ /**
+ *
+ * @param v
+ * @return this % v
+ *
+ */
+ public function mod(v:BigInteger):BigInteger {
+ var r:BigInteger = nbi();
+ abs().divRemTo(v,null,r);
+ if (s<0 && r.compareTo(ZERO)>0) {
+ v.subTo(r,r);
+ }
+ return r;
+ }
+ /**
+ * this^e % m, 0 <= e < 2^32
+ */
+ public function modPowInt(e:int, m:BigInteger):BigInteger {
+ var z:IReduction;
+ if (e<256 || m.isEven()) {
+ z = new ClassicReduction(m);
+ } else {
+ z = new MontgomeryReduction(m);
+ }
+ return exp(e, z);
+ }
+
+ /**
+ * copy this to r
+ */
+ bi_internal function copyTo(r:BigInteger):void {
+ for (var i:int = t-1; i>=0; --i) {
+ r.a[i] = a[i];
+ }
+ r.t = t;
+ r.s = s;
+ }
+ /**
+ * set from integer value "value", -DV <= value < DV
+ */
+ bi_internal function fromInt(value:int):void {
+ t = 1;
+ s = (value<0)?-1:0;
+ if (value>0) {
+ a[0] = value;
+ } else if (value<-1) {
+ a[0] = value+DV;
+ } else {
+ t = 0;
+ }
+ }
+ /**
+ * set from ByteArray and length,
+ * starting a current position
+ * If length goes beyond the array, pad with zeroes.
+ */
+ bi_internal function fromArray(value:ByteArray, length:int, unsigned:Boolean = false):void {
+ var p:int = value.position;
+ var i:int = p+length;
+ var sh:int = 0;
+ const k:int = 8;
+ t = 0;
+ s = 0;
+ while (--i >= p) {
+ var x:int = i<value.length?value[i]:0;
+ if (sh == 0) {
+ a[t++] = x;
+ } else if (sh+k > DB) {
+ a[t-1] |= (x&((1<<(DB-sh))-1))<<sh;
+ a[t++] = x>>(DB-sh);
+ } else {
+ a[t-1] |= x<<sh;
+ }
+ sh += k;
+ if (sh >= DB) sh -= DB;
+ }
+ if (!unsigned && (value[0]&0x80)==0x80) {
+ s = -1;
+ if (sh > 0) {
+ a[t-1] |= ((1<<(DB-sh))-1)<<sh;
+ }
+ }
+ clamp();
+ value.position = Math.min(p+length,value.length);
+ }
+ /**
+ * clamp off excess high words
+ */
+ bi_internal function clamp():void {
+ var c:int = s&DM;
+ while (t>0 && a[t-1]==c) {
+ --t;
+ }
+ }
+ /**
+ * r = this << n*DB
+ */
+ bi_internal function dlShiftTo(n:int, r:BigInteger):void {
+ var i:int;
+ for (i=t-1; i>=0; --i) {
+ r.a[i+n] = a[i];
+ }
+ for (i=n-1; i>=0; --i) {
+ r.a[i] = 0;
+ }
+ r.t = t+n;
+ r.s = s;
+ }
+ /**
+ * r = this >> n*DB
+ */
+ bi_internal function drShiftTo(n:int, r:BigInteger):void {
+ var i:int;
+ for (i=n; i<t; ++i) {
+ r.a[i-n] = a[i];
+ }
+ r.t = Math.max(t-n,0);
+ r.s = s;
+ }
+ /**
+ * r = this << n
+ */
+ bi_internal function lShiftTo(n:int, r:BigInteger):void {
+ var bs:int = n%DB;
+ var cbs:int = DB-bs;
+ var bm:int = (1<<cbs)-1;
+ var ds:int = n/DB;
+ var c:int = (s<<bs)&DM;
+ var i:int;
+ for (i=t-1; i>=0; --i) {
+ r.a[i+ds+1] = (a[i]>>cbs)|c;
+ c = (a[i]&bm)<<bs;
+ }
+ for (i=ds-1; i>=0; --i) {
+ r.a[i] = 0;
+ }
+ r.a[ds] = c;
+ r.t = t+ds+1;
+ r.s = s;
+ r.clamp();
+ }
+ /**
+ * r = this >> n
+ */
+ bi_internal function rShiftTo(n:int, r:BigInteger):void {
+ r.s = s;
+ var ds:int = n/DB;
+ if (ds >= t) {
+ r.t = 0;
+ return;
+ }
+ var bs:int = n%DB;
+ var cbs:int = DB-bs;
+ var bm:int = (1<<bs)-1;
+ r.a[0] = a[ds]>>bs;
+ var i:int;
+ for (i=ds+1; i<t; ++i) {
+ r.a[i-ds-1] |= (a[i]&bm)<<cbs;
+ r.a[i-ds] = a[i]>>bs;
+ }
+ if (bs>0) {
+ r.a[t-ds-1] |= (s&bm)<<cbs;
+ }
+ r.t = t-ds;
+ r.clamp();
+ }
+ /**
+ * r = this - v
+ */
+ bi_internal function subTo(v:BigInteger, r:BigInteger):void {
+ var i:int = 0;
+ var c:int = 0;
+ var m:int = Math.min(v.t, t);
+ while (i<m) {
+ c += a[i] - v.a[i];
+ r.a[i++] = c & DM;
+ c >>= DB;
+ }
+ if (v.t < t) {
+ c -= v.s;
+ while (i< t) {
+ c+= a[i];
+ r.a[i++] = c&DM;
+ c >>= DB;
+ }
+ c += s;
+ } else {
+ c += s;
+ while (i < v.t) {
+ c -= v.a[i];
+ r.a[i++] = c&DM;
+ c >>= DB;
+ }
+ c -= v.s;
+ }
+ r.s = (c<0)?-1:0;
+ if (c<-1) {
+ r.a[i++] = DV+c;
+ } else if (c>0) {
+ r.a[i++] = c;
+ }
+ r.t = i;
+ r.clamp();
+ }
+ /**
+ * am: Compute w_j += (x*this_i), propagates carries,
+ * c is initial carry, returns final carry.
+ * c < 3*dvalue, x < 2*dvalue, this_i < dvalue
+ */
+ bi_internal function am(i:int,x:int,w:BigInteger,j:int,c:int,n:int):int {
+ var xl:int = x&0x7fff;
+ var xh:int = x>>15;
+ while(--n >= 0) {
+ var l:int = a[i]&0x7fff;
+ var h:int = a[i++]>>15;
+ var m:int = xh*l + h*xl;
+ l = xl*l + ((m&0x7fff)<<15)+w.a[j]+(c&0x3fffffff);
+ c = (l>>>30)+(m>>>15)+xh*h+(c>>>30);
+ w.a[j++] = l&0x3fffffff;
+ }
+ return c;
+ }
+ /**
+ * r = this * v, r != this,a (HAC 14.12)
+ * "this" should be the larger one if appropriate
+ */
+ bi_internal function multiplyTo(v:BigInteger, r:BigInteger):void {
+ var x:BigInteger = abs();
+ var y:BigInteger = v.abs();
+ var i:int = x.t;
+ r.t = i+y.t;
+ while (--i >= 0) {
+ r.a[i] = 0;
+ }
+ for (i=0; i<y.t; ++i) {
+ r.a[i+x.t] = x.am(0, y.a[i], r, i, 0, x.t);
+ }
+ r.s = 0;
+ r.clamp();
+ if (s!=v.s) {
+ ZERO.subTo(r, r);
+ }
+ }
+ /**
+ * r = this^2, r != this (HAC 14.16)
+ */
+ bi_internal function squareTo(r:BigInteger):void {
+ var x:BigInteger = abs();
+ var i:int = r.t = 2*x.t;
+ while (--i>=0) r.a[i] = 0;
+ for (i=0; i<x.t-1; ++i) {
+ var c:int = x.am(i, x.a[i], r, 2*i, 0, 1);
+ if ((r.a[i+x.t] += x.am(i+1, 2*x.a[i], r, 2*i+1, c, x.t-i-1)) >= DV) {
+ r.a[i+x.t] -= DV;
+ r.a[i+x.t+1] = 1;
+ }
+ }
+ if (r.t>0) {
+ r.a[r.t-1] += x.am(i, x.a[i], r, 2*i, 0, 1);
+ }
+ r.s = 0;
+ r.clamp();
+ }
+ /**
+ * divide this by m, quotient and remainder to q, r (HAC 14.20)
+ * r != q, this != m. q or r may be null.
+ */
+ bi_internal function divRemTo(m:BigInteger, q:BigInteger = null, r:BigInteger = null):void {
+ var pm:BigInteger = m.abs();
+ if (pm.t <= 0) return;
+ var pt:BigInteger = abs();
+ if (pt.t < pm.t) {
+ if (q!=null) q.fromInt(0);
+ if (r!=null) copyTo(r);
+ return;
+ }
+ if (r==null) r = nbi();
+ var y:BigInteger = nbi();
+ var ts:int = s;
+ var ms:int = m.s;
+ var nsh:int = DB-nbits(pm.a[pm.t-1]); // normalize modulus
+ if (nsh>0) {
+ pm.lShiftTo(nsh, y);
+ pt.lShiftTo(nsh, r);
+ } else {
+ pm.copyTo(y);
+ pt.copyTo(r);
+ }
+ var ys:int = y.t;
+ var y0:int = y.a[ys-1];
+ if (y0==0) return;
+ var yt:Number = y0*(1<<F1)+((ys>1)?y.a[ys-2]>>F2:0);
+ var d1:Number = FV/yt;
+ var d2:Number = (1<<F1)/yt;
+ var e:Number = 1<<F2;
+ var i:int = r.t;
+ var j:int = i-ys;
+ var t:BigInteger = (q==null)?nbi():q;
+ y.dlShiftTo(j,t);
+ if (r.compareTo(t)>=0) {
+ r.a[r.t++] = 1;
+ r.subTo(t,r);
+ }
+ ONE.dlShiftTo(ys,t);
+ t.subTo(y,y); // "negative" y so we can replace sub with am later.
+ while(y.t<ys) y.(y.t++, 0);
+ while(--j >= 0) {
+ // Estimate quotient digit
+ var qd:int = (r.a[--i]==y0)?DM:Number(r.a[i])*d1+(Number(r.a[i-1])+e)*d2;
+ if ((r.a[i]+= y.am(0, qd, r, j, 0, ys))<qd) { // Try it out
+ y.dlShiftTo(j, t);
+ r.subTo(t,r);
+ while (r.a[i]<--qd) {
+ r.subTo(t,r);
+ }
+ }
+ }
+ if (q!=null) {
+ r.drShiftTo(ys,q);
+ if (ts!=ms) {
+ ZERO.subTo(q,q);
+ }
+ }
+ r.t = ys;
+ r.clamp();
+ if (nsh>0) {
+ r.rShiftTo(nsh, r); // Denormalize remainder
+ }
+ if (ts<0) {
+ ZERO.subTo(r,r);
+ }
+ }
+ /**
+ * return "-1/this % 2^DB"; useful for Mont. reduction
+ * justification:
+ * xy == 1 (mod n)
+ * xy = 1+km
+ * xy(2-xy) = (1+km)(1-km)
+ * x[y(2-xy)] = 1-k^2.m^2
+ * x[y(2-xy)] == 1 (mod m^2)
+ * if y is 1/x mod m, then y(2-xy) is 1/x mod m^2
+ * should reduce x and y(2-xy) by m^2 at each step to keep size bounded
+ * [XXX unit test the living shit out of this.]
+ */
+ bi_internal function invDigit():int {
+ if (t<1) return 0;
+ var x:int = a[0];
+ if ((x&1)==0) return 0;
+ var y:int = x&3; // y == 1/x mod 2^2
+ y = (y*(2-(x&0xf )*y)) &0xf; // y == 1/x mod 2^4
+ y = (y*(2-(x&0xff)*y)) &0xff; // y == 1/x mod 2^8
+ y = (y*(2-(((x&0xffff)*y)&0xffff)))&0xffff; // y == 1/x mod 2^16
+ // last step - calculate inverse mod DV directly;
+ // assumes 16 < DB <= 32 and assumes ability to handle 48-bit ints
+ // XXX 48 bit ints? Whaaaa? is there an implicit float conversion in here?
+ y = (y*(2-x*y%DV))%DV; // y == 1/x mod 2^dbits
+ // we really want the negative inverse, and -DV < y < DV
+ return (y>0)?DV-y:-y;
+ }
+ /**
+ * true iff this is even
+ */
+ bi_internal function isEven():Boolean {
+ return ((t>0)?(a[0]&1):s) == 0;
+ }
+ /**
+ * this^e, e < 2^32, doing sqr and mul with "r" (HAC 14.79)
+ */
+ bi_internal function exp(e:int, z:IReduction):BigInteger {
+ if (e > 0xffffffff || e < 1) return ONE;
+ var r:BigInteger = nbi();
+ var r2:BigInteger = nbi();
+ var g:BigInteger = z.convert(this);
+ var i:int = nbits(e)-1;
+ g.copyTo(r);
+ while(--i>=0) {
+ z.sqrTo(r, r2);
+ if ((e&(1<<i))>0) {
+ z.mulTo(r2,g,r);
+ } else {
+ var t:BigInteger = r;
+ r = r2;
+ r2 = t;
+ }
+
+ }
+ return z.revert(r);
+ }
+ bi_internal function intAt(str:String, index:int):int {
+ return parseInt(str.charAt(index), 36);
+ }
+
+
+ protected function nbi():* {
+ return new BigInteger;
+ }
+ /**
+ * return bigint initialized to value
+ */
+ public static function nbv(value:int):BigInteger {
+ var bn:BigInteger = new BigInteger;
+ bn.fromInt(value);
+ return bn;
+ }
+
+
+ // Functions above are sufficient for RSA encryption.
+ // The stuff below is useful for decryption and key generation
+
+ public static const lowprimes:Array = [2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293,307,311,313,317,331,337,347,349,353,359,367,373,379,383,389,397,401,409,419,421,431,433,439,443,449,457,461,463,467,479,487,491,499,503,509];
+ public static const lplim:int = (1<<26)/lowprimes[lowprimes.length-1];
+
+
+ public function clone():BigInteger {
+ var r:BigInteger = new BigInteger;
+ this.copyTo(r);
+ return r;
+ }
+
+ /**
+ *
+ * @return value as integer
+ *
+ */
+ public function intValue():int {
+ if (s<0) {
+ if (t==1) {
+ return a[0]-DV;
+ } else if (t==0) {
+ return -1;
+ }
+ } else if (t==1) {
+ return a[0];
+ } else if (t==0) {
+ return 0;
+ }
+ // assumes 16 < DB < 32
+ return ((a[1]&((1<<(32-DB))-1))<<DB)|a[0];
+ }
+
+ /**
+ *
+ * @return value as byte
+ *
+ */
+ public function byteValue():int {
+ return (t==0)?s:(a[0]<<24)>>24;
+ }
+
+ /**
+ *
+ * @return value as short (assumes DB>=16)
+ *
+ */
+ public function shortValue():int {
+ return (t==0)?s:(a[0]<<16)>>16;
+ }
+
+ /**
+ *
+ * @param r
+ * @return x s.t. r^x < DV
+ *
+ */
+ protected function chunkSize(r:Number):int {
+ return Math.floor(Math.LN2*DB/Math.log(r));
+ }
+
+ /**
+ *
+ * @return 0 if this ==0, 1 if this >0
+ *
+ */
+ public function sigNum():int {
+ if (s<0) {
+ return -1;
+ } else if (t<=0 || (t==1 && a[0]<=0)) {
+ return 0;
+ } else{
+ return 1;
+ }
+ }
+
+ /**
+ *
+ * @param b: radix to use
+ * @return a string representing the integer converted to the radix.
+ *
+ */
+ protected function toRadix(b:uint=10):String {
+ if (sigNum()==0 || b<2 || b>32) return "0";
+ var cs:int = chunkSize(b);
+ var a:Number = Math.pow(b, cs);
+ var d:BigInteger = nbv(a);
+ var y:BigInteger = nbi();
+ var z:BigInteger = nbi();
+ var r:String = "";
+ divRemTo(d, y, z);
+ while (y.sigNum()>0) {
+ r = (a+z.intValue()).toString(b).substr(1) + r;
+ y.divRemTo(d,y,z);
+ }
+ return z.intValue().toString(b) + r;
+ }
+
+ /**
+ *
+ * @param s a string to convert from using radix.
+ * @param b a radix
+ *
+ */
+ protected function fromRadix(s:String, b:int = 10):void {
+ fromInt(0);
+ var cs:int = chunkSize(b);
+ var d:Number = Math.pow(b, cs);
+ var mi:Boolean = false;
+ var j:int = 0;
+ var w:int = 0;
+ for (var i:int=0;i<s.length;++i) {
+ var x:int = intAt(s, i);
+ if (x<0) {
+ if (s.charAt(i) == "-" && sigNum() == 0) {
+ mi = true;
+ }
+ continue;
+ }
+ w = b*w+x;
+ if (++j >= cs) {
+ dMultiply(d);
+ dAddOffset(w,0);
+ j=0;
+ w=0;
+ }
+ }
+ if (j>0) {
+ dMultiply(Math.pow(b,j));
+ dAddOffset(w,0);
+ }
+ if (mi) {
+ BigInteger.ZERO.subTo(this, this);
+ }
+ }
+
+ // XXX function fromNumber not written yet.
+
+ /**
+ *
+ * @return a byte array.
+ *
+ */
+ public function toByteArray():ByteArray {
+ var i:int = t;
+ var r:ByteArray = new ByteArray;
+ r[0] = s;
+ var p:int = DB-(i*DB)%8;
+ var d:int;
+ var k:int=0;
+ if (i-->0) {
+ if (p<DB && (d=a[i]>>p)!=(s&DM)>>p) {
+ r[k++] = d|(s<<(DB-p));
+ }
+ while (i>=0) {
+ if(p<8) {
+ d = (a[i]&((1<<p)-1))<<(8-p);
+ d|= a[--i]>>(p+=DB-8);
+ } else {
+ d = (a[i]>>(p-=8))&0xff;
+ if (p<=0) {
+ p += DB;
+ --i;
+ }
+ }
+ if ((d&0x80)!=0) d|=-256;
+ if (k==0 && (s&0x80)!=(d&0x80)) ++k;
+ if (k>0 || d!=s) r[k++] = d;
+ }
+ }
+ return r;
+ }
+
+ public function equals(a:BigInteger):Boolean {
+ return compareTo(a)==0;
+ }
+ public function min(a:BigInteger):BigInteger {
+ return (compareTo(a)<0)?this:a;
+ }
+ public function max(a:BigInteger):BigInteger {
+ return (compareTo(a)>0)?this:a;
+ }
+
+ /**
+ *
+ * @param a a BigInteger to perform the operation with
+ * @param op a Function implementing the operation
+ * @param r a BigInteger to store the result of the operation
+ *
+ */
+ protected function bitwiseTo(a:BigInteger, op:Function, r:BigInteger):void {
+ var i:int;
+ var f:int;
+ var m:int = Math.min(a.t, t);
+ for (i=0; i<m; ++i) {
+ r.a[i] = op(this.a[i],a.a[i]);
+ }
+ if (a.t<t) {
+ f = a.s&DM;
+ for (i=m;i<t;++i) {
+ r.a[i] = op(this.a[i],f);
+ }
+ r.t = t;
+ } else {
+ f = s&DM;
+ for (i=m;i<a.t;++i) {
+ r.a[i] = op(f,a.a[i]);
+ }
+ r.t = a.t;
+ }
+ r.s = op(s, a.s);
+ r.clamp();
+ }
+
+ private function op_and(x:int, y:int):int {return x&y;}
+ public function and(a:BigInteger):BigInteger {
+ var r:BigInteger = new BigInteger;
+ bitwiseTo(a, op_and, r);
+ return r;
+ }
+
+ private function op_or(x:int, y:int):int {return x|y;}
+ public function or(a:BigInteger):BigInteger {
+ var r:BigInteger = new BigInteger;
+ bitwiseTo(a, op_or, r);
+ return r;
+ }
+
+ private function op_xor(x:int, y:int):int {return x^y;}
+ public function xor(a:BigInteger):BigInteger {
+ var r:BigInteger = new BigInteger;
+ bitwiseTo(a, op_xor, r);
+ return r;
+ }
+
+ private function op_andnot(x:int, y:int):int { return x&~y;}
+ public function andNot(a:BigInteger):BigInteger {
+ var r:BigInteger = new BigInteger;
+ bitwiseTo(a, op_andnot, r);
+ return r;
+ }
+
+ public function not():BigInteger {
+ var r:BigInteger = new BigInteger;
+ for (var i:int=0;i<t;++i) {
+ r[i] = DM&~a[i];
+ }
+ r.t = t;
+ r.s = ~s;
+ return r;
+ }
+
+ public function shiftLeft(n:int):BigInteger {
+ var r:BigInteger = new BigInteger;
+ if (n<0) {
+ rShiftTo(-n, r);
+ } else {
+ lShiftTo(n, r);
+ }
+ return r;
+ }
+ public function shiftRight(n:int):BigInteger {
+ var r:BigInteger = new BigInteger;
+ if (n<0) {
+ lShiftTo(-n, r);
+ } else {
+ rShiftTo(n, r);
+ }
+ return r;
+ }
+
+ /**
+ *
+ * @param x
+ * @return index of lowet 1-bit in x, x < 2^31
+ *
+ */
+ private function lbit(x:int):int {
+ if (x==0) return -1;
+ var r:int = 0;
+ if ((x&0xffff)==0) { x>>= 16; r += 16; }
+ if ((x&0xff) == 0) { x>>= 8; r += 8; }
+ if ((x&0xf) == 0) { x>>= 4; r += 4; }
+ if ((x&0x3) == 0) { x>>= 2; r += 2; }
+ if ((x&0x1) == 0) ++r;
+ return r;
+ }
+
+ /**
+ *
+ * @return index of lowest 1-bit (or -1 if none)
+ *
+ */
+ public function getLowestSetBit():int {
+ for (var i:int=0;i<t;++i) {
+ if (a[i]!=0) return i*DB+lbit(a[i]);
+ }
+ if (s<0) return t*DB;
+ return -1;
+ }
+
+ /**
+ *
+ * @param x
+ * @return number of 1 bits in x
+ *
+ */
+ private function cbit(x:int):int {
+ var r:uint =0;
+ while (x!=0) { x &= x-1; ++r }
+ return r;
+ }
+
+ /**
+ *
+ * @return number of set bits
+ *
+ */
+ public function bitCount():int {
+ var r:int=0;
+ var x:int = s&DM;
+ for (var i:int=0;i<t;++i) {
+ r += cbit(a[i]^x);
+ }
+ return r;
+ }
+
+ /**
+ *
+ * @param n
+ * @return true iff nth bit is set
+ *
+ */
+ public function testBit(n:int):Boolean {
+ var j:int = Math.floor(n/DB);
+ if (j>=t) {
+ return s!=0;
+ }
+ return ((a[j]&(1<<(n%DB)))!=0);
+ }
+
+ /**
+ *
+ * @param n
+ * @param op
+ * @return this op (1<<n)
+ *
+ */
+ protected function changeBit(n:int,op:Function):BigInteger {
+ var r:BigInteger = BigInteger.ONE.shiftLeft(n);
+ bitwiseTo(r, op, r);
+ return r;
+ }
+
+ /**
+ *
+ * @param n
+ * @return this | (1<<n)
+ *
+ */
+ public function setBit(n:int):BigInteger { return changeBit(n, op_or); }
+
+ /**
+ *
+ * @param n
+ * @return this & ~(1<<n)
+ *
+ */
+ public function clearBit(n:int):BigInteger { return changeBit(n, op_andnot); }
+
+ /**
+ *
+ * @param n
+ * @return this ^ (1<<n)
+ *
+ */
+ public function flipBit(n:int):BigInteger { return changeBit(n, op_xor); }
+
+ /**
+ *
+ * @param a
+ * @param r = this + a
+ *
+ */
+ protected function addTo(a:BigInteger, r:BigInteger):void {
+ var i:int = 0;
+ var c:int = 0;
+ var m:int = Math.min(a.t, t);
+ while (i<m) {
+ c += this.a[i] + a.a[i];
+ r.a[i++] = c&DM;
+ c>>=DB;
+ }
+ if (a.t < t) {
+ c += a.s;
+ while (i<t) {
+ c += this.a[i];
+ r.a[i++] = c&DM;
+ c >>= DB;
+ }
+ c += s;
+ } else {
+ c += s;
+ while (i<a.t) {
+ c += a.a[i];
+ r.a[i++] = c&DM;
+ c >>= DB;
+ }
+ c += a.s;
+ }
+ r.s = (c<0)?-1:0;
+ if (c>0) {
+ r.a[i++] = c;
+ } else if (c<-1) {
+ r.a[i++] = DV+c;
+ }
+ r.t = i;
+ r.clamp();
+ }
+
+ /**
+ *
+ * @param a
+ * @return this + a
+ *
+ */
+ public function add(a:BigInteger):BigInteger {
+ var r:BigInteger = new BigInteger;
+ addTo(a,r);
+ return r;
+ }
+
+ /**
+ *
+ * @param a
+ * @return this - a
+ *
+ */
+ public function subtract(a:BigInteger):BigInteger {
+ var r:BigInteger = new BigInteger;
+ subTo(a,r);
+ return r;
+ }
+
+ /**
+ *
+ * @param a
+ * @return this * a
+ *
+ */
+ public function multiply(a:BigInteger):BigInteger {
+ var r:BigInteger = new BigInteger;
+ multiplyTo(a,r);
+ return r;
+ }
+
+ /**
+ *
+ * @param a
+ * @return this / a
+ *
+ */
+ public function divide(a:BigInteger):BigInteger {
+ var r:BigInteger = new BigInteger;
+ divRemTo(a, r, null);
+ return r;
+ }
+
+ public function remainder(a:BigInteger):BigInteger {
+ var r:BigInteger = new BigInteger;
+ divRemTo(a, null, r);
+ return r;
+ }
+
+ /**
+ *
+ * @param a
+ * @return [this/a, this%a]
+ *
+ */
+ public function divideAndRemainder(a:BigInteger):Array {
+ var q:BigInteger = new BigInteger;
+ var r:BigInteger = new BigInteger;
+ divRemTo(a, q, r);
+ return [q,r];
+ }
+
+ /**
+ *
+ * this *= n, this >=0, 1 < n < DV
+ *
+ * @param n
+ *
+ */
+ bi_internal function dMultiply(n:int):void {
+ a[t] = am(0, n-1, this, 0, 0, t);
+ ++t;
+ clamp();
+ }
+
+ /**
+ *
+ * this += n << w words, this >= 0
+ *
+ * @param n
+ * @param w
+ *
+ */
+ bi_internal function dAddOffset(n:int, w:int):void {
+ while (t<=w) {
+ a[t++] = 0;
+ }
+ a[w] += n;
+ while (a[w] >= DV) {
+ a[w] -= DV;
+ if (++w >= t) {
+ a[t++] = 0;
+ }
+ ++a[w];
+ }
+ }
+
+ /**
+ *
+ * @param e
+ * @return this^e
+ *
+ */
+ public function pow(e:int):BigInteger {
+ return exp(e, new NullReduction);
+ }
+
+ /**
+ *
+ * @param a
+ * @param n
+ * @param r = lower n words of "this * a", a.t <= n
+ *
+ */
+ bi_internal function multiplyLowerTo(a:BigInteger, n:int, r:BigInteger):void {
+ var i:int = Math.min(t+a.t, n);
+ r.s = 0; // assumes a, this >= 0
+ r.t = i;
+ while (i>0) {
+ r.a[--i]=0;
+ }
+ var j:int;
+ for (j=r.t-t;i<j;++i) {
+ r.a[i+t] = am(0, a.a[i], r, i, 0, t);
+ }
+ for (j=Math.min(a.t,n);i<j;++i) {
+ am(0, a.a[i], r, i, 0, n-i);
+ }
+ r.clamp();
+ }
+
+ /**
+ *
+ * @param a
+ * @param n
+ * @param r = "this * a" without lower n words, n > 0
+ *
+ */
+ bi_internal function multiplyUpperTo(a:BigInteger, n:int, r:BigInteger):void {
+ --n;
+ var i:int = r.t = t+a.t-n;
+ r.s = 0; // assumes a,this >= 0
+ while (--i>=0) {
+ r.a[i] = 0;
+ }
+ for (i=Math.max(n-t,0);i<a.t;++i) {
+ r.a[t+i-n] = am(n-i, a.a[i], r, 0, 0, t+i-n);
+ }
+ r.clamp();
+ r.drShiftTo(1,r);
+ }
+
+ /**
+ *
+ * @param e
+ * @param m
+ * @return this^e % m (HAC 14.85)
+ *
+ */
+ public function modPow(e:BigInteger, m:BigInteger):BigInteger {
+ var i:int = e.bitLength();
+ var k:int;
+ var r:BigInteger = nbv(1);
+ var z:IReduction;
+
+ if (i<=0) {
+ return r;
+ } else if (i<18) {
+ k=1;
+ } else if (i<48) {
+ k=3;
+ } else if (i<144) {
+ k=4;
+ } else if (i<768) {
+ k=5;
+ } else {
+ k=6;
+ }
+ if (i<8) {
+ z = new ClassicReduction(m);
+ } else if (m.isEven()) {
+ z = new BarrettReduction(m);
+ } else {
+ z = new MontgomeryReduction(m);
+ }
+ // precomputation
+ var g:Array = [];
+ var n:int = 3;
+ var k1:int = k-1;
+ var km:int = (1<<k)-1;
+ g[1] = z.convert(this);
+ if (k > 1) {
+ var g2:BigInteger = new BigInteger;
+ z.sqrTo(g[1], g2);
+ while (n<=km) {
+ g[n] = new BigInteger;
+ z.mulTo(g2, g[n-2], g[n]);
+ n += 2;
+ }
+ }
+
+ var j:int = e.t-1;
+ var w:int;
+ var is1:Boolean = true;
+ var r2:BigInteger = new BigInteger;
+ var t:BigInteger;
+ i = nbits(e.a[j])-1;
+ while (j>=0) {
+ if (i>=k1) {
+ w = (e.a[j]>>(i-k1))&km;
+ } else {
+ w = (e.a[j]&((1<<(i+1))-1))<<(k1-i);
+ if (j>0) {
+ w |= e.a[j-1]>>(DB+i-k1);
+ }
+ }
+ n = k;
+ while ((w&1)==0) {
+ w >>= 1;
+ --n;
+ }
+ if ((i -= n) <0) {
+ i += DB;
+ --j;
+ }
+ if (is1) { // ret == 1, don't bother squaring or multiplying it
+ g[w].copyTo(r);
+ is1 = false;
+ } else {
+ while (n>1) {
+ z.sqrTo(r, r2);
+ z.sqrTo(r2, r);
+ n -= 2;
+ }
+ if (n>0) {
+ z.sqrTo(r, r2);
+ } else {
+ t = r;
+ r = r2;
+ r2 = t;
+ }
+ z.mulTo(r2, g[w], r);
+ }
+ while (j>=0 && (e.a[j]&(1<<i)) == 0) {
+ z.sqrTo(r, r2);
+ t = r;
+ r = r2;
+ r2 = t;
+ if (--i<0) {
+ i = DB-1;
+ --j;
+ }
+
+ }
+ }
+ return z.revert(r);
+ }
+
+ /**
+ *
+ * @param a
+ * @return gcd(this, a) (HAC 14.54)
+ *
+ */
+ public function gcd(a:BigInteger):BigInteger {
+ var x:BigInteger = (s<0)?negate():clone();
+ var y:BigInteger = (a.s<0)?a.negate():a.clone();
+ if (x.compareTo(y)<0) {
+ var t:BigInteger=x;
+ x=y;
+ y=t;
+ }
+ var i:int = x.getLowestSetBit();
+ var g:int = y.getLowestSetBit();
+ if (g<0) return x;
+ if (i<g) g= i;
+ if (g>0) {
+ x.rShiftTo(g, x);
+ y.rShiftTo(g, y);
+ }
+ while (x.sigNum()>0) {
+ if ((i = x.getLowestSetBit()) >0) {
+ x.rShiftTo(i, x);
+ }
+ if ((i = y.getLowestSetBit()) >0) {
+ y.rShiftTo(i, y);
+ }
+ if (x.compareTo(y) >= 0) {
+ x.subTo(y, x);
+ x.rShiftTo(1, x);
+ } else {
+ y.subTo(x, y);
+ y.rShiftTo(1, y);
+ }
+ }
+ if (g>0) {
+ y.lShiftTo(g, y);
+ }
+ return y;
+ }
+
+ /**
+ *
+ * @param n
+ * @return this % n, n < 2^DB
+ *
+ */
+ protected function modInt(n:int):int {
+ if (n<=0) return 0;
+ var d:int = DV%n;
+ var r:int = (s<0)?n-1:0;
+ if (t>0) {
+ if (d==0) {
+ r = a[0]%n;
+ } else {
+ for (var i:int=t-1;i>=0;--i) {
+ r = (d*r+a[i])%n;
+ }
+ }
+ }
+ return r;
+ }
+
+ /**
+ *
+ * @param m
+ * @return 1/this %m (HAC 14.61)
+ *
+ */
+ public function modInverse(m:BigInteger):BigInteger {
+ var ac:Boolean = m.isEven();
+ if ((isEven()&&ac) || m.sigNum()==0) {
+ return BigInteger.ZERO;
+ }
+ var u:BigInteger = m.clone();
+ var v:BigInteger = clone();
+ var a:BigInteger = nbv(1);
+ var b:BigInteger = nbv(0);
+ var c:BigInteger = nbv(0);
+ var d:BigInteger = nbv(1);
+ while (u.sigNum()!=0) {
+ while (u.isEven()) {
+ u.rShiftTo(1,u);
+ if (ac) {
+ if (!a.isEven() || !b.isEven()) {
+ a.addTo(this,a);
+ b.subTo(m,b);
+ }
+ a.rShiftTo(1,a);
+ } else if (!b.isEven()) {
+ b.subTo(m,b);
+ }
+ b.rShiftTo(1,b);
+ }
+ while (v.isEven()) {
+ v.rShiftTo(1,v);
+ if (ac) {
+ if (!c.isEven() || !d.isEven()) {
+ c.addTo(this,c);
+ d.subTo(m,d);
+ }
+ c.rShiftTo(1,c);
+ } else if (!d.isEven()) {
+ d.subTo(m,d);
+ }
+ d.rShiftTo(1,d);
+ }
+ if (u.compareTo(v)>=0) {
+ u.subTo(v,u);
+ if (ac) {
+ a.subTo(c,a);
+ }
+ b.subTo(d,b);
+ } else {
+ v.subTo(u,v);
+ if (ac) {
+ c.subTo(a,c);
+ }
+ d.subTo(b,d);
+ }
+ }
+ if (v.compareTo(BigInteger.ONE) != 0) {
+ return BigInteger.ZERO;
+ }
+ if (d.compareTo(m) >= 0) {
+ return d.subtract(m);
+ }
+ if (d.sigNum()<0) {
+ d.addTo(m,d);
+ } else {
+ return d;
+ }
+ if (d.sigNum()<0) {
+ return d.add(m);
+ } else {
+ return d;
+ }
+ }
+
+ /**
+ *
+ * @param t
+ * @return primality with certainty >= 1-.5^t
+ *
+ */
+ public function isProbablePrime(t:int):Boolean {
+ var i:int;
+ var x:BigInteger = abs();
+ if (x.t == 1 && x.a[0]<=lowprimes[lowprimes.length-1]) {
+ for (i=0;i<lowprimes.length;++i) {
+ if (x[0]==lowprimes[i]) return true;
+ }
+ return false;
+ }
+ if (x.isEven()) return false;
+ i = 1;
+ while (i<lowprimes.length) {
+ var m:int = lowprimes[i];
+ var j:int = i+1;
+ while (j<lowprimes.length && m<lplim) {
+ m *= lowprimes[j++];
+ }
+ m = x.modInt(m);
+ while (i<j) {
+ if (m%lowprimes[i++]==0) {
+ return false;
+ }
+ }
+ }
+ return x.millerRabin(t);
+ }
+
+ /**
+ *
+ * @param t
+ * @return true if probably prime (HAC 4.24, Miller-Rabin)
+ *
+ */
+ protected function millerRabin(t:int):Boolean {
+ var n1:BigInteger = subtract(BigInteger.ONE);
+ var k:int = n1.getLowestSetBit();
+ if (k<=0) {
+ return false;
+ }
+ var r:BigInteger = n1.shiftRight(k);
+ t = (t+1)>>1;
+ if (t>lowprimes.length) {
+ t = lowprimes.length;
+ }
+ var a:BigInteger = new BigInteger;
+ for (var i:int=0;i<t;++i) {
+ a.fromInt(lowprimes[i]);
+ var y:BigInteger = a.modPow(r, this);
+ if (y.compareTo(BigInteger.ONE)!=0 && y.compareTo(n1)!=0) {
+ var j:int = 1;
+ while (j++<k && y.compareTo(n1)!=0) {
+ y = y.modPowInt(2, this);
+ if (y.compareTo(BigInteger.ONE)==0) {
+ return false;
+ }
+ }
+ if (y.compareTo(n1)!=0) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Tweak our BigInteger until it looks prime enough
+ *
+ * @param bits
+ * @param t
+ *
+ */
+ public function primify(bits:int, t:int):void {
+ if (!testBit(bits-1)) { // force MSB set
+ bitwiseTo(BigInteger.ONE.shiftLeft(bits-1), op_or, this);
+ }
+ if (isEven()) {
+ dAddOffset(1,0); // force odd
+ }
+ while (!isProbablePrime(t)) {
+ dAddOffset(2,0);
+ while(bitLength()>bits) subTo(BigInteger.ONE.shiftLeft(bits-1),this);
+ }
+ }
+
+ }
+}
diff --git a/flash-src/third-party/com/hurlant/math/ClassicReduction.as b/flash-src/third-party/com/hurlant/math/ClassicReduction.as new file mode 100755 index 0000000..ea9f17c --- /dev/null +++ b/flash-src/third-party/com/hurlant/math/ClassicReduction.as @@ -0,0 +1,35 @@ +package com.hurlant.math
+{
+ use namespace bi_internal;
+
+ /**
+ * Modular reduction using "classic" algorithm
+ */
+ internal class ClassicReduction implements IReduction
+ {
+ private var m:BigInteger;
+ public function ClassicReduction(m:BigInteger) {
+ this.m = m;
+ }
+ public function convert(x:BigInteger):BigInteger {
+ if (x.s<0 || x.compareTo(m)>=0) {
+ return x.mod(m);
+ }
+ return x;
+ }
+ public function revert(x:BigInteger):BigInteger {
+ return x;
+ }
+ public function reduce(x:BigInteger):void {
+ x.divRemTo(m, null,x);
+ }
+ public function mulTo(x:BigInteger, y:BigInteger, r:BigInteger):void {
+ x.multiplyTo(y,r);
+ reduce(r);
+ }
+ public function sqrTo(x:BigInteger, r:BigInteger):void {
+ x.squareTo(r);
+ reduce(r);
+ }
+ }
+}
\ No newline at end of file diff --git a/flash-src/third-party/com/hurlant/math/IReduction.as b/flash-src/third-party/com/hurlant/math/IReduction.as new file mode 100755 index 0000000..210a054 --- /dev/null +++ b/flash-src/third-party/com/hurlant/math/IReduction.as @@ -0,0 +1,11 @@ +package com.hurlant.math
+{
+ internal interface IReduction
+ {
+ function convert(x:BigInteger):BigInteger;
+ function revert(x:BigInteger):BigInteger;
+ function reduce(x:BigInteger):void;
+ function mulTo(x:BigInteger, y:BigInteger, r:BigInteger):void;
+ function sqrTo(x:BigInteger, r:BigInteger):void;
+ }
+}
\ No newline at end of file diff --git a/flash-src/third-party/com/hurlant/math/MontgomeryReduction.as b/flash-src/third-party/com/hurlant/math/MontgomeryReduction.as new file mode 100755 index 0000000..47a16d6 --- /dev/null +++ b/flash-src/third-party/com/hurlant/math/MontgomeryReduction.as @@ -0,0 +1,85 @@ +package com.hurlant.math
+{
+ use namespace bi_internal;
+ /**
+ * Montgomery reduction
+ */
+ internal class MontgomeryReduction implements IReduction
+ {
+ private var m:BigInteger;
+ private var mp:int;
+ private var mpl:int;
+ private var mph:int;
+ private var um:int;
+ private var mt2:int;
+ public function MontgomeryReduction(m:BigInteger) {
+ this.m = m;
+ mp = m.invDigit();
+ mpl = mp & 0x7fff;
+ mph = mp>>15;
+ um = (1<<(BigInteger.DB-15))-1;
+ mt2 = 2*m.t;
+ }
+ /**
+ * xR mod m
+ */
+ public function convert(x:BigInteger):BigInteger {
+ var r:BigInteger = new BigInteger;
+ x.abs().dlShiftTo(m.t, r);
+ r.divRemTo(m, null, r);
+ if (x.s<0 && r.compareTo(BigInteger.ZERO)>0) {
+ m.subTo(r,r);
+ }
+ return r;
+ }
+ /**
+ * x/R mod m
+ */
+ public function revert(x:BigInteger):BigInteger {
+ var r:BigInteger = new BigInteger;
+ x.copyTo(r);
+ reduce(r);
+ return r;
+ }
+ /**
+ * x = x/R mod m (HAC 14.32)
+ */
+ public function reduce(x:BigInteger):void {
+ while (x.t<=mt2) { // pad x so am has enough room later
+ x.a[x.t++] = 0;
+ }
+ for (var i:int=0; i<m.t; ++i) {
+ // faster way of calculating u0 = x[i]*mp mod DV
+ var j:int = x.a[i]&0x7fff;
+ var u0:int = (j*mpl+(((j*mph+(x.a[i]>>15)*mpl)&um)<<15))&BigInteger.DM;
+ // use am to combine the multiply-shift-add into one call
+ j = i+m.t;
+ x.a[j] += m.am(0, u0, x, i, 0, m.t);
+ // propagate carry
+ while (x.a[j]>=BigInteger.DV) {
+ x.a[j] -= BigInteger.DV;
+ x.a[++j]++;
+ }
+ }
+ x.clamp();
+ x.drShiftTo(m.t, x);
+ if (x.compareTo(m)>=0) {
+ x.subTo(m,x);
+ }
+ }
+ /**
+ * r = "x^2/R mod m"; x != r
+ */
+ public function sqrTo(x:BigInteger, r:BigInteger):void {
+ x.squareTo(r);
+ reduce(r);
+ }
+ /**
+ * r = "xy/R mod m"; x,y != r
+ */
+ public function mulTo(x:BigInteger, y:BigInteger, r:BigInteger):void {
+ x.multiplyTo(y,r);
+ reduce(r);
+ }
+ }
+}
\ No newline at end of file diff --git a/flash-src/third-party/com/hurlant/math/NullReduction.as b/flash-src/third-party/com/hurlant/math/NullReduction.as new file mode 100755 index 0000000..5b55832 --- /dev/null +++ b/flash-src/third-party/com/hurlant/math/NullReduction.as @@ -0,0 +1,34 @@ +package com.hurlant.math
+{
+ use namespace bi_internal;
+ /**
+ * A "null" reducer
+ */
+ public class NullReduction implements IReduction
+ {
+ public function revert(x:BigInteger):BigInteger
+ {
+ return x;
+ }
+
+ public function mulTo(x:BigInteger, y:BigInteger, r:BigInteger):void
+ {
+ x.multiplyTo(y,r);
+ }
+
+ public function sqrTo(x:BigInteger, r:BigInteger):void
+ {
+ x.squareTo(r);
+ }
+
+ public function convert(x:BigInteger):BigInteger
+ {
+ return x;
+ }
+
+ public function reduce(x:BigInteger):void
+ {
+ }
+
+ }
+}
\ No newline at end of file diff --git a/flash-src/third-party/com/hurlant/math/bi_internal.as b/flash-src/third-party/com/hurlant/math/bi_internal.as new file mode 100755 index 0000000..dc86aad --- /dev/null +++ b/flash-src/third-party/com/hurlant/math/bi_internal.as @@ -0,0 +1,11 @@ +/**
+ * bi_internal
+ *
+ * A namespace. w00t.
+ * Copyright (c) 2007 Henri Torgemane
+ *
+ * See LICENSE.txt for full license information.
+ */
+package com.hurlant.math {
+ public namespace bi_internal = "http://crypto.hurlant.com/BigInteger";
+}
\ No newline at end of file diff --git a/flash-src/third-party/com/hurlant/util/ArrayUtil.as b/flash-src/third-party/com/hurlant/util/ArrayUtil.as new file mode 100755 index 0000000..b02b8d5 --- /dev/null +++ b/flash-src/third-party/com/hurlant/util/ArrayUtil.as @@ -0,0 +1,25 @@ +/**
+ * ArrayUtil
+ *
+ * A class that allows to compare two ByteArrays.
+ * Copyright (c) 2007 Henri Torgemane
+ *
+ * See LICENSE.txt for full license information.
+ */
+package com.hurlant.util {
+ import flash.utils.ByteArray;
+
+
+ public class ArrayUtil {
+
+ public static function equals(a1:ByteArray, a2:ByteArray):Boolean {
+ if (a1.length != a2.length) return false;
+ var l:int = a1.length;
+ for (var i:int=0;i<l;i++) {
+ if (a1[i]!=a2[i]) return false;
+ }
+ return true;
+ }
+ }
+
+}
\ No newline at end of file diff --git a/flash-src/third-party/com/hurlant/util/Base64.as b/flash-src/third-party/com/hurlant/util/Base64.as new file mode 100755 index 0000000..bcb349c --- /dev/null +++ b/flash-src/third-party/com/hurlant/util/Base64.as @@ -0,0 +1,189 @@ +/* Base64 library for ActionScript 3.0.
+ * Based on: Ma Bingyao code.
+ * Optimized by: Jean-Philippe Auclair / jpauclair.wordpress.com
+ * Copyright (C) 2007 Ma Bingyao <andot@ujn.edu.cn>
+ * LastModified: Oct 26, 2009
+ * This library is free. You can redistribute it and/or modify it.
+ */
+package com.hurlant.util{
+ import flash.utils.ByteArray;
+
+ public class Base64
+ {
+ private static const _encodeChars : Vector.<int> = InitEncoreChar();
+ private static const _decodeChars : Vector.<int> = InitDecodeChar();
+
+ public static function encodeByteArray(data : ByteArray) : String
+ {
+ var out : ByteArray = new ByteArray();
+ //Presetting the length keep the memory smaller and optimize speed since there is no "grow" needed
+ out.length = (2 + data.length - ((data.length + 2) % 3)) * 4 / 3; //Preset length //1.6 to 1.5 ms
+ var i : int = 0;
+ var r : int = data.length % 3;
+ var len : int = data.length - r;
+ var c : int; //read (3) character AND write (4) characters
+
+ while (i < len)
+ {
+ //Read 3 Characters (8bit * 3 = 24 bits)
+ c = data[i++] << 16 | data[i++] << 8 | data[i++];
+
+ //Cannot optimize this to read int because of the positioning overhead. (as3 bytearray seek is slow)
+ //Convert to 4 Characters (6 bit * 4 = 24 bits)
+ c = (_encodeChars[c >>> 18] << 24) | (_encodeChars[c >>> 12 & 0x3f] << 16) | (_encodeChars[c >>> 6 & 0x3f] << 8) | _encodeChars[c & 0x3f];
+
+ //Optimization: On older and slower computer, do one write Int instead of 4 write byte: 1.5 to 0.71 ms
+ out.writeInt(c);
+ /*
+ out.writeByte(_encodeChars[c >> 18] );
+ out.writeByte(_encodeChars[c >> 12 & 0x3f]);
+ out.writeByte(_encodeChars[c >> 6 & 0x3f]);
+ out.writeByte(_encodeChars[c & 0x3f]);
+ */
+ }
+
+ if (r == 1) //Need two "=" padding
+ {
+ //Read one char, write two chars, write padding
+ c = data[i];
+ c = (_encodeChars[c >>> 2] << 24) | (_encodeChars[(c & 0x03) << 4] << 16) | 61 << 8 | 61;
+ out.writeInt(c);
+ }
+ else if (r == 2) //Need one "=" padding
+ {
+ c = data[i++] << 8 | data[i];
+ c = (_encodeChars[c >>> 10] << 24) | (_encodeChars[c >>> 4 & 0x3f] << 16) | (_encodeChars[(c & 0x0f) << 2] << 8) | 61;
+ out.writeInt(c);
+ }
+
+ out.position = 0;
+ return out.readUTFBytes(out.length);
+ }
+
+
+ public static function decodeToByteArray(str : String) : ByteArray
+ {
+ var c1 : int;
+ var c2 : int;
+ var c3 : int;
+ var c4 : int;
+ var i : int;
+ var len : int;
+ var out : ByteArray;
+ len = str.length;
+ i = 0;
+ out = new ByteArray();
+ var byteString : ByteArray = new ByteArray();
+ byteString.writeUTFBytes(str);
+ while (i < len)
+ {
+ //c1
+ do
+ {
+ c1 = _decodeChars[byteString[i++]];
+ } while (i < len && c1 == -1);
+ if (c1 == -1) break;
+
+ //c2
+ do
+ {
+ c2 = _decodeChars[byteString[i++]];
+ } while (i < len && c2 == -1);
+ if (c2 == -1) break;
+
+ out.writeByte((c1 << 2) | ((c2 & 0x30) >> 4));
+
+ //c3
+ do
+ {
+ c3 = byteString[i++];
+ if (c3 == 61) return out;
+
+ c3 = _decodeChars[c3];
+ } while (i < len && c3 == -1);
+ if (c3 == -1) break;
+
+ out.writeByte(((c2 & 0x0f) << 4) | ((c3 & 0x3c) >> 2));
+
+ //c4
+ do {
+ c4 = byteString[i++];
+ if (c4 == 61) return out;
+
+ c4 = _decodeChars[c4];
+ } while (i < len && c4 == -1);
+ if (c4 == -1) break;
+
+ out.writeByte(((c3 & 0x03) << 6) | c4);
+
+ }
+
+ out.position = 0;
+
+ return out;
+ }
+
+ public static function encode(data : String) : String {
+ // Convert string to ByteArray
+ var bytes : ByteArray = new ByteArray();
+ bytes.writeUTFBytes(data);
+
+ // Return encoded ByteArray
+ return encodeByteArray(bytes);
+ }
+
+ public static function decode(data : String) : String {
+ // Decode data to ByteArray
+ var bytes : ByteArray = decodeToByteArray(data);
+
+ // Convert to string and return
+ return bytes.readUTFBytes(bytes.length);
+ }
+
+ public static function InitEncoreChar() : Vector.<int>
+ {
+ var encodeChars : Vector.<int> = new Vector.<int>();
+ // We could push the number directly, but i think it's nice to see the characters (with no overhead on encode/decode)
+ var chars : String = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+ for (var i : int = 0; i < 64; i++)
+ {
+ encodeChars.push(chars.charCodeAt(i));
+ }
+ /*
+ encodeChars.push(
+ 65, 66, 67, 68, 69, 70, 71, 72,
+ 73, 74, 75, 76, 77, 78, 79, 80,
+ 81, 82, 83, 84, 85, 86, 87, 88,
+ 89, 90, 97, 98, 99, 100, 101, 102,
+ 103, 104, 105, 106, 107, 108, 109, 110,
+ 111, 112, 113, 114, 115, 116, 117, 118,
+ 119, 120, 121, 122, 48, 49, 50, 51,
+ 52, 53, 54, 55, 56, 57, 43, 47);
+ */
+ return encodeChars;
+ }
+
+ public static function InitDecodeChar() : Vector.<int>
+ {
+ var decodeChars : Vector.<int> = new Vector.<int>();
+
+ decodeChars.push(-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,
+ 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1,
+ -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
+ -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
+ 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1
+ - 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1);
+ return decodeChars;
+ }
+ }
+}
\ No newline at end of file diff --git a/flash-src/third-party/com/hurlant/util/Hex.as b/flash-src/third-party/com/hurlant/util/Hex.as new file mode 100755 index 0000000..98d887b --- /dev/null +++ b/flash-src/third-party/com/hurlant/util/Hex.as @@ -0,0 +1,66 @@ +/**
+ * Hex
+ *
+ * Utility class to convert Hex strings to ByteArray or String types.
+ * Copyright (c) 2007 Henri Torgemane
+ *
+ * See LICENSE.txt for full license information.
+ */
+package com.hurlant.util
+{
+ import flash.utils.ByteArray;
+
+ public class Hex
+ {
+ /**
+ * Support straight hex, or colon-laced hex.
+ * (that means 23:03:0e:f0, but *NOT* 23:3:e:f0)
+ * Whitespace characters are ignored.
+ */
+ public static function toArray(hex:String):ByteArray {
+ hex = hex.replace(/\s|:/gm,'');
+ var a:ByteArray = new ByteArray;
+ if (hex.length&1==1) hex="0"+hex;
+ for (var i:uint=0;i<hex.length;i+=2) {
+ a[i/2] = parseInt(hex.substr(i,2),16);
+ }
+ return a;
+ }
+
+ public static function fromArray(array:ByteArray, colons:Boolean=false):String {
+ var s:String = "";
+ for (var i:uint=0;i<array.length;i++) {
+ s+=("0"+array[i].toString(16)).substr(-2,2);
+ if (colons) {
+ if (i<array.length-1) s+=":";
+ }
+ }
+ return s;
+ }
+
+ /**
+ *
+ * @param hex
+ * @return a UTF-8 string decoded from hex
+ *
+ */
+ public static function toString(hex:String):String {
+ var a:ByteArray = toArray(hex);
+ return a.readUTFBytes(a.length);
+ }
+
+
+ /**
+ *
+ * @param str
+ * @return a hex string encoded from the UTF-8 string str
+ *
+ */
+ public static function fromString(str:String, colons:Boolean=false):String {
+ var a:ByteArray = new ByteArray;
+ a.writeUTFBytes(str);
+ return fromArray(a, colons);
+ }
+
+ }
+}
\ No newline at end of file diff --git a/flash-src/third-party/com/hurlant/util/Memory.as b/flash-src/third-party/com/hurlant/util/Memory.as new file mode 100755 index 0000000..688e1bc --- /dev/null +++ b/flash-src/third-party/com/hurlant/util/Memory.as @@ -0,0 +1,28 @@ +/**
+ * Memory
+ *
+ * A class with a few memory-management methods, as much as
+ * such a thing exists in a Flash player.
+ * Copyright (c) 2007 Henri Torgemane
+ *
+ * See LICENSE.txt for full license information.
+ */
+package com.hurlant.util
+{
+ import flash.net.LocalConnection;
+ import flash.system.System;
+
+ public class Memory
+ {
+ public static function gc():void {
+ // force a GC
+ try {
+ new LocalConnection().connect('foo');
+ new LocalConnection().connect('foo');
+ } catch (e:*) {}
+ }
+ public static function get used():uint {
+ return System.totalMemory;
+ }
+ }
+}
\ No newline at end of file diff --git a/flash-src/third-party/com/hurlant/util/der/ByteString.as b/flash-src/third-party/com/hurlant/util/der/ByteString.as new file mode 100755 index 0000000..fb8b280 --- /dev/null +++ b/flash-src/third-party/com/hurlant/util/der/ByteString.as @@ -0,0 +1,43 @@ +/**
+ * ByteString
+ *
+ * An ASN1 type for a ByteString, represented with a ByteArray
+ * Copyright (c) 2007 Henri Torgemane
+ *
+ * See LICENSE.txt for full license information.
+ */
+package com.hurlant.util.der
+{
+ import flash.utils.ByteArray;
+ import com.hurlant.util.Hex;
+
+ public class ByteString extends ByteArray implements IAsn1Type
+ {
+ private var type:uint;
+ private var len:uint;
+
+ public function ByteString(type:uint = 0x04, length:uint = 0x00) {
+ this.type = type;
+ this.len = length;
+ }
+
+ public function getLength():uint
+ {
+ return len;
+ }
+
+ public function getType():uint
+ {
+ return type;
+ }
+
+ public function toDER():ByteArray {
+ return DER.wrapDER(type, this);
+ }
+
+ override public function toString():String {
+ return DER.indent+"ByteString["+type+"]["+len+"]["+Hex.fromArray(this)+"]";
+ }
+
+ }
+}
\ No newline at end of file diff --git a/flash-src/third-party/com/hurlant/util/der/DER.as b/flash-src/third-party/com/hurlant/util/der/DER.as new file mode 100755 index 0000000..bb5ecce --- /dev/null +++ b/flash-src/third-party/com/hurlant/util/der/DER.as @@ -0,0 +1,210 @@ +/**
+ * DER
+ *
+ * A basic class to parse DER structures.
+ * It is very incomplete, but sufficient to extract whatever data we need so far.
+ * Copyright (c) 2007 Henri Torgemane
+ *
+ * See LICENSE.txt for full license information.
+ */
+package com.hurlant.util.der
+{
+ import com.hurlant.math.BigInteger;
+
+ import flash.utils.ByteArray;
+ import com.hurlant.util.der.Sequence;
+ import com.hurlant.util.Hex;
+
+ // goal 1: to be able to parse an RSA Private Key PEM file.
+ // goal 2: to parse an X509v3 cert. kinda.
+
+ /**
+ * DER for dummies:
+ * http://luca.ntop.org/Teaching/Appunti/asn1.html
+ *
+ * This class does the bare minimum to get by. if that.
+ */
+ public class DER
+ {
+ public static var indent:String = "";
+
+ public static function parse(der:ByteArray, structure:*=null):IAsn1Type {
+/* if (der.position==0) {
+ trace("DER.parse: "+Hex.fromArray(der));
+ }
+ */ // type
+ var type:int = der.readUnsignedByte();
+ var constructed:Boolean = (type&0x20)!=0;
+ type &=0x1F;
+ // length
+ var len:int = der.readUnsignedByte();
+ if (len>=0x80) {
+ // long form of length
+ var count:int = len & 0x7f;
+ len = 0;
+ while (count>0) {
+ len = (len<<8) | der.readUnsignedByte();
+ count--;
+ }
+ }
+ // data
+ var b:ByteArray
+ switch (type) {
+ case 0x00: // WHAT IS THIS THINGY? (seen as 0xa0)
+ // (note to self: read a spec someday.)
+ // for now, treat as a sequence.
+ case 0x10: // SEQUENCE/SEQUENCE OF. whatever
+ // treat as an array
+ var p:int = der.position;
+ var o:Sequence = new Sequence(type, len);
+ var arrayStruct:Array = structure as Array;
+ if (arrayStruct!=null) {
+ // copy the array, as we destroy it later.
+ arrayStruct = arrayStruct.concat();
+ }
+ while (der.position < p+len) {
+ var tmpStruct:Object = null
+ if (arrayStruct!=null) {
+ tmpStruct = arrayStruct.shift();
+ }
+ if (tmpStruct!=null) {
+ while (tmpStruct && tmpStruct.optional) {
+ // make sure we have something that looks reasonable. XXX I'm winging it here..
+ var wantConstructed:Boolean = (tmpStruct.value is Array);
+ var isConstructed:Boolean = isConstructedType(der);
+ if (wantConstructed!=isConstructed) {
+ // not found. put default stuff, or null
+ o.push(tmpStruct.defaultValue);
+ o[tmpStruct.name] = tmpStruct.defaultValue;
+ // try the next thing
+ tmpStruct = arrayStruct.shift();
+ } else {
+ break;
+ }
+ }
+ }
+ if (tmpStruct!=null) {
+ var name:String = tmpStruct.name;
+ var value:* = tmpStruct.value;
+ if (tmpStruct.extract) {
+ // we need to keep a binary copy of this element
+ var size:int = getLengthOfNextElement(der);
+ var ba:ByteArray = new ByteArray;
+ ba.writeBytes(der, der.position, size);
+ o[name+"_bin"] = ba;
+ }
+ var obj:IAsn1Type = DER.parse(der, value);
+ o.push(obj);
+ o[name] = obj;
+ } else {
+ o.push(DER.parse(der));
+ }
+ }
+ return o;
+ case 0x11: // SET/SET OF
+ p = der.position;
+ var s:Set = new Set(type, len);
+ while (der.position < p+len) {
+ s.push(DER.parse(der));
+ }
+ return s;
+ case 0x02: // INTEGER
+ // put in a BigInteger
+ b = new ByteArray;
+ der.readBytes(b,0,len);
+ b.position=0;
+ return new Integer(type, len, b);
+ case 0x06: // OBJECT IDENTIFIER:
+ b = new ByteArray;
+ der.readBytes(b,0,len);
+ b.position=0;
+ return new ObjectIdentifier(type, len, b);
+ default:
+ trace("I DONT KNOW HOW TO HANDLE DER stuff of TYPE "+type);
+ // fall through
+ case 0x03: // BIT STRING
+ if (der[der.position]==0) {
+ //trace("Horrible Bit String pre-padding removal hack."); // I wish I had the patience to find a spec for this.
+ der.position++;
+ len--;
+ }
+ case 0x04: // OCTET STRING
+ // stuff in a ByteArray for now.
+ var bs:ByteString = new ByteString(type, len);
+ der.readBytes(bs,0,len);
+ return bs;
+ case 0x05: // NULL
+ // if len!=0, something's horribly wrong.
+ // should I check?
+ return null;
+ case 0x13: // PrintableString
+ var ps:PrintableString = new PrintableString(type, len);
+ ps.setString(der.readMultiByte(len, "US-ASCII"));
+ return ps;
+ case 0x22: // XXX look up what this is. openssl uses this to store my email.
+ case 0x14: // T61String - an horrible format we don't even pretend to support correctly
+ ps = new PrintableString(type, len);
+ ps.setString(der.readMultiByte(len, "latin1"));
+ return ps;
+ case 0x17: // UTCTime
+ var ut:UTCTime = new UTCTime(type, len);
+ ut.setUTCTime(der.readMultiByte(len, "US-ASCII"));
+ return ut;
+ }
+ }
+
+ private static function getLengthOfNextElement(b:ByteArray):int {
+ var p:uint = b.position;
+ // length
+ b.position++;
+ var len:int = b.readUnsignedByte();
+ if (len>=0x80) {
+ // long form of length
+ var count:int = len & 0x7f;
+ len = 0;
+ while (count>0) {
+ len = (len<<8) | b.readUnsignedByte();
+ count--;
+ }
+ }
+ len += b.position-p; // length of length
+ b.position = p;
+ return len;
+ }
+ private static function isConstructedType(b:ByteArray):Boolean {
+ var type:int = b[b.position];
+ return (type&0x20)!=0;
+ }
+
+ public static function wrapDER(type:int, data:ByteArray):ByteArray {
+ var d:ByteArray = new ByteArray;
+ d.writeByte(type);
+ var len:int = data.length;
+ if (len<128) {
+ d.writeByte(len);
+ } else if (len<256) {
+ d.writeByte(1 | 0x80);
+ d.writeByte(len);
+ } else if (len<65536) {
+ d.writeByte(2 | 0x80);
+ d.writeByte(len>>8);
+ d.writeByte(len);
+ } else if (len<65536*256) {
+ d.writeByte(3 | 0x80);
+ d.writeByte(len>>16);
+ d.writeByte(len>>8);
+ d.writeByte(len);
+ } else {
+ d.writeByte(4 | 0x80);
+ d.writeByte(len>>24);
+ d.writeByte(len>>16);
+ d.writeByte(len>>8);
+ d.writeByte(len);
+ }
+ d.writeBytes(data);
+ d.position=0;
+ return d;
+
+ }
+ }
+}
\ No newline at end of file diff --git a/flash-src/third-party/com/hurlant/util/der/IAsn1Type.as b/flash-src/third-party/com/hurlant/util/der/IAsn1Type.as new file mode 100755 index 0000000..f4f2112 --- /dev/null +++ b/flash-src/third-party/com/hurlant/util/der/IAsn1Type.as @@ -0,0 +1,21 @@ +/**
+ * IAsn1Type
+ *
+ * An interface for Asn-1 types.
+ * Copyright (c) 2007 Henri Torgemane
+ *
+ * See LICENSE.txt for full license information.
+ */
+package com.hurlant.util.der
+{
+ import flash.utils.ByteArray;
+
+ public interface IAsn1Type
+ {
+ function getType():uint;
+ function getLength():uint;
+
+ function toDER():ByteArray;
+
+ }
+}
\ No newline at end of file diff --git a/flash-src/third-party/com/hurlant/util/der/Integer.as b/flash-src/third-party/com/hurlant/util/der/Integer.as new file mode 100755 index 0000000..e2f045c --- /dev/null +++ b/flash-src/third-party/com/hurlant/util/der/Integer.as @@ -0,0 +1,44 @@ +/**
+ * Integer
+ *
+ * An ASN1 type for an Integer, represented with a BigInteger
+ * Copyright (c) 2007 Henri Torgemane
+ *
+ * See LICENSE.txt for full license information.
+ */
+package com.hurlant.util.der
+{
+ import com.hurlant.math.BigInteger;
+ import flash.utils.ByteArray;
+
+ public class Integer extends BigInteger implements IAsn1Type
+ {
+ private var type:uint;
+ private var len:uint;
+
+ public function Integer(type:uint, length:uint, b:ByteArray) {
+ this.type = type;
+ this.len = length;
+ super(b);
+ }
+
+ public function getLength():uint
+ {
+ return len;
+ }
+
+ public function getType():uint
+ {
+ return type;
+ }
+
+ override public function toString(radix:Number=0):String {
+ return DER.indent+"Integer["+type+"]["+len+"]["+super.toString(16)+"]";
+ }
+
+ public function toDER():ByteArray {
+ return null;
+ }
+
+ }
+}
\ No newline at end of file diff --git a/flash-src/third-party/com/hurlant/util/der/OID.as b/flash-src/third-party/com/hurlant/util/der/OID.as new file mode 100755 index 0000000..4d43d95 --- /dev/null +++ b/flash-src/third-party/com/hurlant/util/der/OID.as @@ -0,0 +1,35 @@ +/**
+ * OID
+ *
+ * A list of various ObjectIdentifiers.
+ * Copyright (c) 2007 Henri Torgemane
+ *
+ * See LICENSE.txt for full license information.
+ */
+package com.hurlant.util.der
+{
+ public class OID
+ {
+
+ public static const RSA_ENCRYPTION:String = "1.2.840.113549.1.1.1";
+ public static const MD2_WITH_RSA_ENCRYPTION:String = "1.2.840.113549.1.1.2";
+ public static const MD5_WITH_RSA_ENCRYPTION:String = "1.2.840.113549.1.1.4";
+ public static const SHA1_WITH_RSA_ENCRYPTION:String = "1.2.840.113549.1.1.5";
+ public static const MD2_ALGORITHM:String = "1.2.840.113549.2.2";
+ public static const MD5_ALGORITHM:String = "1.2.840.113549.2.5";
+ public static const DSA:String = "1.2.840.10040.4.1";
+ public static const DSA_WITH_SHA1:String = "1.2.840.10040.4.3";
+ public static const DH_PUBLIC_NUMBER:String = "1.2.840.10046.2.1";
+ public static const SHA1_ALGORITHM:String = "1.3.14.3.2.26";
+
+ public static const COMMON_NAME:String = "2.5.4.3";
+ public static const SURNAME:String = "2.5.4.4";
+ public static const COUNTRY_NAME:String = "2.5.4.6";
+ public static const LOCALITY_NAME:String = "2.5.4.7";
+ public static const STATE_NAME:String = "2.5.4.8";
+ public static const ORGANIZATION_NAME:String = "2.5.4.10";
+ public static const ORG_UNIT_NAME:String = "2.5.4.11";
+ public static const TITLE:String = "2.5.4.12";
+
+ }
+}
\ No newline at end of file diff --git a/flash-src/third-party/com/hurlant/util/der/ObjectIdentifier.as b/flash-src/third-party/com/hurlant/util/der/ObjectIdentifier.as new file mode 100755 index 0000000..932acd7 --- /dev/null +++ b/flash-src/third-party/com/hurlant/util/der/ObjectIdentifier.as @@ -0,0 +1,112 @@ +/**
+ * ObjectIdentifier
+ *
+ * An ASN1 type for an ObjectIdentifier
+ * We store the oid in an Array.
+ * Copyright (c) 2007 Henri Torgemane
+ *
+ * See LICENSE.txt for full license information.
+ */
+package com.hurlant.util.der
+{
+ import flash.utils.ByteArray;
+
+ public class ObjectIdentifier implements IAsn1Type
+ {
+ private var type:uint;
+ private var len:uint;
+ private var oid:Array;
+
+ public function ObjectIdentifier(type:uint, length:uint, b:*) {
+ this.type = type;
+ this.len = length;
+ if (b is ByteArray) {
+ parse(b as ByteArray);
+ } else if (b is String) {
+ generate(b as String);
+ } else {
+ throw new Error("Invalid call to new ObjectIdentifier");
+ }
+ }
+
+ private function generate(s:String):void {
+ oid = s.split(".");
+ }
+
+ private function parse(b:ByteArray):void {
+ // parse stuff
+ // first byte = 40*value1 + value2
+ var o:uint = b.readUnsignedByte();
+ var a:Array = []
+ a.push(uint(o/40));
+ a.push(uint(o%40));
+ var v:uint = 0;
+ while (b.bytesAvailable>0) {
+ o = b.readUnsignedByte();
+ var last:Boolean = (o&0x80)==0;
+ o &= 0x7f;
+ v = v*128 + o;
+ if (last) {
+ a.push(v);
+ v = 0;
+ }
+ }
+ oid = a;
+ }
+
+ public function getLength():uint
+ {
+ return len;
+ }
+
+ public function getType():uint
+ {
+ return type;
+ }
+
+ public function toDER():ByteArray {
+ var tmp:Array = [];
+ tmp[0] = oid[0]*40 + oid[1];
+ for (var i:int=2;i<oid.length;i++) {
+ var v:int = parseInt(oid[i]);
+ if (v<128) {
+ tmp.push(v);
+ } else if (v<128*128) {
+ tmp.push( (v>>7)|0x80 );
+ tmp.push( v&0x7f );
+ } else if (v<128*128*128) {
+ tmp.push( (v>>14)|0x80 );
+ tmp.push( (v>>7)&0x7f | 0x80 );
+ tmp.push( v&0x7f);
+ } else if (v<128*128*128*128) {
+ tmp.push( (v>>21)|0x80 );
+ tmp.push( (v>>14) & 0x7f | 0x80 );
+ tmp.push( (v>>7) & 0x7f | 0x80 );
+ tmp.push( v & 0x7f );
+ } else {
+ throw new Error("OID element bigger than we thought. :(");
+ }
+ }
+ len = tmp.length;
+ if (type==0) {
+ type = 6;
+ }
+ tmp.unshift(len); // assume length is small enough to fit here.
+ tmp.unshift(type);
+ var b:ByteArray = new ByteArray;
+ for (i=0;i<tmp.length;i++) {
+ b[i] = tmp[i];
+ }
+ return b;
+ }
+
+ public function toString():String {
+ return DER.indent+oid.join(".");
+ }
+
+ public function dump():String {
+ return "OID["+type+"]["+len+"]["+toString()+"]";
+ }
+
+ }
+}
\ No newline at end of file diff --git a/flash-src/third-party/com/hurlant/util/der/PEM.as b/flash-src/third-party/com/hurlant/util/der/PEM.as new file mode 100755 index 0000000..5693e76 --- /dev/null +++ b/flash-src/third-party/com/hurlant/util/der/PEM.as @@ -0,0 +1,118 @@ +/**
+ * PEM
+ *
+ * A class to parse some PEM stuff.
+ * Copyright (c) 2007 Henri Torgemane
+ *
+ * See LICENSE.txt for full license information.
+ */
+package com.hurlant.util.der
+{
+ import com.hurlant.crypto.rsa.RSAKey;
+ import com.hurlant.math.BigInteger;
+ import com.hurlant.util.Base64;
+
+ import flash.utils.ByteArray;
+ import com.hurlant.util.Hex;
+
+ public class PEM
+ {
+ private static const RSA_PRIVATE_KEY_HEADER:String = "-----BEGIN RSA PRIVATE KEY-----";
+ private static const RSA_PRIVATE_KEY_FOOTER:String = "-----END RSA PRIVATE KEY-----";
+ private static const RSA_PUBLIC_KEY_HEADER:String = "-----BEGIN PUBLIC KEY-----";
+ private static const RSA_PUBLIC_KEY_FOOTER:String = "-----END PUBLIC KEY-----";
+ private static const CERTIFICATE_HEADER:String = "-----BEGIN CERTIFICATE-----";
+ private static const CERTIFICATE_FOOTER:String = "-----END CERTIFICATE-----";
+
+
+
+ /**
+ *
+ * Read a structure encoded according to
+ * ftp://ftp.rsasecurity.com/pub/pkcs/ascii/pkcs-1v2.asc
+ * section 11.1.2
+ *
+ * @param str
+ * @return
+ *
+ */
+ public static function readRSAPrivateKey(str:String):RSAKey {
+ var der:ByteArray = extractBinary(RSA_PRIVATE_KEY_HEADER, RSA_PRIVATE_KEY_FOOTER, str);
+ if (der==null) return null;
+ var obj:* = DER.parse(der);
+ if (obj is Array) {
+ var arr:Array = obj as Array;
+ // arr[0] is Version. should be 0. should be checked. shoulda woulda coulda.
+ return new RSAKey(
+ arr[1], // N
+ arr[2].valueOf(), // E
+ arr[3], // D
+ arr[4], // P
+ arr[5], // Q
+ arr[6], // DMP1
+ arr[7], // DMQ1
+ arr[8]); // IQMP
+ } else {
+ // dunno
+ return null;
+ }
+ }
+
+
+ /**
+ * Read a structure encoded according to some spec somewhere
+ * Also, follows some chunk from
+ * ftp://ftp.rsasecurity.com/pub/pkcs/ascii/pkcs-1v2.asc
+ * section 11.1
+ *
+ * @param str
+ * @return
+ *
+ */
+ public static function readRSAPublicKey(str:String):RSAKey {
+ var der:ByteArray = extractBinary(RSA_PUBLIC_KEY_HEADER, RSA_PUBLIC_KEY_FOOTER, str);
+ if (der==null) return null;
+ var obj:* = DER.parse(der);
+ if (obj is Array) {
+ var arr:Array = obj as Array;
+ // arr[0] = [ <some crap that means "rsaEncryption">, null ]; ( apparently, that's an X-509 Algorithm Identifier.
+ if (arr[0][0].toString()!=OID.RSA_ENCRYPTION) {
+ return null;
+ }
+ // arr[1] is a ByteArray begging to be parsed as DER
+ arr[1].position = 1; // there's a 0x00 byte up front. find out why later. like, read a spec.
+ obj = DER.parse(arr[1]);
+ if (obj is Array) {
+ arr = obj as Array;
+ // arr[0] = modulus
+ // arr[1] = public expt.
+ return new RSAKey(arr[0], arr[1]);
+ } else {
+ return null;
+ }
+ } else {
+ // dunno
+ return null;
+ }
+ }
+
+ public static function readCertIntoArray(str:String):ByteArray {
+ var tmp:ByteArray = extractBinary(CERTIFICATE_HEADER, CERTIFICATE_FOOTER, str);
+ return tmp;
+ }
+
+ private static function extractBinary(header:String, footer:String, str:String):ByteArray {
+ var i:int = str.indexOf(header);
+ if (i==-1) return null;
+ i += header.length;
+ var j:int = str.indexOf(footer);
+ if (j==-1) return null;
+ var b64:String = str.substring(i, j);
+ // remove whitesapces.
+ b64 = b64.replace(/\s/mg, '');
+ // decode
+ return Base64.decodeToByteArray(b64);
+ }
+
+ }
+}
\ No newline at end of file diff --git a/flash-src/third-party/com/hurlant/util/der/PrintableString.as b/flash-src/third-party/com/hurlant/util/der/PrintableString.as new file mode 100755 index 0000000..ed1775e --- /dev/null +++ b/flash-src/third-party/com/hurlant/util/der/PrintableString.as @@ -0,0 +1,49 @@ +/**
+ * PrintableString
+ *
+ * An ASN1 type for a PrintableString, held within a String
+ * Copyright (c) 2007 Henri Torgemane
+ *
+ * See LICENSE.txt for full license information.
+ */
+package com.hurlant.util.der
+{
+ import flash.utils.ByteArray;
+
+ public class PrintableString implements IAsn1Type
+ {
+ protected var type:uint;
+ protected var len:uint;
+ protected var str:String;
+
+ public function PrintableString(type:uint, length:uint) {
+ this.type = type;
+ this.len = length;
+ }
+
+ public function getLength():uint
+ {
+ return len;
+ }
+
+ public function getType():uint
+ {
+ return type;
+ }
+
+ public function setString(s:String):void {
+ str = s;
+ }
+ public function getString():String {
+ return str;
+ }
+
+ public function toString():String {
+ return DER.indent+str;
+ }
+
+ public function toDER():ByteArray {
+ return null; // XXX not implemented
+ }
+ }
+}
\ No newline at end of file diff --git a/flash-src/third-party/com/hurlant/util/der/Sequence.as b/flash-src/third-party/com/hurlant/util/der/Sequence.as new file mode 100755 index 0000000..c352414 --- /dev/null +++ b/flash-src/third-party/com/hurlant/util/der/Sequence.as @@ -0,0 +1,90 @@ +/**
+ * Sequence
+ *
+ * An ASN1 type for a Sequence, implemented as an Array
+ * Copyright (c) 2007 Henri Torgemane
+ *
+ * See LICENSE.txt for full license information.
+ */
+package com.hurlant.util.der
+{
+ import flash.utils.ByteArray;
+
+ public dynamic class Sequence extends Array implements IAsn1Type
+ {
+ protected var type:uint;
+ protected var len:uint;
+
+ public function Sequence(type:uint = 0x30, length:uint = 0x00) {
+ this.type = type;
+ this.len = length;
+ }
+
+ public function getLength():uint
+ {
+ return len;
+ }
+
+ public function getType():uint
+ {
+ return type;
+ }
+
+ public function toDER():ByteArray {
+ var tmp:ByteArray = new ByteArray;
+ for (var i:int=0;i<length;i++) {
+ var e:IAsn1Type = this[i];
+ if (e == null) { // XXX Arguably, I could have a der.Null class instead
+ tmp.writeByte(0x05);
+ tmp.writeByte(0x00);
+ } else {
+ tmp.writeBytes(e.toDER());
+ }
+ }
+ return DER.wrapDER(type, tmp);
+ }
+
+ public function toString():String {
+ var s:String = DER.indent;
+ DER.indent += " ";
+ var t:String = "";
+ for (var i:int=0;i<length;i++) {
+ if (this[i]==null) continue;
+ var found:Boolean = false;
+ for (var key:String in this) {
+ if ( (i.toString()!=key) && this[i]==this[key]) {
+ t += key+": "+this[i]+"\n";
+ found = true;
+ break;
+ }
+ }
+ if (!found) t+=this[i]+"\n";
+ }
+// var t:String = join("\n");
+ DER.indent= s;
+ return DER.indent+"Sequence["+type+"]["+len+"][\n"+t+"\n"+s+"]";
+ }
+
+ /////////
+
+ public function findAttributeValue(oid:String):IAsn1Type {
+ for each (var set:* in this) {
+ if (set is Set) {
+ var child:* = set[0];
+ if (child is Sequence) {
+ var tmp:* = child[0];
+ if (tmp is ObjectIdentifier) {
+ var id:ObjectIdentifier = tmp as ObjectIdentifier;
+ if (id.toString()==oid) {
+ return child[1] as IAsn1Type;
+ }
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+
+ }
+}
\ No newline at end of file diff --git a/flash-src/third-party/com/hurlant/util/der/Set.as b/flash-src/third-party/com/hurlant/util/der/Set.as new file mode 100755 index 0000000..c0bfa47 --- /dev/null +++ b/flash-src/third-party/com/hurlant/util/der/Set.as @@ -0,0 +1,27 @@ +/**
+ * Set
+ *
+ * An ASN1 type for an Set, that extends a Sequence
+ * Copyright (c) 2007 Henri Torgemane
+ *
+ * See LICENSE.txt for full license information.
+ */
+package com.hurlant.util.der
+{
+ public dynamic class Set extends Sequence implements IAsn1Type
+ {
+ public function Set(type:uint = 0x31, length:uint = 0x00) {
+ super(type, length);
+ }
+
+
+ public override function toString():String {
+ var s:String = DER.indent;
+ DER.indent += " ";
+ var t:String = join("\n");
+ DER.indent= s;
+ return DER.indent+"Set["+type+"]["+len+"][\n"+t+"\n"+s+"]";
+ }
+
+ }
+}
\ No newline at end of file diff --git a/flash-src/third-party/com/hurlant/util/der/Type.as b/flash-src/third-party/com/hurlant/util/der/Type.as new file mode 100755 index 0000000..3dc6dcd --- /dev/null +++ b/flash-src/third-party/com/hurlant/util/der/Type.as @@ -0,0 +1,94 @@ +/**
+ * Type
+ *
+ * A few Asn-1 structures
+ * Copyright (c) 2007 Henri Torgemane
+ *
+ * See LICENSE.txt for full license information.
+ */
+package com.hurlant.util.der
+{
+ import com.hurlant.util.Hex;
+
+ public class Type
+ {
+ public static const TLS_CERT:Array = [
+ {name:"signedCertificate", extract:true, value: [
+ {name:"versionHolder", optional:true, value: [
+ {name:"version"}
+ ], defaultValue: function():Sequence{
+ var s:Sequence = new Sequence(0, 0);
+ var v:Integer = new Integer(2,1, Hex.toArray("00"));
+ s.push(v);
+ s.version = v;
+ return s;
+ }()
+ },
+ {name:"serialNumber"},
+ {name:"signature", value: [
+ {name:"algorithmId"}
+ ]},
+ {name:"issuer", extract:true, value: [
+ {name:"type"},
+ {name:"value"}
+ ]},
+ {name:"validity", value: [
+ {name:"notBefore"},
+ {name:"notAfter"}
+ ]},
+ {name:"subject", extract:true, value: [
+ ]},
+ {name:"subjectPublicKeyInfo", value: [
+ {name:"algorithm", value: [
+ {name:"algorithmId"}
+ ]},
+ {name:"subjectPublicKey"}
+ ]},
+ {name:"extensions", value: [
+ ]}
+ ]},
+ {name:"algorithmIdentifier",value:[
+ {name:"algorithmId"}
+ ]},
+ {name:"encrypted", value:null}
+ ];
+ public static const CERTIFICATE:Array = [
+ {name:"tbsCertificate", value:[
+ {name:"tag0", value:[
+ {name:"version"}
+ ]},
+ {name:"serialNumber"},
+ {name:"signature"},
+ {name:"issuer", value:[
+ {name:"type"},
+ {name:"value"}
+ ]},
+ {name:"validity", value:[
+ {name:"notBefore"},
+ {name:"notAfter"}
+ ]},
+ {name:"subject"},
+ {name:"subjectPublicKeyInfo", value:[
+ {name:"algorithm"},
+ {name:"subjectPublicKey"}
+ ]},
+ {name:"issuerUniqueID"},
+ {name:"subjectUniqueID"},
+ {name:"extensions"}
+ ]},
+ {name:"signatureAlgorithm"},
+ {name:"signatureValue"}
+ ];
+ public static const RSA_PUBLIC_KEY:Array = [
+ {name:"modulus"},
+ {name:"publicExponent"}
+ ];
+ public static const RSA_SIGNATURE:Array = [
+ {name:"algorithm", value:[
+ {name:"algorithmId"}
+ ]},
+ {name:"hash"}
+ ];
+
+ }
+}
\ No newline at end of file diff --git a/flash-src/third-party/com/hurlant/util/der/UTCTime.as b/flash-src/third-party/com/hurlant/util/der/UTCTime.as new file mode 100755 index 0000000..4e49686 --- /dev/null +++ b/flash-src/third-party/com/hurlant/util/der/UTCTime.as @@ -0,0 +1,60 @@ +/**
+ * UTCTime
+ *
+ * An ASN1 type for UTCTime, represented as a Date
+ * Copyright (c) 2007 Henri Torgemane
+ *
+ * See LICENSE.txt for full license information.
+ */
+package com.hurlant.util.der
+{
+ import flash.utils.ByteArray;
+
+ public class UTCTime implements IAsn1Type
+ {
+ protected var type:uint;
+ protected var len:uint;
+ public var date:Date;
+
+ public function UTCTime(type:uint, len:uint)
+ {
+ this.type = type;
+ this.len = len;
+ }
+
+ public function getLength():uint
+ {
+ return len;
+ }
+
+ public function getType():uint
+ {
+ return type;
+ }
+
+ public function setUTCTime(str:String):void {
+
+ var year:uint = parseInt(str.substr(0, 2));
+ if (year<50) {
+ year+=2000;
+ } else {
+ year+=1900;
+ }
+ var month:uint = parseInt(str.substr(2,2));
+ var day:uint = parseInt(str.substr(4,2));
+ var hour:uint = parseInt(str.substr(6,2));
+ var minute:uint = parseInt(str.substr(8,2));
+ // XXX this could be off by up to a day. parse the rest. someday.
+ date = new Date(year, month-1, day, hour, minute);
+ }
+
+
+ public function toString():String {
+ return DER.indent+"UTCTime["+type+"]["+len+"]["+date+"]";
+ }
+
+ public function toDER():ByteArray {
+ return null // XXX not implemented
+ }
+ }
+}
\ No newline at end of file |