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