Merge branch 'master' into sigverify
Conflicts:
js/tools/build/ndn-js.js
diff --git a/js/tools/build/ndn-js-uncomp.js b/js/tools/build/ndn-js-uncomp.js
index 9ce8d3e..2f6f4f8 100644
--- a/js/tools/build/ndn-js-uncomp.js
+++ b/js/tools/build/ndn-js-uncomp.js
@@ -199,7 +199,7 @@
interest.interestLifetime = template.interestLifetime;
}
else
- interest.interestLifetime = 4.0; // default interest timeout value in seconds.
+ interest.interestLifetime = 4000; // default interest timeout value in milliseconds.
if (this.host == null || this.port == null) {
if (this.getHostAndPort == null)
@@ -239,7 +239,7 @@
// Fetch the ccndId.
var interest = new Interest(new Name(NDN.ccndIdFetcher));
- interest.interestLifetime = 4.0; // seconds
+ interest.interestLifetime = 4000; // milliseconds
var thisNDN = this;
var timerID = setTimeout(function() {
@@ -457,10 +457,6 @@
//console.log("raise encapsulated closure");
this.closure.upcall(flag, new UpcallInfo(ndn, null, 0, this.contentObject));
-
- // Store key in cache
- var keyEntry = new KeyStoreEntry(keylocator.keyName, keyHex, rsakey);
- NDN.KeyStore.push(keyEntry);
}
};
@@ -489,6 +485,10 @@
var flag = (verified == true) ? Closure.UPCALL_CONTENT : Closure.UPCALL_CONTENT_BAD;
currentClosure.upcall(flag, new UpcallInfo(ndn, null, 0, co));
+
+ // Store key in cache
+ var keyEntry = new KeyStoreEntry(keylocator.keyName, keyHex, rsakey);
+ NDN.KeyStore.push(keyEntry);
} else {
console.log("Fetch key according to keylocator");
@@ -564,7 +564,7 @@
// Fetch ccndid now
var interest = new Interest(new Name(NDN.ccndIdFetcher));
- interest.interestLifetime = 4.0; // seconds
+ interest.interestLifetime = 4000; // milliseconds
var subarray = encodeToBinaryInterest(interest);
var bytes = new Uint8Array(subarray.length);
@@ -616,7 +616,7 @@
//console.log(NDN.PITTable);
// Raise closure callback
closure.upcall(Closure.UPCALL_INTEREST_TIMED_OUT, new UpcallInfo(ndn, interest, 0, null));
- }, interest.interestLifetime * 1000); // convert interestLifetime from seconds to ms.
+ }, interest.interestLifetime); // interestLifetime is in milliseconds.
//console.log(closure.timerID);
}
else
@@ -1814,6 +1814,7 @@
* This class represents Interest Objects
*/
+// _interestLifetime is in milliseconds.
var Interest = function Interest(_name,_faceInstance,_minSuffixComponents,_maxSuffixComponents,_publisherPublicKeyDigest, _exclude, _childSelector,_answerOriginKind,_scope,_interestLifetime,_nonce){
this.name = _name;
@@ -1826,7 +1827,7 @@
this.childSelector = _childSelector;
this.answerOriginKind = _answerOriginKind;
this.scope = _scope;
- this.interestLifetime = _interestLifetime; // number of seconds
+ this.interestLifetime = _interestLifetime; // milli seconds
this.nonce = _nonce;
};
@@ -1875,7 +1876,7 @@
this.scope = decoder.readIntegerElement(CCNProtocolDTags.Scope);
if (decoder.peekStartElement(CCNProtocolDTags.InterestLifetime))
- this.interestLifetime = DataUtils.bigEndianToUnsignedInt
+ this.interestLifetime = 1000.0 * DataUtils.bigEndianToUnsignedInt
(decoder.readBinaryElement(CCNProtocolDTags.InterestLifetime)) / 4096;
if (decoder.peekStartElement(CCNProtocolDTags.Nonce))
@@ -1914,7 +1915,7 @@
if (null != this.interestLifetime)
encoder.writeElement(CCNProtocolDTags.InterestLifetime,
- DataUtils.nonNegativeIntToBigEndian(this.interestLifetime * 4096));
+ DataUtils.nonNegativeIntToBigEndian((this.interestLifetime / 1000.0) * 4096));
if (null != this.nonce)
encoder.writeElement(CCNProtocolDTags.Nonce, this.nonce);
@@ -2651,6 +2652,60 @@
ForwardingEntry.prototype.getElementLabel = function() { return CCNProtocolDTags.ForwardingEntry; }
/**
+ * @author: Jeff Thompson
+ * See COPYING for copyright and distribution information.
+ * Encapsulate an Uint8Array and support dynamic reallocation.
+ */
+
+/*
+ * Create a DynamicUint8Array where this.array is a Uint8Array of size length.
+ * If length is not supplied, use a default initial length.
+ * The methods will update this.length.
+ * To access the array, use this.array or call subarray.
+ */
+var DynamicUint8Array = function DynamicUint8Array(length) {
+ if (!length)
+ length = 16;
+
+ this.array = new Uint8Array(length);
+ this.length = length;
+};
+
+/*
+ * Ensure that this.array has the length, reallocate and copy if necessary.
+ * Update this.length which may be greater than length.
+ */
+DynamicUint8Array.prototype.ensureLength = function(length) {
+ if (this.array.length >= length)
+ return;
+
+ // See if double is enough.
+ var newLength = this.array.length * 2;
+ if (length > newLength)
+ // The needed length is much greater, so use it.
+ newLength = length;
+
+ var newArray = new Uint8Array(newLength);
+ newArray.set(this.array);
+ this.array = newArray;
+ this.length = newLength;
+};
+
+/*
+ * Call this.array.set(value, offset), reallocating if necessary.
+ */
+DynamicUint8Array.prototype.set = function(value, offset) {
+ this.ensureLength(value.length + offset);
+ this.array.set(value, offset);
+};
+
+/*
+ * Return this.array.subarray(begin, end);
+ */
+DynamicUint8Array.prototype.subarray = function(begin, end) {
+ return this.array.subarray(begin, end);
+}
+/**
* This class is used to encode ccnb binary elements (blob, type/value pairs).
*
* @author: Meki Cheraoui
@@ -2693,7 +2748,7 @@
var BinaryXMLEncoder = function BinaryXMLEncoder(){
- this.ostream = new Uint8Array(10000);
+ this.ostream = new DynamicUint8Array(100);
this.offset =0;
this.CODEC_NAME = "Binary";
};
@@ -2736,7 +2791,8 @@
BinaryXMLEncoder.prototype.writeEndElement = function() {
- this.ostream[this.offset] = XML_CLOSE;
+ this.ostream.ensureLength(this.offset + 1);
+ this.ostream.array[this.offset] = XML_CLOSE;
this.offset += 1;
}
@@ -2856,27 +2912,22 @@
// Encode backwards. Calculate how many bytes we need:
var numEncodingBytes = this.numEncodingBytes(val);
-
- if ((this.offset + numEncodingBytes) > this.ostream.length) {
- throw new Error("Buffer space of " + (this.ostream.length - this.offset) +
- " bytes insufficient to hold " +
- numEncodingBytes + " of encoded type and value.");
- }
+ this.ostream.ensureLength(this.offset + numEncodingBytes);
// Bottom 4 bits of val go in last byte with tag.
- this.ostream[this.offset + numEncodingBytes - 1] =
+ this.ostream.array[this.offset + numEncodingBytes - 1] =
//(byte)
(BYTE_MASK &
(((XML_TT_MASK & type) |
((XML_TT_VAL_MASK & val) << XML_TT_BITS))) |
XML_TT_NO_MORE); // set top bit for last byte
- val = val >>> XML_TT_VAL_BITS;;
+ val = val >>> XML_TT_VAL_BITS;
// Rest of val goes into preceding bytes, 7 bits per byte, top bit
// is "more" flag.
var i = this.offset + numEncodingBytes - 2;
while ((0 != val) && (i >= this.offset)) {
- this.ostream[i] = //(byte)
+ this.ostream.array[i] = //(byte)
(BYTE_MASK & (val & XML_REG_VAL_MASK)); // leave top bit unset
val = val >>> XML_REG_VAL_BITS;
--i;
@@ -2918,7 +2969,7 @@
if(LOG>3) console.log(strBytes);
- this.writeString(strBytes,this.offset);
+ this.writeString(strBytes);
this.offset+= strBytes.length;
};
@@ -2945,7 +2996,7 @@
this.encodeTypeAndVal(XML_BLOB, length);
- this.writeBlobArray(blob, this.offset);
+ this.writeBlobArray(blob);
this.offset += length;
};
@@ -2999,20 +3050,18 @@
this.writeElement(tag, binarydate);
};
-BinaryXMLEncoder.prototype.writeString = function(
- //String
- input,
- //CCNTime
- offset) {
+// This does not update this.offset.
+BinaryXMLEncoder.prototype.writeString = function(input) {
if(typeof input === 'string'){
//console.log('went here');
if(LOG>4) console.log('GOING TO WRITE A STRING');
if(LOG>4) console.log(input);
- for (i = 0; i < input.length; i++) {
+ this.ostream.ensureLength(this.offset + input.length);
+ for (var i = 0; i < input.length; i++) {
if(LOG>4) console.log('input.charCodeAt(i)=' + input.charCodeAt(i));
- this.ostream[this.offset+i] = (input.charCodeAt(i));
+ this.ostream.array[this.offset + i] = (input.charCodeAt(i));
}
}
else{
@@ -3031,15 +3080,10 @@
BinaryXMLEncoder.prototype.writeBlobArray = function(
//Uint8Array
- blob,
- //int
- offset) {
+ blob) {
if(LOG>4) console.log('GOING TO WRITE A BLOB');
- /*for (var i = 0; i < Blob.length; i++) {
- this.ostream[this.offset+i] = Blob[i];
- }*/
this.ostream.set(blob, this.offset);
};
@@ -3792,7 +3836,7 @@
this.state = BinaryXMLStructureDecoder.READ_HEADER_OR_CLOSE;
this.headerLength = 0;
this.useHeaderBuffer = false;
- this.headerBuffer = new Uint8Array(5);
+ this.headerBuffer = new DynamicUint8Array(5);
this.nBytesToRead = 0;
};
@@ -3846,7 +3890,7 @@
// We can't get all of the header bytes from this input. Save in headerBuffer.
this.useHeaderBuffer = true;
var nNewBytes = this.headerLength - startingHeaderLength;
- this.setHeaderBuffer
+ this.headerBuffer.set
(input.subarray(this.offset - nNewBytes, nNewBytes), startingHeaderLength);
return false;
@@ -3862,10 +3906,10 @@
if (this.useHeaderBuffer) {
// Copy the remaining bytes into headerBuffer.
nNewBytes = this.headerLength - startingHeaderLength;
- this.setHeaderBuffer
+ this.headerBuffer.set
(input.subarray(this.offset - nNewBytes, nNewBytes), startingHeaderLength);
- typeAndVal = new BinaryXMLDecoder(this.headerBuffer).decodeTypeAndVal();
+ typeAndVal = new BinaryXMLDecoder(this.headerBuffer.array).decodeTypeAndVal();
}
else {
// We didn't have to use the headerBuffer.
@@ -3942,20 +3986,7 @@
offset) {
this.offset = offset;
}
-
-/*
- * Set call this.headerBuffer.set(subarray, bufferOffset), an reallocate the headerBuffer if needed.
- */
-BinaryXMLStructureDecoder.prototype.setHeaderBuffer = function(subarray, bufferOffset) {
- var size = subarray.length + bufferOffset;
- if (size > this.headerBuffer.length) {
- // Reallocate the buffer.
- var newHeaderBuffer = new Uint8Array(size + 5);
- newHeaderBuffer.set(this.headerBuffer);
- this.headerBuffer = newHeaderBuffer;
- }
- this.headerBuffer.set(subarray, bufferOffset);
-}/**
+/**
* This class contains utilities to help parse the data
* author: Meki Cheraoui, Jeff Thompson
* See COPYING for copyright and distribution information.
@@ -4512,6 +4543,17 @@
}
+/*
+ * Decode the Uint8Array which holds SubjectPublicKeyInfo and return an RSAKey.
+ */
+function decodeSubjectPublicKeyInfo(array) {
+ var hex = DataUtils.toHex(array).toLowerCase();
+ var a = _x509_getPublicKeyHexArrayFromCertHex(hex, _x509_getSubjectPublicKeyPosFromCertHex(hex, 0));
+ var rsaKey = new RSAKey();
+ rsaKey.setPublic(a[0], a[1]);
+ return rsaKey;
+}
+
/* Return a user friendly HTML string with the contents of co.
This also outputs to console.log.
*/
@@ -4571,37 +4613,21 @@
output+= "<br />";
}
if(co.signedInfo!=null && co.signedInfo.locator!=null && co.signedInfo.locator.certificate!=null){
- var tmp = DataUtils.toString(co.signedInfo.locator.certificate);
- var publickey = rstr2b64(tmp);
- var publickeyHex = DataUtils.toHex(co.signedInfo.locator.certificate).toLowerCase();
- var publickeyString = DataUtils.toString(co.signedInfo.locator.certificate);
+ var certificateHex = DataUtils.toHex(co.signedInfo.locator.certificate).toLowerCase();
var signature = DataUtils.toHex(co.signature.signature).toLowerCase();
var input = DataUtils.toString(co.rawSignatureData);
- output += "DER Certificate: "+publickey ;
+ output += "Hex Certificate: "+ certificateHex ;
output+= "<br />";
output+= "<br />";
- if(LOG>2) console.log(" ContentName + SignedInfo + Content = "+input);
-
- if(LOG>2) console.log("HEX OF ContentName + SignedInfo + Content = ");
- if(LOG>2) console.log(DataUtils.stringtoBase64(input));
-
- if(LOG>2) console.log(" PublicKey = "+publickey );
- if(LOG>2) console.log(" PublicKeyHex = "+publickeyHex );
- if(LOG>2) console.log(" PublicKeyString = "+publickeyString );
-
- if(LOG>2) console.log(" Signature is");
- if(LOG>2) console.log( signature );
- //if(LOG>2) console.log(" Signature NOW IS" );
- //if(LOG>2) console.log(co.signature.signature);
-
var x509 = new X509();
- x509.readCertPEM(publickey);
+ x509.readCertHex(certificateHex);
+ output += "Public key (hex) modulus: " + x509.subjectPublicKeyRSA.n.toString(16) + "<br/>";
+ output += "exponent: " + x509.subjectPublicKeyRSA.e.toString(16) + "<br/>";
+ output += "<br/>";
- //x509.readCertPEMWithoutRSAInit(publickey);
-
var result = x509.subjectPublicKeyRSA.verifyByteArray(co.rawSignatureData, signature);
if(LOG>2) console.log('result is '+result);
@@ -4614,35 +4640,10 @@
if(LOG>2) console.log('EXPONENT e after is ');
if(LOG>2) console.log(e);
- /*var rsakey = new RSAKey();
-
- var kp = publickeyHex.slice(56,314);
-
- output += "PUBLISHER KEY(hex): "+kp ;
-
- output+= "<br />";
- output+= "<br />";
-
- console.log('kp is '+kp);
-
- var exp = publickeyHex.slice(318,324);
-
- console.log('kp size is '+kp.length );
- output += "exponent: "+exp ;
-
- output+= "<br />";
- output+= "<br />";
-
- console.log('exp is '+exp);
-
- rsakey.setPublic(kp,exp);
-
- var result = rsakey.verifyString(input, signature);*/
-
if(result)
- output += 'SIGNATURE VALID';
+ output += 'SIGNATURE VALID';
else
- output += 'SIGNATURE INVALID';
+ output += 'SIGNATURE INVALID';
//output += "VALID: "+ toHex(co.signedInfo.locator.publicKey);
@@ -4652,19 +4653,17 @@
//if(LOG>4) console.log('str'[1]);
}
if(co.signedInfo!=null && co.signedInfo.locator!=null && co.signedInfo.locator.publicKey!=null){
- var publickey = rstr2b64(DataUtils.toString(co.signedInfo.locator.publicKey));
var publickeyHex = DataUtils.toHex(co.signedInfo.locator.publicKey).toLowerCase();
var publickeyString = DataUtils.toString(co.signedInfo.locator.publicKey);
var signature = DataUtils.toHex(co.signature.signature).toLowerCase();
var input = DataUtils.toString(co.rawSignatureData);
- output += "DER Certificate: "+publickey ;
+ output += "Public key: " + publickeyHex;
output+= "<br />";
output+= "<br />";
if(LOG>2) console.log(" ContentName + SignedInfo + Content = "+input);
- if(LOG>2) console.log(" PublicKey = "+publickey );
if(LOG>2) console.log(" PublicKeyHex = "+publickeyHex );
if(LOG>2) console.log(" PublicKeyString = "+publickeyString );
@@ -4673,53 +4672,13 @@
if(LOG>2) console.log(" Signature NOW IS" );
if(LOG>2) console.log(co.signature.signature);
-
- /*var x509 = new X509();
-
- x509.readCertPEM(publickey);
-
-
- //x509.readCertPEMWithoutRSAInit(publickey);
+
+ var rsakey = decodeSubjectPublicKeyInfo(co.signedInfo.locator.publicKey);
- var result = x509.subjectPublicKeyRSA.verifyString(input, signature);*/
- //console.log('result is '+result);
-
- var kp = publickeyHex.slice(56,314);
-
- output += "PUBLISHER KEY(hex): "+kp ;
-
- output+= "<br />";
- output+= "<br />";
-
- if(LOG>2) console.log('PUBLIC KEY IN HEX is ');
- if(LOG>2) console.log(kp);
-
- var exp = publickeyHex.slice(318,324);
-
- if(LOG>2) console.log('kp size is '+kp.length );
- output += "exponent: "+exp ;
-
- output+= "<br />";
- output+= "<br />";
-
- if(LOG>2) console.log('EXPONENT is ');
- if(LOG>2) console.log(exp);
-
- /*var c1 = hex_sha256(input);
- var c2 = signature;
-
- if(LOG>4)console.log('input is ');
- if(LOG>4)console.log(input);
- if(LOG>4)console.log('C1 is ');
- if(LOG>4)console.log(c1);
- if(LOG>4)console.log('C2 is ');
- if(LOG>4)console.log(c2);
- var result = c1 == c2;*/
-
- var rsakey = new RSAKey();
-
- rsakey.setPublic(kp,exp);
-
+ output += "Public key (hex) modulus: " + rsakey.n.toString(16) + "<br/>";
+ output += "exponent: " + rsakey.e.toString(16) + "<br/>";
+ output += "<br/>";
+
var result = rsakey.verifyByteArray(co.rawSignatureData,signature);
// var result = rsakey.verifyString(input, signature);
@@ -4745,6 +4704,8 @@
return output;
}
+
+
/**
* @author: Meki Cheraoui
* See COPYING for copyright and distribution information.
@@ -6379,6 +6340,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.