blob: 262e5d2179675bb8bb18f7378ce5080392bd637e [file] [log] [blame]
Alexander Afanasyev181a8b92013-02-28 13:28:53 -08001/*! 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.
57// If pInfo is supplied, it is the position in hCert of the SubjectPublicKeyInfo.
58function _x509_getSubjectPublicKeyPosFromCertHex(hCert, pInfo) {
59 if (pInfo == null)
60 pInfo = _x509_getSubjectPublicKeyInfoPosFromCertHex(hCert);
61 if (pInfo == -1) return -1;
62 var a = ASN1HEX.getPosArrayOfChildren_AtObj(hCert, pInfo);
63
64 if (a.length != 2) return -1;
65 var pBitString = a[1];
66 if (hCert.substring(pBitString, pBitString + 2) != '03') return -1;
67 var pBitStringV = ASN1HEX.getStartPosOfV_AtObj(hCert, pBitString);
68
69 if (hCert.substring(pBitStringV, pBitStringV + 2) != '00') return -1;
70 return pBitStringV + 2;
71}
72
73// If p is supplied, it is the public key position in hCert.
74function _x509_getPublicKeyHexArrayFromCertHex(hCert, p) {
75 if (p == null)
76 p = _x509_getSubjectPublicKeyPosFromCertHex(hCert);
77 var a = ASN1HEX.getPosArrayOfChildren_AtObj(hCert, p);
78 //var a = ASN1HEX.getPosArrayOfChildren_AtObj(hCert, a[3]);
79 if(LOG>4){
80 console.log('a is now');
81 console.log(a);
82 }
83
84 //if (a.length != 2) return [];
85 if (a.length < 2) return [];
86
87 var hN = ASN1HEX.getHexOfV_AtObj(hCert, a[0]);
88 var hE = ASN1HEX.getHexOfV_AtObj(hCert, a[1]);
89 if (hN != null && hE != null) {
90 return [hN, hE];
91 } else {
92 return [];
93 }
94}
95
96function _x509_getPublicKeyHexArrayFromCertPEM(sCertPEM) {
97 var hCert = _x509_pemToHex(sCertPEM);
98 var a = _x509_getPublicKeyHexArrayFromCertHex(hCert);
99 return a;
100}
101
102// ===== get basic fields from hex =====================================
103/**
104 * get hexadecimal string of serialNumber field of certificate.<br/>
105 * @name getSerialNumberHex
106 * @memberOf X509#
107 * @function
108 */
109function _x509_getSerialNumberHex() {
110 return ASN1HEX.getDecendantHexVByNthList(this.hex, 0, [0, 1]);
111}
112
113/**
114 * get hexadecimal string of issuer field of certificate.<br/>
115 * @name getIssuerHex
116 * @memberOf X509#
117 * @function
118 */
119function _x509_getIssuerHex() {
120 return ASN1HEX.getDecendantHexTLVByNthList(this.hex, 0, [0, 3]);
121}
122
123/**
124 * get string of issuer field of certificate.<br/>
125 * @name getIssuerString
126 * @memberOf X509#
127 * @function
128 */
129function _x509_getIssuerString() {
130 return _x509_hex2dn(ASN1HEX.getDecendantHexTLVByNthList(this.hex, 0, [0, 3]));
131}
132
133/**
134 * get hexadecimal string of subject field of certificate.<br/>
135 * @name getSubjectHex
136 * @memberOf X509#
137 * @function
138 */
139function _x509_getSubjectHex() {
140 return ASN1HEX.getDecendantHexTLVByNthList(this.hex, 0, [0, 5]);
141}
142
143/**
144 * get string of subject field of certificate.<br/>
145 * @name getSubjectString
146 * @memberOf X509#
147 * @function
148 */
149function _x509_getSubjectString() {
150 return _x509_hex2dn(ASN1HEX.getDecendantHexTLVByNthList(this.hex, 0, [0, 5]));
151}
152
153/**
154 * get notBefore field string of certificate.<br/>
155 * @name getNotBefore
156 * @memberOf X509#
157 * @function
158 */
159function _x509_getNotBefore() {
160 var s = ASN1HEX.getDecendantHexVByNthList(this.hex, 0, [0, 4, 0]);
161 s = s.replace(/(..)/g, "%$1");
162 s = decodeURIComponent(s);
163 return s;
164}
165
166/**
167 * get notAfter field string of certificate.<br/>
168 * @name getNotAfter
169 * @memberOf X509#
170 * @function
171 */
172function _x509_getNotAfter() {
173 var s = ASN1HEX.getDecendantHexVByNthList(this.hex, 0, [0, 4, 1]);
174 s = s.replace(/(..)/g, "%$1");
175 s = decodeURIComponent(s);
176 return s;
177}
178
179// ===== read certificate =====================================
180
181_x509_DN_ATTRHEX = {
182 "0603550406": "C",
183 "060355040a": "O",
184 "060355040b": "OU",
185 "0603550403": "CN",
186 "0603550405": "SN",
187 "0603550408": "ST",
188 "0603550407": "L" };
189
190function _x509_hex2dn(hDN) {
191 var s = "";
192 var a = ASN1HEX.getPosArrayOfChildren_AtObj(hDN, 0);
193 for (var i = 0; i < a.length; i++) {
194 var hRDN = ASN1HEX.getHexOfTLV_AtObj(hDN, a[i]);
195 s = s + "/" + _x509_hex2rdn(hRDN);
196 }
197 return s;
198}
199
200function _x509_hex2rdn(hRDN) {
201 var hType = ASN1HEX.getDecendantHexTLVByNthList(hRDN, 0, [0, 0]);
202 var hValue = ASN1HEX.getDecendantHexVByNthList(hRDN, 0, [0, 1]);
203 var type = "";
204 try { type = _x509_DN_ATTRHEX[hType]; } catch (ex) { type = hType; }
205 hValue = hValue.replace(/(..)/g, "%$1");
206 var value = decodeURIComponent(hValue);
207 return type + "=" + value;
208}
209
210// ===== read certificate =====================================
211
212
213/**
214 * read PEM formatted X.509 certificate from string.<br/>
215 * @name readCertPEM
216 * @memberOf X509#
217 * @function
218 * @param {String} sCertPEM string for PEM formatted X.509 certificate
219 */
220function _x509_readCertPEM(sCertPEM) {
221 var hCert = _x509_pemToHex(sCertPEM);
222 var a = _x509_getPublicKeyHexArrayFromCertHex(hCert);
223 if(LOG>4){
224 console.log('HEX VALUE IS ' + hCert);
225 console.log('type of a' + typeof a);
226 console.log('a VALUE IS ');
227 console.log(a);
228 console.log('a[0] VALUE IS ' + a[0]);
229 console.log('a[1] VALUE IS ' + a[1]);
230 }
231 var rsa = new RSAKey();
232 rsa.setPublic(a[0], a[1]);
233 this.subjectPublicKeyRSA = rsa;
234 this.subjectPublicKeyRSA_hN = a[0];
235 this.subjectPublicKeyRSA_hE = a[1];
236 this.hex = hCert;
237}
238
239/**
240 * read hex formatted X.509 certificate from string.
241 * @name readCertHex
242 * @memberOf X509#
243 * @function
244 * @param {String} hCert string for hex formatted X.509 certificate
245 */
246function _x509_readCertHex(hCert) {
247 hCert = hCert.toLowerCase();
248 var a = _x509_getPublicKeyHexArrayFromCertHex(hCert);
249 var rsa = new RSAKey();
250 rsa.setPublic(a[0], a[1]);
251 this.subjectPublicKeyRSA = rsa;
252 this.subjectPublicKeyRSA_hN = a[0];
253 this.subjectPublicKeyRSA_hE = a[1];
254 this.hex = hCert;
255}
256
257function _x509_readCertPEMWithoutRSAInit(sCertPEM) {
258 var hCert = _x509_pemToHex(sCertPEM);
259 var a = _x509_getPublicKeyHexArrayFromCertHex(hCert);
260 this.subjectPublicKeyRSA.setPublic(a[0], a[1]);
261 this.subjectPublicKeyRSA_hN = a[0];
262 this.subjectPublicKeyRSA_hE = a[1];
263 this.hex = hCert;
264}
265
266/**
267 * X.509 certificate class.<br/>
268 * @class X.509 certificate class
269 * @property {RSAKey} subjectPublicKeyRSA Tom Wu's RSAKey object
270 * @property {String} subjectPublicKeyRSA_hN hexadecimal string for modulus of RSA public key
271 * @property {String} subjectPublicKeyRSA_hE hexadecimal string for public exponent of RSA public key
272 * @property {String} hex hexacedimal string for X.509 certificate.
273 * @author Kenji Urushima
274 * @version 1.0.1 (08 May 2012)
275 * @see <a href="http://kjur.github.com/jsrsasigns/">'jwrsasign'(RSA Sign JavaScript Library) home page http://kjur.github.com/jsrsasign/</a>
276 */
277function X509() {
278 this.subjectPublicKeyRSA = null;
279 this.subjectPublicKeyRSA_hN = null;
280 this.subjectPublicKeyRSA_hE = null;
281 this.hex = null;
282}
283
284X509.prototype.readCertPEM = _x509_readCertPEM;
285X509.prototype.readCertHex = _x509_readCertHex;
286X509.prototype.readCertPEMWithoutRSAInit = _x509_readCertPEMWithoutRSAInit;
287X509.prototype.getSerialNumberHex = _x509_getSerialNumberHex;
288X509.prototype.getIssuerHex = _x509_getIssuerHex;
289X509.prototype.getSubjectHex = _x509_getSubjectHex;
290X509.prototype.getIssuerString = _x509_getIssuerString;
291X509.prototype.getSubjectString = _x509_getSubjectString;
292X509.prototype.getNotBefore = _x509_getNotBefore;
293X509.prototype.getNotAfter = _x509_getNotAfter;
294