blob: c34c0154f083dd33b6eac59b5cffb5bfbc1dd93c [file] [log] [blame]
Meki Cherkaoui88d59cd2012-05-14 07:34:58 -07001/*! x509-1.1.js (c) 2012 Kenji Urushima | kjur.github.com/jsrsasign/license
2 */
3//
4// x509.js - X509 class to read subject public key from certificate.
5//
6// version: 1.1 (10-May-2012)
7//
8// Copyright (c) 2010-2012 Kenji Urushima (kenji.urushima@gmail.com)
9//
10// This software is licensed under the terms of the MIT License.
11// http://kjur.github.com/jsrsasign/license
12//
13// The above copyright and license notice shall be
14// included in all copies or substantial portions of the Software.
15//
16
17// Depends:
18// base64.js
19// rsa.js
20// asn1hex.js
21
22function _x509_pemToBase64(sCertPEM) {
23 var s = sCertPEM;
24 s = s.replace("-----BEGIN CERTIFICATE-----", "");
25 s = s.replace("-----END CERTIFICATE-----", "");
26 s = s.replace(/[ \n]+/g, "");
27 return s;
28}
29
30function _x509_pemToHex(sCertPEM) {
31 var b64Cert = _x509_pemToBase64(sCertPEM);
32 var hCert = b64tohex(b64Cert);
33 return hCert;
34}
35
36function _x509_getHexTbsCertificateFromCert(hCert) {
37 var pTbsCert = ASN1HEX.getStartPosOfV_AtObj(hCert, 0);
38 return pTbsCert;
39}
40
41// NOTE: privateKeyUsagePeriod field of X509v2 not supported.
42// NOTE: v1 and v3 supported
43function _x509_getSubjectPublicKeyInfoPosFromCertHex(hCert) {
44 var pTbsCert = ASN1HEX.getStartPosOfV_AtObj(hCert, 0);
45 var a = ASN1HEX.getPosArrayOfChildren_AtObj(hCert, pTbsCert);
46 if (a.length < 1) return -1;
47 if (hCert.substring(a[0], a[0] + 10) == "a003020102") { // v3
48 if (a.length < 6) return -1;
49 return a[6];
50 } else {
51 if (a.length < 5) return -1;
52 return a[5];
53 }
54}
55
56// NOTE: Without BITSTRING encapsulation.
57function _x509_getSubjectPublicKeyPosFromCertHex(hCert) {
58 var pInfo = _x509_getSubjectPublicKeyInfoPosFromCertHex(hCert);
59 if (pInfo == -1) return -1;
60 var a = ASN1HEX.getPosArrayOfChildren_AtObj(hCert, pInfo);
61
62 if (a.length != 2) return -1;
63 var pBitString = a[1];
64 if (hCert.substring(pBitString, pBitString + 2) != '03') return -1;
65 var pBitStringV = ASN1HEX.getStartPosOfV_AtObj(hCert, pBitString);
66
67 if (hCert.substring(pBitStringV, pBitStringV + 2) != '00') return -1;
68 return pBitStringV + 2;
69}
70
71function _x509_getPublicKeyHexArrayFromCertHex(hCert) {
72 var p = _x509_getSubjectPublicKeyPosFromCertHex(hCert);
73 var a = ASN1HEX.getPosArrayOfChildren_AtObj(hCert, p);
74 //var a = ASN1HEX.getPosArrayOfChildren_AtObj(hCert, a[3]);
75 if(LOG>4){
76 console.log('a is now');
77 console.log(a);
78 }
79
80 //if (a.length != 2) return [];
81 if (a.length < 2) return [];
82
83 var hN = ASN1HEX.getHexOfV_AtObj(hCert, a[0]);
84 var hE = ASN1HEX.getHexOfV_AtObj(hCert, a[1]);
85 if (hN != null && hE != null) {
86 return [hN, hE];
87 } else {
88 return [];
89 }
90}
91
92function _x509_getPublicKeyHexArrayFromCertPEM(sCertPEM) {
93 var hCert = _x509_pemToHex(sCertPEM);
94 var a = _x509_getPublicKeyHexArrayFromCertHex(hCert);
95 return a;
96}
97
98// ===== get basic fields from hex =====================================
99/**
100 * get hexadecimal string of serialNumber field of certificate.<br/>
101 * @name getSerialNumberHex
102 * @memberOf X509#
103 * @function
104 */
105function _x509_getSerialNumberHex() {
106 return ASN1HEX.getDecendantHexVByNthList(this.hex, 0, [0, 1]);
107}
108
109/**
110 * get hexadecimal string of issuer field of certificate.<br/>
111 * @name getIssuerHex
112 * @memberOf X509#
113 * @function
114 */
115function _x509_getIssuerHex() {
116 return ASN1HEX.getDecendantHexTLVByNthList(this.hex, 0, [0, 3]);
117}
118
119/**
120 * get string of issuer field of certificate.<br/>
121 * @name getIssuerString
122 * @memberOf X509#
123 * @function
124 */
125function _x509_getIssuerString() {
126 return _x509_hex2dn(ASN1HEX.getDecendantHexTLVByNthList(this.hex, 0, [0, 3]));
127}
128
129/**
130 * get hexadecimal string of subject field of certificate.<br/>
131 * @name getSubjectHex
132 * @memberOf X509#
133 * @function
134 */
135function _x509_getSubjectHex() {
136 return ASN1HEX.getDecendantHexTLVByNthList(this.hex, 0, [0, 5]);
137}
138
139/**
140 * get string of subject field of certificate.<br/>
141 * @name getSubjectString
142 * @memberOf X509#
143 * @function
144 */
145function _x509_getSubjectString() {
146 return _x509_hex2dn(ASN1HEX.getDecendantHexTLVByNthList(this.hex, 0, [0, 5]));
147}
148
149/**
150 * get notBefore field string of certificate.<br/>
151 * @name getNotBefore
152 * @memberOf X509#
153 * @function
154 */
155function _x509_getNotBefore() {
156 var s = ASN1HEX.getDecendantHexVByNthList(this.hex, 0, [0, 4, 0]);
157 s = s.replace(/(..)/g, "%$1");
158 s = decodeURIComponent(s);
159 return s;
160}
161
162/**
163 * get notAfter field string of certificate.<br/>
164 * @name getNotAfter
165 * @memberOf X509#
166 * @function
167 */
168function _x509_getNotAfter() {
169 var s = ASN1HEX.getDecendantHexVByNthList(this.hex, 0, [0, 4, 1]);
170 s = s.replace(/(..)/g, "%$1");
171 s = decodeURIComponent(s);
172 return s;
173}
174
175// ===== read certificate =====================================
176
177_x509_DN_ATTRHEX = {
178 "0603550406": "C",
179 "060355040a": "O",
180 "060355040b": "OU",
181 "0603550403": "CN",
182 "0603550405": "SN",
183 "0603550408": "ST",
184 "0603550407": "L" };
185
186function _x509_hex2dn(hDN) {
187 var s = "";
188 var a = ASN1HEX.getPosArrayOfChildren_AtObj(hDN, 0);
189 for (var i = 0; i < a.length; i++) {
190 var hRDN = ASN1HEX.getHexOfTLV_AtObj(hDN, a[i]);
191 s = s + "/" + _x509_hex2rdn(hRDN);
192 }
193 return s;
194}
195
196function _x509_hex2rdn(hRDN) {
197 var hType = ASN1HEX.getDecendantHexTLVByNthList(hRDN, 0, [0, 0]);
198 var hValue = ASN1HEX.getDecendantHexVByNthList(hRDN, 0, [0, 1]);
199 var type = "";
200 try { type = _x509_DN_ATTRHEX[hType]; } catch (ex) { type = hType; }
201 hValue = hValue.replace(/(..)/g, "%$1");
202 var value = decodeURIComponent(hValue);
203 return type + "=" + value;
204}
205
206// ===== read certificate =====================================
207
208
209/**
210 * read PEM formatted X.509 certificate from string.<br/>
211 * @name readCertPEM
212 * @memberOf X509#
213 * @function
214 * @param {String} sCertPEM string for PEM formatted X.509 certificate
215 */
216function _x509_readCertPEM(sCertPEM) {
217 var hCert = _x509_pemToHex(sCertPEM);
218 var a = _x509_getPublicKeyHexArrayFromCertHex(hCert);
219 if(LOG>4){
220 console.log('HEX VALUE IS ' + hCert);
221 console.log('type of a' + typeof a);
222 console.log('a VALUE IS ');
223 console.log(a);
224 console.log('a[0] VALUE IS ' + a[0]);
225 console.log('a[1] VALUE IS ' + a[1]);
226 }
227 var rsa = new RSAKey();
228 rsa.setPublic(a[0], a[1]);
229 this.subjectPublicKeyRSA = rsa;
230 this.subjectPublicKeyRSA_hN = a[0];
231 this.subjectPublicKeyRSA_hE = a[1];
232 this.hex = hCert;
233}
234
Jeff Thompsond3d45c82012-12-29 16:15:49 -0800235/**
236 * read hex formatted X.509 certificate from string.
237 * @name readCertHex
238 * @memberOf X509#
239 * @function
240 * @param {String} hCert string for hex formatted X.509 certificate
241 */
242function _x509_readCertHex(hCert) {
243 hCert = hCert.toLowerCase();
244 var a = _x509_getPublicKeyHexArrayFromCertHex(hCert);
245 var rsa = new RSAKey();
246 rsa.setPublic(a[0], a[1]);
247 this.subjectPublicKeyRSA = rsa;
248 this.subjectPublicKeyRSA_hN = a[0];
249 this.subjectPublicKeyRSA_hE = a[1];
250 this.hex = hCert;
251}
252
Meki Cherkaoui88d59cd2012-05-14 07:34:58 -0700253function _x509_readCertPEMWithoutRSAInit(sCertPEM) {
254 var hCert = _x509_pemToHex(sCertPEM);
255 var a = _x509_getPublicKeyHexArrayFromCertHex(hCert);
256 this.subjectPublicKeyRSA.setPublic(a[0], a[1]);
257 this.subjectPublicKeyRSA_hN = a[0];
258 this.subjectPublicKeyRSA_hE = a[1];
259 this.hex = hCert;
260}
261
262/**
263 * X.509 certificate class.<br/>
264 * @class X.509 certificate class
265 * @property {RSAKey} subjectPublicKeyRSA Tom Wu's RSAKey object
266 * @property {String} subjectPublicKeyRSA_hN hexadecimal string for modulus of RSA public key
267 * @property {String} subjectPublicKeyRSA_hE hexadecimal string for public exponent of RSA public key
268 * @property {String} hex hexacedimal string for X.509 certificate.
269 * @author Kenji Urushima
270 * @version 1.0.1 (08 May 2012)
271 * @see <a href="http://kjur.github.com/jsrsasigns/">'jwrsasign'(RSA Sign JavaScript Library) home page http://kjur.github.com/jsrsasign/</a>
272 */
273function X509() {
274 this.subjectPublicKeyRSA = null;
275 this.subjectPublicKeyRSA_hN = null;
276 this.subjectPublicKeyRSA_hE = null;
277 this.hex = null;
278}
279
280X509.prototype.readCertPEM = _x509_readCertPEM;
Jeff Thompsond3d45c82012-12-29 16:15:49 -0800281X509.prototype.readCertHex = _x509_readCertHex;
Meki Cherkaoui88d59cd2012-05-14 07:34:58 -0700282X509.prototype.readCertPEMWithoutRSAInit = _x509_readCertPEMWithoutRSAInit;
283X509.prototype.getSerialNumberHex = _x509_getSerialNumberHex;
284X509.prototype.getIssuerHex = _x509_getIssuerHex;
285X509.prototype.getSubjectHex = _x509_getSubjectHex;
286X509.prototype.getIssuerString = _x509_getIssuerString;
287X509.prototype.getSubjectString = _x509_getSubjectString;
288X509.prototype.getNotBefore = _x509_getNotBefore;
289X509.prototype.getNotAfter = _x509_getNotAfter;
290