mirror of
https://github.com/moparisthebest/mailiverse
synced 2024-12-04 22:02:15 -05:00
268 lines
7.9 KiB
JavaScript
268 lines
7.9 KiB
JavaScript
|
/*! 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.<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);
|
||
|
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.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;
|
||
|
|