| /*! 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; |
| |