/*! 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_NO(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]; } } // tjp function _x509_getSubjectPublicKeyPosFromCertHex (hCert) { var identifier = ASN1HEX.getStartPosOfV_AtObj(hCert, 0); var bitstring = ASN1HEX.getPosOfNextSibling_AtObj(hCert, identifier); var sequence = ASN1HEX.getStartPosOfV_AtObj(hCert, bitstring); if (hCert.substring(sequence, sequence + 2) != '00') return -1; return sequence + 2; } // end tjp // NOTE: Without BITSTRING encapsulation. function _x509_getSubjectPublicKeyPosFromCertHex_NO(hCert) { var 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; } function _x509_getPublicKeyHexArrayFromCertHex(hCert) { var p = _x509_getSubjectPublicKeyPosFromCertHex(hCert); var a = ASN1HEX.getPosArrayOfChildren_AtObj(hCert, p); 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.
* @name getSerialNumberHex * @memberOf X509# * @function */ function _x509_getSerialNumberHex() { return ASN1HEX.getDecendantHexVByNthList(this.hex, 0, [0, 1]); } /** * get hexadecimal string of issuer field of certificate.
* @name getIssuerHex * @memberOf X509# * @function */ function _x509_getIssuerHex() { return ASN1HEX.getDecendantHexTLVByNthList(this.hex, 0, [0, 3]); } /** * get string of issuer field of certificate.
* @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.
* @name getSubjectHex * @memberOf X509# * @function */ function _x509_getSubjectHex() { return ASN1HEX.getDecendantHexTLVByNthList(this.hex, 0, [0, 5]); } /** * get string of subject field of certificate.
* @name getSubjectString * @memberOf X509# * @function */ function _x509_getSubjectString() { return _x509_hex2dn(ASN1HEX.getDecendantHexTLVByNthList(this.hex, 0, [0, 5])); } /** * get notBefore field string of certificate.
* @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.
* @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.
* @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); 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.
* @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 'jwrsasign'(RSA Sign JavaScript Library) home page http://kjur.github.com/jsrsasign/ */ function X509() { this.subjectPublicKeyRSA = null; this.subjectPublicKeyRSA_hN = null; this.subjectPublicKeyRSA_hE = null; this.hex = null; } X509.prototype.readCertPEM = _x509_readCertPEM; 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;