In _x509_getSubjectPublicKeyPosFromCertHex and _x509_getPublicKeyHexArrayFromCertHex, added an optional position argument to enable decoding a SubjectPublicKeyInfo directly.
diff --git a/js/tools/build/ndn-js-uncomp.js b/js/tools/build/ndn-js-uncomp.js
index 73d3862..3ec855a 100644
--- a/js/tools/build/ndn-js-uncomp.js
+++ b/js/tools/build/ndn-js-uncomp.js
@@ -92,7 +92,6 @@
this.transport = getTransport();
this.getHostAndPort = (settings.getHostAndPort || this.transport.defaultGetHostAndPort);
this.host = (settings.host !== undefined ? settings.host : 'localhost');
- dump("this.host " + this.host + "\n");
this.port = (settings.port || 9696);
this.readyStatus = NDN.UNOPEN;
// Event handler
@@ -341,7 +340,22 @@
var entry = getEntryForRegisteredPrefix(nameStr);
if (entry != null) {
//console.log(entry);
- entry.closure.upcall(Closure.UPCALL_INTEREST, new UpcallInfo(ndn, interest, 0, null));
+ var info = new UpcallInfo(ndn, interest, 0, null);
+ var ret = entry.closure.upcall(Closure.UPCALL_INTEREST, info);
+ if (ret == Closure.RESULT_INTEREST_CONSUMED && info.contentObject != null) {
+ var coBinary = encodeToBinaryContentObject(info.contentObject);
+ // If we directly use coBinary.buffer to feed ws.send(), WebSocket
+ // will end up sending a packet with 10000 bytes of data. That
+ // is, WebSocket will flush the entire buffer in BinaryXMLEncoder
+ // regardless of the offset of the Uint8Array. So we have to
+ // create a new Uint8Array buffer with just the right size and
+ // copy the content from coBinary to the new buffer.
+ // ---Wentao
+ var bytearray = new Uint8Array(coBinary.length);
+ bytearray.set(coBinary);
+
+ self.ws.send(bytearray.buffer);
+ }
}
} else if (decoder.peekStartElement(CCNProtocolDTags.ContentObject)) { // Content packet
@@ -1015,26 +1029,37 @@
/*
* Find the last component in name that has a ContentDigest and return the digest value as Uint8Array,
- * or null if not found.
- * A ContentDigest component is Name.ContentDigestPrefix + 32 bytes + Name.ContentDigestSuffix.
+ * or null if not found. See Name.getComponentContentDigestValue.
*/
Name.prototype.getContentDigestValue = function() {
- var digestComponentLength = Name.ContentDigestPrefix.length + 32 + Name.ContentDigestSuffix.length;
for (var i = this.components.length - 1; i >= 0; --i) {
- // Check for the correct length and equal ContentDigestPrefix and ContentDigestSuffix.
- if (this.components[i].length == digestComponentLength &&
- DataUtils.arraysEqual(this.components[i].subarray(0, Name.ContentDigestPrefix.length),
- Name.ContentDigestPrefix) &&
- DataUtils.arraysEqual(this.components[i].subarray
- (this.components[i].length - Name.ContentDigestSuffix.length, this.components[i].length),
- Name.ContentDigestSuffix))
- return this.components[i].subarray
- (Name.ContentDigestPrefix.length, Name.ContentDigestPrefix.length + 32);
+ var digestValue = Name.getComponentContentDigestValue(this.components[i]);
+ if (digestValue != null)
+ return digestValue;
}
return null;
}
+/*
+ * If component is a ContentDigest, return the digest value as a Uint8Array subarray (don't modify!).
+ * If not a ContentDigest, return null.
+ * A ContentDigest component is Name.ContentDigestPrefix + 32 bytes + Name.ContentDigestSuffix.
+ */
+Name.getComponentContentDigestValue = function(component) {
+ var digestComponentLength = Name.ContentDigestPrefix.length + 32 + Name.ContentDigestSuffix.length;
+ // Check for the correct length and equal ContentDigestPrefix and ContentDigestSuffix.
+ if (component.length == digestComponentLength &&
+ DataUtils.arraysEqual(component.subarray(0, Name.ContentDigestPrefix.length),
+ Name.ContentDigestPrefix) &&
+ DataUtils.arraysEqual(component.subarray
+ (component.length - Name.ContentDigestSuffix.length, component.length),
+ Name.ContentDigestSuffix))
+ return component.subarray(Name.ContentDigestPrefix.length, Name.ContentDigestPrefix.length + 32);
+ else
+ return null;
+}
+
// Meta GUID "%C1.M.G%C1" + ContentDigest with a 32 byte BLOB.
Name.ContentDigestPrefix = new Uint8Array([0xc1, 0x2e, 0x4d, 0x2e, 0x47, 0xc1, 0x01, 0xaa, 0x02, 0x85]);
Name.ContentDigestSuffix = new Uint8Array([0x00]);
@@ -1080,7 +1105,7 @@
var ContentObject = function ContentObject(_name,_signedInfo,_content,_signature){
- if (typeof _name === 'string'){
+ if (typeof _name == 'string') {
this.name = new Name(_name);
}
else{
@@ -1088,7 +1113,13 @@
this.name = _name;
}
this.signedInfo = _signedInfo;
- this.content=_content;
+
+ if (typeof _content == 'string') {
+ this.content = DataUtils.toNumbersFromString(_content);
+ } else {
+ this.content = _content;
+ }
+
this.signature = _signature;
@@ -1344,6 +1375,9 @@
this.locator =_locator;//KeyLocator
this.freshnessSeconds =_freshnessSeconds; // Integer
this.finalBlockID=_finalBlockID; //byte array
+
+ // SWT: merge setFields() method into constructor
+ this.setFields();
};
@@ -4046,7 +4080,7 @@
/**
* Raw String to Uint8Array.
*/
-DataUtils.toNumbersFromString = function( str ){
+DataUtils.toNumbersFromString = function(str) {
var bytes = new Uint8Array(str.length);
for(var i=0;i<str.length;i++)
bytes[i] = str.charCodeAt(i);
@@ -4518,6 +4552,10 @@
if(LOG>2) console.log('EXPONENT is ');
if(LOG>2) console.log(exp);
+ var a = _x509_getPublicKeyHexArrayFromCertHex(publickeyHex, _x509_getSubjectPublicKeyPosFromCertHex(publickeyHex, 0));
+ output += "a[0] " + a[0] + "<br/>";
+ output += "a[1] " + a[1] + "<br/>";
+
/*var c1 = hex_sha256(input);
var c2 = signature;
@@ -4558,6 +4596,8 @@
return output;
}
+
+
/**
* @author: Meki Cheraoui
* See COPYING for copyright and distribution information.
@@ -6192,6 +6232,300 @@
ASN1HEX.getDecendantIndexByNthList = _asnhex_getDecendantIndexByNthList;
ASN1HEX.getDecendantHexVByNthList = _asnhex_getDecendantHexVByNthList;
ASN1HEX.getDecendantHexTLVByNthList = _asnhex_getDecendantHexTLVByNthList;
+/*! x509-1.1.js (c) 2012 Kenji Urushima | kjur.github.com/jsrsasign/license
+ */
+//
+// x509.js - X509 class to read subject public key from certificate.
+//
+// version: 1.1 (10-May-2012)
+//
+// Copyright (c) 2010-2012 Kenji Urushima (kenji.urushima@gmail.com)
+//
+// This software is licensed under the terms of the MIT License.
+// http://kjur.github.com/jsrsasign/license
+//
+// The above copyright and license notice shall be
+// included in all copies or substantial portions of the Software.
+//
+
+// Depends:
+// base64.js
+// rsa.js
+// asn1hex.js
+
+function _x509_pemToBase64(sCertPEM) {
+ var s = sCertPEM;
+ s = s.replace("-----BEGIN CERTIFICATE-----", "");
+ s = s.replace("-----END CERTIFICATE-----", "");
+ s = s.replace(/[ \n]+/g, "");
+ return s;
+}
+
+function _x509_pemToHex(sCertPEM) {
+ var b64Cert = _x509_pemToBase64(sCertPEM);
+ var hCert = b64tohex(b64Cert);
+ return hCert;
+}
+
+function _x509_getHexTbsCertificateFromCert(hCert) {
+ var pTbsCert = ASN1HEX.getStartPosOfV_AtObj(hCert, 0);
+ return pTbsCert;
+}
+
+// NOTE: privateKeyUsagePeriod field of X509v2 not supported.
+// NOTE: v1 and v3 supported
+function _x509_getSubjectPublicKeyInfoPosFromCertHex(hCert) {
+ var pTbsCert = ASN1HEX.getStartPosOfV_AtObj(hCert, 0);
+ var a = ASN1HEX.getPosArrayOfChildren_AtObj(hCert, pTbsCert);
+ if (a.length < 1) return -1;
+ if (hCert.substring(a[0], a[0] + 10) == "a003020102") { // v3
+ if (a.length < 6) return -1;
+ return a[6];
+ } else {
+ if (a.length < 5) return -1;
+ return a[5];
+ }
+}
+
+// NOTE: Without BITSTRING encapsulation.
+// If pInfo is supplied, it is the position in hCert of the SubjectPublicKeyInfo.
+function _x509_getSubjectPublicKeyPosFromCertHex(hCert, pInfo) {
+ if (pInfo == null)
+ pInfo = _x509_getSubjectPublicKeyInfoPosFromCertHex(hCert);
+ if (pInfo == -1) return -1;
+ var a = ASN1HEX.getPosArrayOfChildren_AtObj(hCert, pInfo);
+
+ if (a.length != 2) return -1;
+ var pBitString = a[1];
+ if (hCert.substring(pBitString, pBitString + 2) != '03') return -1;
+ var pBitStringV = ASN1HEX.getStartPosOfV_AtObj(hCert, pBitString);
+
+ if (hCert.substring(pBitStringV, pBitStringV + 2) != '00') return -1;
+ return pBitStringV + 2;
+}
+
+// If p is supplied, it is the public key position in hCert.
+function _x509_getPublicKeyHexArrayFromCertHex(hCert, p) {
+ if (p == null)
+ p = _x509_getSubjectPublicKeyPosFromCertHex(hCert);
+ var a = ASN1HEX.getPosArrayOfChildren_AtObj(hCert, p);
+ //var a = ASN1HEX.getPosArrayOfChildren_AtObj(hCert, a[3]);
+ if(LOG>4){
+ console.log('a is now');
+ console.log(a);
+ }
+
+ //if (a.length != 2) return [];
+ if (a.length < 2) return [];
+
+ var hN = ASN1HEX.getHexOfV_AtObj(hCert, a[0]);
+ var hE = ASN1HEX.getHexOfV_AtObj(hCert, a[1]);
+ if (hN != null && hE != null) {
+ return [hN, hE];
+ } else {
+ return [];
+ }
+}
+
+function _x509_getPublicKeyHexArrayFromCertPEM(sCertPEM) {
+ var hCert = _x509_pemToHex(sCertPEM);
+ var a = _x509_getPublicKeyHexArrayFromCertHex(hCert);
+ return a;
+}
+
+// ===== get basic fields from hex =====================================
+/**
+ * get hexadecimal string of serialNumber field of certificate.<br/>
+ * @name getSerialNumberHex
+ * @memberOf X509#
+ * @function
+ */
+function _x509_getSerialNumberHex() {
+ return ASN1HEX.getDecendantHexVByNthList(this.hex, 0, [0, 1]);
+}
+
+/**
+ * get hexadecimal string of issuer field of certificate.<br/>
+ * @name getIssuerHex
+ * @memberOf X509#
+ * @function
+ */
+function _x509_getIssuerHex() {
+ return ASN1HEX.getDecendantHexTLVByNthList(this.hex, 0, [0, 3]);
+}
+
+/**
+ * get string of issuer field of certificate.<br/>
+ * @name getIssuerString
+ * @memberOf X509#
+ * @function
+ */
+function _x509_getIssuerString() {
+ return _x509_hex2dn(ASN1HEX.getDecendantHexTLVByNthList(this.hex, 0, [0, 3]));
+}
+
+/**
+ * get hexadecimal string of subject field of certificate.<br/>
+ * @name getSubjectHex
+ * @memberOf X509#
+ * @function
+ */
+function _x509_getSubjectHex() {
+ return ASN1HEX.getDecendantHexTLVByNthList(this.hex, 0, [0, 5]);
+}
+
+/**
+ * get string of subject field of certificate.<br/>
+ * @name getSubjectString
+ * @memberOf X509#
+ * @function
+ */
+function _x509_getSubjectString() {
+ return _x509_hex2dn(ASN1HEX.getDecendantHexTLVByNthList(this.hex, 0, [0, 5]));
+}
+
+/**
+ * get notBefore field string of certificate.<br/>
+ * @name getNotBefore
+ * @memberOf X509#
+ * @function
+ */
+function _x509_getNotBefore() {
+ var s = ASN1HEX.getDecendantHexVByNthList(this.hex, 0, [0, 4, 0]);
+ s = s.replace(/(..)/g, "%$1");
+ s = decodeURIComponent(s);
+ return s;
+}
+
+/**
+ * get notAfter field string of certificate.<br/>
+ * @name getNotAfter
+ * @memberOf X509#
+ * @function
+ */
+function _x509_getNotAfter() {
+ var s = ASN1HEX.getDecendantHexVByNthList(this.hex, 0, [0, 4, 1]);
+ s = s.replace(/(..)/g, "%$1");
+ s = decodeURIComponent(s);
+ return s;
+}
+
+// ===== read certificate =====================================
+
+_x509_DN_ATTRHEX = {
+ "0603550406": "C",
+ "060355040a": "O",
+ "060355040b": "OU",
+ "0603550403": "CN",
+ "0603550405": "SN",
+ "0603550408": "ST",
+ "0603550407": "L" };
+
+function _x509_hex2dn(hDN) {
+ var s = "";
+ var a = ASN1HEX.getPosArrayOfChildren_AtObj(hDN, 0);
+ for (var i = 0; i < a.length; i++) {
+ var hRDN = ASN1HEX.getHexOfTLV_AtObj(hDN, a[i]);
+ s = s + "/" + _x509_hex2rdn(hRDN);
+ }
+ return s;
+}
+
+function _x509_hex2rdn(hRDN) {
+ var hType = ASN1HEX.getDecendantHexTLVByNthList(hRDN, 0, [0, 0]);
+ var hValue = ASN1HEX.getDecendantHexVByNthList(hRDN, 0, [0, 1]);
+ var type = "";
+ try { type = _x509_DN_ATTRHEX[hType]; } catch (ex) { type = hType; }
+ hValue = hValue.replace(/(..)/g, "%$1");
+ var value = decodeURIComponent(hValue);
+ return type + "=" + value;
+}
+
+// ===== read certificate =====================================
+
+
+/**
+ * read PEM formatted X.509 certificate from string.<br/>
+ * @name readCertPEM
+ * @memberOf X509#
+ * @function
+ * @param {String} sCertPEM string for PEM formatted X.509 certificate
+ */
+function _x509_readCertPEM(sCertPEM) {
+ var hCert = _x509_pemToHex(sCertPEM);
+ var a = _x509_getPublicKeyHexArrayFromCertHex(hCert);
+ if(LOG>4){
+ console.log('HEX VALUE IS ' + hCert);
+ console.log('type of a' + typeof a);
+ console.log('a VALUE IS ');
+ console.log(a);
+ console.log('a[0] VALUE IS ' + a[0]);
+ console.log('a[1] VALUE IS ' + a[1]);
+ }
+ var rsa = new RSAKey();
+ rsa.setPublic(a[0], a[1]);
+ this.subjectPublicKeyRSA = rsa;
+ this.subjectPublicKeyRSA_hN = a[0];
+ this.subjectPublicKeyRSA_hE = a[1];
+ this.hex = hCert;
+}
+
+/**
+ * read hex formatted X.509 certificate from string.
+ * @name readCertHex
+ * @memberOf X509#
+ * @function
+ * @param {String} hCert string for hex formatted X.509 certificate
+ */
+function _x509_readCertHex(hCert) {
+ hCert = hCert.toLowerCase();
+ var a = _x509_getPublicKeyHexArrayFromCertHex(hCert);
+ var rsa = new RSAKey();
+ rsa.setPublic(a[0], a[1]);
+ this.subjectPublicKeyRSA = rsa;
+ this.subjectPublicKeyRSA_hN = a[0];
+ this.subjectPublicKeyRSA_hE = a[1];
+ this.hex = hCert;
+}
+
+function _x509_readCertPEMWithoutRSAInit(sCertPEM) {
+ var hCert = _x509_pemToHex(sCertPEM);
+ var a = _x509_getPublicKeyHexArrayFromCertHex(hCert);
+ this.subjectPublicKeyRSA.setPublic(a[0], a[1]);
+ this.subjectPublicKeyRSA_hN = a[0];
+ this.subjectPublicKeyRSA_hE = a[1];
+ this.hex = hCert;
+}
+
+/**
+ * X.509 certificate class.<br/>
+ * @class X.509 certificate class
+ * @property {RSAKey} subjectPublicKeyRSA Tom Wu's RSAKey object
+ * @property {String} subjectPublicKeyRSA_hN hexadecimal string for modulus of RSA public key
+ * @property {String} subjectPublicKeyRSA_hE hexadecimal string for public exponent of RSA public key
+ * @property {String} hex hexacedimal string for X.509 certificate.
+ * @author Kenji Urushima
+ * @version 1.0.1 (08 May 2012)
+ * @see <a href="http://kjur.github.com/jsrsasigns/">'jwrsasign'(RSA Sign JavaScript Library) home page http://kjur.github.com/jsrsasign/</a>
+ */
+function X509() {
+ this.subjectPublicKeyRSA = null;
+ this.subjectPublicKeyRSA_hN = null;
+ this.subjectPublicKeyRSA_hE = null;
+ this.hex = null;
+}
+
+X509.prototype.readCertPEM = _x509_readCertPEM;
+X509.prototype.readCertHex = _x509_readCertHex;
+X509.prototype.readCertPEMWithoutRSAInit = _x509_readCertPEMWithoutRSAInit;
+X509.prototype.getSerialNumberHex = _x509_getSerialNumberHex;
+X509.prototype.getIssuerHex = _x509_getIssuerHex;
+X509.prototype.getSubjectHex = _x509_getSubjectHex;
+X509.prototype.getIssuerString = _x509_getIssuerString;
+X509.prototype.getSubjectString = _x509_getSubjectString;
+X509.prototype.getNotBefore = _x509_getNotBefore;
+X509.prototype.getNotAfter = _x509_getNotAfter;
+
// Copyright (c) 2005 Tom Wu
// All Rights Reserved.
// See "LICENSE" for details.
diff --git a/js/tools/build/ndn-js.js b/js/tools/build/ndn-js.js
index aa51fd6..c3f12d3 100644
--- a/js/tools/build/ndn-js.js
+++ b/js/tools/build/ndn-js.js
@@ -148,9 +148,10 @@
b+"<br />";2<LOG&&console.log(" ContentName + SignedInfo + Content = "+g);2<LOG&&console.log("HEX OF ContentName + SignedInfo + Content = ");2<LOG&&console.log(DataUtils.stringtoBase64(g));2<LOG&&console.log(" PublicKey = "+d);2<LOG&&console.log(" PublicKeyHex = "+e);2<LOG&&console.log(" PublicKeyString = "+f);2<LOG&&console.log(" Signature is");2<LOG&&console.log(c);e=new X509;e.readCertPEM(d);c=e.subjectPublicKeyRSA.verifyByteArray(a.rawSignatureData,c);2<LOG&&console.log("result is "+c);d=e.subjectPublicKeyRSA.n;
e=e.subjectPublicKeyRSA.e;2<LOG&&console.log("PUBLIC KEY n after is ");2<LOG&&console.log(d);2<LOG&&console.log("EXPONENT e after is ");2<LOG&&console.log(e);b=c?b+"SIGNATURE VALID":b+"SIGNATURE INVALID";b+="<br />";b+="<br />"}null!=a.signedInfo&&(null!=a.signedInfo.locator&&null!=a.signedInfo.locator.publicKey)&&(d=rstr2b64(DataUtils.toString(a.signedInfo.locator.publicKey)),e=DataUtils.toHex(a.signedInfo.locator.publicKey).toLowerCase(),f=DataUtils.toString(a.signedInfo.locator.publicKey),c=DataUtils.toHex(a.signature.signature).toLowerCase(),
g=DataUtils.toString(a.rawSignatureData),b+="DER Certificate: "+d,b+="<br />",b+="<br />",2<LOG&&console.log(" ContentName + SignedInfo + Content = "+g),2<LOG&&console.log(" PublicKey = "+d),2<LOG&&console.log(" PublicKeyHex = "+e),2<LOG&&console.log(" PublicKeyString = "+f),2<LOG&&console.log(" Signature "+c),2<LOG&&console.log(" Signature NOW IS"),2<LOG&&console.log(a.signature.signature),d=e.slice(56,314),b+="PUBLISHER KEY(hex): "+d,b+="<br />",b+="<br />",2<LOG&&console.log("PUBLIC KEY IN HEX is "),
-2<LOG&&console.log(d),f=e.slice(318,324),2<LOG&&console.log("kp size is "+d.length),b+="exponent: "+f,b+="<br />",b+="<br />",2<LOG&&console.log("EXPONENT is "),2<LOG&&console.log(f),e=new RSAKey,e.setPublic(d,f),c=e.verifyByteArray(a.rawSignatureData,c),2<LOG&&console.log("PUBLIC KEY n after is "),2<LOG&&console.log(e.n),2<LOG&&console.log("EXPONENT e after is "),2<LOG&&console.log(e.e),b=c?b+"SIGNATURE VALID":b+"SIGNATURE INVALID",b+="<br />",b+="<br />")}return b}
-var KeyManager=function(){this.certificate="MIIBmzCCAQQCCQC32FyQa61S7jANBgkqhkiG9w0BAQUFADASMRAwDgYDVQQDEwdheGVsY2R2MB4XDTEyMDQyODIzNDQzN1oXDTEyMDUyODIzNDQzN1owEjEQMA4GA1UEAxMHYXhlbGNkdjCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA4X0wp9goqxuECxdULcr2IHr9Ih4Iaypg0Wy39URIup8/CLzQmdsh3RYqd55hqonu5VTTpH3iMLx6xZDVJAZ8OJi7pvXcQ2C4Re2kjL2c8SanI0RfDhlS1zJadfr1VhRPmpivcYawJ4aFuOLAi+qHFxtN7lhcGCgpW1OV60oXd58CAwEAATANBgkqhkiG9w0BAQUFAAOBgQDLOrA1fXzSrpftUB5Ro6DigX1Bjkf7F5Bkd69hSVp+jYeJFBBlsILQAfSxUZPQtD+2Yc3iCmSYNyxqu9PcufDRJlnvB7PG29+L3y9lR37tetzUV9eTscJ7rdp8Wt6AzpW32IJ/54yKNfP7S6ZIoIG+LP6EIxq6s8K1MXRt8uBJKw==";
-this.publicKey="30819F300D06092A864886F70D010101050003818D0030818902818100E17D30A7D828AB1B840B17542DCAF6207AFD221E086B2A60D16CB7F54448BA9F3F08BCD099DB21DD162A779E61AA89EEE554D3A47DE230BC7AC590D524067C3898BBA6F5DC4360B845EDA48CBD9CF126A723445F0E1952D7325A75FAF556144F9A98AF7186B0278685B8E2C08BEA87171B4DEE585C1828295B5395EB4A17779F0203010001";this.privateKey="MIICXQIBAAKBgQDhfTCn2CirG4QLF1QtyvYgev0iHghrKmDRbLf1REi6nz8IvNCZ2yHdFip3nmGqie7lVNOkfeIwvHrFkNUkBnw4mLum9dxDYLhF7aSMvZzxJqcjRF8OGVLXMlp1+vVWFE+amK9xhrAnhoW44sCL6ocXG03uWFwYKClbU5XrShd3nwIDAQABAoGAGkv6T6jC3WmhFZYL6CdCWvlc6gysmKrhjarrLTxgavtFY6R5g2ft5BXAsCCVbUkWxkIFSKqxpVNl0gKZCNGEzPDN6mHJOQI/h0rlxNIHAuGfoAbCzALnqmyZivhJAPGijAyKuU9tczsst5+Kpn+bn7ehzHQuj7iwJonS5WbojqECQQD851K8TpW2GrRizNgG4dx6orZxAaon/Jnl8lS7soXhllQty7qG+oDfzznmdMsiznCqEABzHUUKOVGE9RWPN3aRAkEA5D/w9N55d0ibnChFJlc8cUAoaqH+w+U3oQP2Lb6AZHJpLptN4y4b/uf5d4wYU5/i/gC7SSBH3wFhh9bjRLUDLwJAVOx8vN0Kqt7myfKNbCo19jxjVSlA8TKCn1Oznl/BU1I+rC4oUaEW25DjmX6IpAR8kq7S59ThVSCQPjxqY/A08QJBAIRaF2zGPITQk3r/VumemCvLWiRK/yG0noc9dtibqHOWbCtcXtOm/xDWjq+lis2i3ssOvYrvrv0/HcDY+Dv1An0CQQCLJtMsfSg4kvG/FRY5UMhtMuwo8ovYcMXt4Xv/LWaMhndD67b2UGawQCRqr5ghRTABWdDD/HuuMBjrkPsX0861"};
+2<LOG&&console.log(d),f=e.slice(318,324),2<LOG&&console.log("kp size is "+d.length),b+="exponent: "+f,b+="<br />",b+="<br />",2<LOG&&console.log("EXPONENT is "),2<LOG&&console.log(f),e=_x509_getPublicKeyHexArrayFromCertHex(e,_x509_getSubjectPublicKeyPosFromCertHex(e,0)),b+="a[0] "+e[0]+"<br/>",b+="a[1] "+e[1]+"<br/>",e=new RSAKey,e.setPublic(d,f),c=e.verifyByteArray(a.rawSignatureData,c),2<LOG&&console.log("PUBLIC KEY n after is "),2<LOG&&console.log(e.n),2<LOG&&console.log("EXPONENT e after is "),
+2<LOG&&console.log(e.e),b=c?b+"SIGNATURE VALID":b+"SIGNATURE INVALID",b+="<br />",b+="<br />")}return b}
+var KeyManager=function(){this.certificate="MIIBmzCCAQQCCQC32FyQa61S7jANBgkqhkiG9w0BAQUFADASMRAwDgYDVQQDEwdheGVsY2R2MB4XDTEyMDQyODIzNDQzN1oXDTEyMDUyODIzNDQzN1owEjEQMA4GA1UEAxMHYXhlbGNkdjCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA4X0wp9goqxuECxdULcr2IHr9Ih4Iaypg0Wy39URIup8/CLzQmdsh3RYqd55hqonu5VTTpH3iMLx6xZDVJAZ8OJi7pvXcQ2C4Re2kjL2c8SanI0RfDhlS1zJadfr1VhRPmpivcYawJ4aFuOLAi+qHFxtN7lhcGCgpW1OV60oXd58CAwEAATANBgkqhkiG9w0BAQUFAAOBgQDLOrA1fXzSrpftUB5Ro6DigX1Bjkf7F5Bkd69hSVp+jYeJFBBlsILQAfSxUZPQtD+2Yc3iCmSYNyxqu9PcufDRJlnvB7PG29+L3y9lR37tetzUV9eTscJ7rdp8Wt6AzpW32IJ/54yKNfP7S6ZIoIG+LP6EIxq6s8K1MXRt8uBJKw==";this.publicKey=
+"30819F300D06092A864886F70D010101050003818D0030818902818100E17D30A7D828AB1B840B17542DCAF6207AFD221E086B2A60D16CB7F54448BA9F3F08BCD099DB21DD162A779E61AA89EEE554D3A47DE230BC7AC590D524067C3898BBA6F5DC4360B845EDA48CBD9CF126A723445F0E1952D7325A75FAF556144F9A98AF7186B0278685B8E2C08BEA87171B4DEE585C1828295B5395EB4A17779F0203010001";this.privateKey="MIICXQIBAAKBgQDhfTCn2CirG4QLF1QtyvYgev0iHghrKmDRbLf1REi6nz8IvNCZ2yHdFip3nmGqie7lVNOkfeIwvHrFkNUkBnw4mLum9dxDYLhF7aSMvZzxJqcjRF8OGVLXMlp1+vVWFE+amK9xhrAnhoW44sCL6ocXG03uWFwYKClbU5XrShd3nwIDAQABAoGAGkv6T6jC3WmhFZYL6CdCWvlc6gysmKrhjarrLTxgavtFY6R5g2ft5BXAsCCVbUkWxkIFSKqxpVNl0gKZCNGEzPDN6mHJOQI/h0rlxNIHAuGfoAbCzALnqmyZivhJAPGijAyKuU9tczsst5+Kpn+bn7ehzHQuj7iwJonS5WbojqECQQD851K8TpW2GrRizNgG4dx6orZxAaon/Jnl8lS7soXhllQty7qG+oDfzznmdMsiznCqEABzHUUKOVGE9RWPN3aRAkEA5D/w9N55d0ibnChFJlc8cUAoaqH+w+U3oQP2Lb6AZHJpLptN4y4b/uf5d4wYU5/i/gC7SSBH3wFhh9bjRLUDLwJAVOx8vN0Kqt7myfKNbCo19jxjVSlA8TKCn1Oznl/BU1I+rC4oUaEW25DjmX6IpAR8kq7S59ThVSCQPjxqY/A08QJBAIRaF2zGPITQk3r/VumemCvLWiRK/yG0noc9dtibqHOWbCtcXtOm/xDWjq+lis2i3ssOvYrvrv0/HcDY+Dv1An0CQQCLJtMsfSg4kvG/FRY5UMhtMuwo8ovYcMXt4Xv/LWaMhndD67b2UGawQCRqr5ghRTABWdDD/HuuMBjrkPsX0861"};
KeyManager.prototype.verify=function(a,b){var c=this.certificate,d=new X509;d.readCertPEM(c);return d.subjectPublicKeyRSA.verifyString(a,b)};KeyManager.prototype.sign=function(a){var b=this.privateKey,c=new RSAKey;c.readPrivateKeyFromPEMString(b);return c.signString(a,"sha256")};var globalKeyManager=new KeyManager,hexcase=0,b64pad="";function hex_sha256_from_bytes(a){return rstr2hex(binb2rstr(binb_sha256(byteArray2binb(a),8*a.length)))}
function hex_sha256(a){return rstr2hex(rstr_sha256(str2rstr_utf8(a)))}function b64_sha256(a){return rstr2b64(rstr_sha256(str2rstr_utf8(a)))}function any_sha256(a,b){return rstr2any(rstr_sha256(str2rstr_utf8(a)),b)}function hex_hmac_sha256(a,b){return rstr2hex(rstr_hmac_sha256(str2rstr_utf8(a),str2rstr_utf8(b)))}function b64_hmac_sha256(a,b){return rstr2b64(rstr_hmac_sha256(str2rstr_utf8(a),str2rstr_utf8(b)))}
function any_hmac_sha256(a,b,c){return rstr2any(rstr_hmac_sha256(str2rstr_utf8(a),str2rstr_utf8(b)),c)}function sha256_vm_test(){return"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"==hex_sha256("abc").toLowerCase()}function rstr_sha256(a){return binb2rstr(binb_sha256(rstr2binb(a),8*a.length))}
@@ -200,7 +201,17 @@
function _asnhex_getPosArrayOfChildren_AtObj(a,b){var c=[],d=_asnhex_getStartPosOfV_AtObj(a,b);c.push(d);for(var e=_asnhex_getIntOfL_AtObj(a,b),f=d,g=0;;){f=_asnhex_getPosOfNextSibling_AtObj(a,f);if(null==f||f-d>=2*e)break;if(200<=g)break;c.push(f);g++}return c}function _asnhex_getNthChildIndex_AtObj(a,b,c){return _asnhex_getPosArrayOfChildren_AtObj(a,b)[c]}
function _asnhex_getDecendantIndexByNthList(a,b,c){if(0==c.length)return b;var d=c.shift(),b=_asnhex_getPosArrayOfChildren_AtObj(a,b);return _asnhex_getDecendantIndexByNthList(a,b[d],c)}function _asnhex_getDecendantHexTLVByNthList(a,b,c){b=_asnhex_getDecendantIndexByNthList(a,b,c);return _asnhex_getHexOfTLV_AtObj(a,b)}function _asnhex_getDecendantHexVByNthList(a,b,c){b=_asnhex_getDecendantIndexByNthList(a,b,c);return _asnhex_getHexOfV_AtObj(a,b)}function ASN1HEX(){return ASN1HEX}
ASN1HEX.getByteLengthOfL_AtObj=_asnhex_getByteLengthOfL_AtObj;ASN1HEX.getHexOfL_AtObj=_asnhex_getHexOfL_AtObj;ASN1HEX.getIntOfL_AtObj=_asnhex_getIntOfL_AtObj;ASN1HEX.getStartPosOfV_AtObj=_asnhex_getStartPosOfV_AtObj;ASN1HEX.getHexOfV_AtObj=_asnhex_getHexOfV_AtObj;ASN1HEX.getHexOfTLV_AtObj=_asnhex_getHexOfTLV_AtObj;ASN1HEX.getPosOfNextSibling_AtObj=_asnhex_getPosOfNextSibling_AtObj;ASN1HEX.getPosArrayOfChildren_AtObj=_asnhex_getPosArrayOfChildren_AtObj;ASN1HEX.getNthChildIndex_AtObj=_asnhex_getNthChildIndex_AtObj;
-ASN1HEX.getDecendantIndexByNthList=_asnhex_getDecendantIndexByNthList;ASN1HEX.getDecendantHexVByNthList=_asnhex_getDecendantHexVByNthList;ASN1HEX.getDecendantHexTLVByNthList=_asnhex_getDecendantHexTLVByNthList;var dbits,canary=0xdeadbeefcafe,j_lm=15715070==(canary&16777215);function BigInteger(a,b,c){null!=a&&("number"==typeof a?this.fromNumber(a,b,c):null==b&&"string"!=typeof a?this.fromString(a,256):this.fromString(a,b))}function nbi(){return new BigInteger(null)}
+ASN1HEX.getDecendantIndexByNthList=_asnhex_getDecendantIndexByNthList;ASN1HEX.getDecendantHexVByNthList=_asnhex_getDecendantHexVByNthList;ASN1HEX.getDecendantHexTLVByNthList=_asnhex_getDecendantHexTLVByNthList;function _x509_pemToBase64(a){a=a.replace("-----BEGIN CERTIFICATE-----","");a=a.replace("-----END CERTIFICATE-----","");return a=a.replace(/[ \n]+/g,"")}function _x509_pemToHex(a){a=_x509_pemToBase64(a);return b64tohex(a)}
+function _x509_getHexTbsCertificateFromCert(a){return ASN1HEX.getStartPosOfV_AtObj(a,0)}function _x509_getSubjectPublicKeyInfoPosFromCertHex(a){var b=ASN1HEX.getStartPosOfV_AtObj(a,0),b=ASN1HEX.getPosArrayOfChildren_AtObj(a,b);return 1>b.length?-1:"a003020102"==a.substring(b[0],b[0]+10)?6>b.length?-1:b[6]:5>b.length?-1:b[5]}
+function _x509_getSubjectPublicKeyPosFromCertHex(a,b){null==b&&(b=_x509_getSubjectPublicKeyInfoPosFromCertHex(a));if(-1==b)return-1;var c=ASN1HEX.getPosArrayOfChildren_AtObj(a,b);if(2!=c.length)return-1;c=c[1];if("03"!=a.substring(c,c+2))return-1;c=ASN1HEX.getStartPosOfV_AtObj(a,c);return"00"!=a.substring(c,c+2)?-1:c+2}
+function _x509_getPublicKeyHexArrayFromCertHex(a,b){null==b&&(b=_x509_getSubjectPublicKeyPosFromCertHex(a));var c=ASN1HEX.getPosArrayOfChildren_AtObj(a,b);4<LOG&&(console.log("a is now"),console.log(c));if(2>c.length)return[];var d=ASN1HEX.getHexOfV_AtObj(a,c[0]),c=ASN1HEX.getHexOfV_AtObj(a,c[1]);return null!=d&&null!=c?[d,c]:[]}function _x509_getPublicKeyHexArrayFromCertPEM(a){a=_x509_pemToHex(a);return _x509_getPublicKeyHexArrayFromCertHex(a)}
+function _x509_getSerialNumberHex(){return ASN1HEX.getDecendantHexVByNthList(this.hex,0,[0,1])}function _x509_getIssuerHex(){return ASN1HEX.getDecendantHexTLVByNthList(this.hex,0,[0,3])}function _x509_getIssuerString(){return _x509_hex2dn(ASN1HEX.getDecendantHexTLVByNthList(this.hex,0,[0,3]))}function _x509_getSubjectHex(){return ASN1HEX.getDecendantHexTLVByNthList(this.hex,0,[0,5])}function _x509_getSubjectString(){return _x509_hex2dn(ASN1HEX.getDecendantHexTLVByNthList(this.hex,0,[0,5]))}
+function _x509_getNotBefore(){var a=ASN1HEX.getDecendantHexVByNthList(this.hex,0,[0,4,0]),a=a.replace(/(..)/g,"%$1");return a=decodeURIComponent(a)}function _x509_getNotAfter(){var a=ASN1HEX.getDecendantHexVByNthList(this.hex,0,[0,4,1]),a=a.replace(/(..)/g,"%$1");return a=decodeURIComponent(a)}_x509_DN_ATTRHEX={"0603550406":"C","060355040a":"O","060355040b":"OU","0603550403":"CN","0603550405":"SN","0603550408":"ST","0603550407":"L"};
+function _x509_hex2dn(a){for(var b="",c=ASN1HEX.getPosArrayOfChildren_AtObj(a,0),d=0;d<c.length;d++)var e=ASN1HEX.getHexOfTLV_AtObj(a,c[d]),b=b+"/"+_x509_hex2rdn(e);return b}function _x509_hex2rdn(a){var b=ASN1HEX.getDecendantHexTLVByNthList(a,0,[0,0]),c=ASN1HEX.getDecendantHexVByNthList(a,0,[0,1]),a="";try{a=_x509_DN_ATTRHEX[b]}catch(d){a=b}c=c.replace(/(..)/g,"%$1");b=decodeURIComponent(c);return a+"="+b}
+function _x509_readCertPEM(a){var a=_x509_pemToHex(a),b=_x509_getPublicKeyHexArrayFromCertHex(a);4<LOG&&(console.log("HEX VALUE IS "+a),console.log("type of a"+typeof b),console.log("a VALUE IS "),console.log(b),console.log("a[0] VALUE IS "+b[0]),console.log("a[1] VALUE IS "+b[1]));var c=new RSAKey;c.setPublic(b[0],b[1]);this.subjectPublicKeyRSA=c;this.subjectPublicKeyRSA_hN=b[0];this.subjectPublicKeyRSA_hE=b[1];this.hex=a}
+function _x509_readCertHex(a){var a=a.toLowerCase(),b=_x509_getPublicKeyHexArrayFromCertHex(a),c=new RSAKey;c.setPublic(b[0],b[1]);this.subjectPublicKeyRSA=c;this.subjectPublicKeyRSA_hN=b[0];this.subjectPublicKeyRSA_hE=b[1];this.hex=a}function _x509_readCertPEMWithoutRSAInit(a){var a=_x509_pemToHex(a),b=_x509_getPublicKeyHexArrayFromCertHex(a);this.subjectPublicKeyRSA.setPublic(b[0],b[1]);this.subjectPublicKeyRSA_hN=b[0];this.subjectPublicKeyRSA_hE=b[1];this.hex=a}
+function X509(){this.hex=this.subjectPublicKeyRSA_hE=this.subjectPublicKeyRSA_hN=this.subjectPublicKeyRSA=null}X509.prototype.readCertPEM=_x509_readCertPEM;X509.prototype.readCertHex=_x509_readCertHex;X509.prototype.readCertPEMWithoutRSAInit=_x509_readCertPEMWithoutRSAInit;X509.prototype.getSerialNumberHex=_x509_getSerialNumberHex;X509.prototype.getIssuerHex=_x509_getIssuerHex;X509.prototype.getSubjectHex=_x509_getSubjectHex;X509.prototype.getIssuerString=_x509_getIssuerString;
+X509.prototype.getSubjectString=_x509_getSubjectString;X509.prototype.getNotBefore=_x509_getNotBefore;X509.prototype.getNotAfter=_x509_getNotAfter;var dbits,canary=0xdeadbeefcafe,j_lm=15715070==(canary&16777215);function BigInteger(a,b,c){null!=a&&("number"==typeof a?this.fromNumber(a,b,c):null==b&&"string"!=typeof a?this.fromString(a,256):this.fromString(a,b))}function nbi(){return new BigInteger(null)}
function am1(a,b,c,d,e,f){for(;0<=--f;){var g=b*this[a++]+c[d]+e,e=Math.floor(g/67108864);c[d++]=g&67108863}return e}function am2(a,b,c,d,e,f){for(var g=b&32767,b=b>>15;0<=--f;){var h=this[a]&32767,j=this[a++]>>15,l=b*h+j*g,h=g*h+((l&32767)<<15)+c[d]+(e&1073741823),e=(h>>>30)+(l>>>15)+b*j+(e>>>30);c[d++]=h&1073741823}return e}
function am3(a,b,c,d,e,f){for(var g=b&16383,b=b>>14;0<=--f;){var h=this[a]&16383,j=this[a++]>>14,l=b*h+j*g,h=g*h+((l&16383)<<14)+c[d]+e,e=(h>>28)+(l>>14)+b*j;c[d++]=h&268435455}return e}j_lm&&"Microsoft Internet Explorer"==navigator.appName?(BigInteger.prototype.am=am2,dbits=30):j_lm&&"Netscape"!=navigator.appName?(BigInteger.prototype.am=am1,dbits=26):(BigInteger.prototype.am=am3,dbits=28);BigInteger.prototype.DB=dbits;BigInteger.prototype.DM=(1<<dbits)-1;BigInteger.prototype.DV=1<<dbits;
var BI_FP=52;BigInteger.prototype.FV=Math.pow(2,BI_FP);BigInteger.prototype.F1=BI_FP-dbits;BigInteger.prototype.F2=2*dbits-BI_FP;var BI_RM="0123456789abcdefghijklmnopqrstuvwxyz",BI_RC=[],rr,vv;rr=48;for(vv=0;9>=vv;++vv)BI_RC[rr++]=vv;rr=97;for(vv=10;36>vv;++vv)BI_RC[rr++]=vv;rr=65;for(vv=10;36>vv;++vv)BI_RC[rr++]=vv;function int2char(a){return BI_RM.charAt(a)}function intAt(a,b){var c=BI_RC[a.charCodeAt(b)];return null==c?-1:c}