1 /* asn1ocsp-1.1.3.js (c) 2016-2020 Kenji Urushima | kjur.github.com/jsrsasign/license
  2  */
  3 /*
  4  * asn1ocsp.js - ASN.1 DER encoder classes for OCSP protocol
  5  *
  6  * Copyright (c) 2016-2020 Kenji Urushima (kenji.urushima@gmail.com)
  7  *
  8  * This software is licensed under the terms of the MIT License.
  9  * https://kjur.github.io/jsrsasign/license
 10  *
 11  * The above copyright and license notice shall be 
 12  * included in all copies or substantial portions of the Software.
 13  */
 14 
 15 /**
 16  * @fileOverview
 17  * @name asn1ocsp-1.0.js
 18  * @author Kenji Urushima kenji.urushima@gmail.com
 19  * @version jsrsasign 9.1.9 asn1ocsp 1.1.3 (2020-Sep-08)
 20  * @since jsrsasign 6.1.0
 21  * @license <a href="https://kjur.github.io/jsrsasign/license/">MIT License</a>
 22  */
 23 
 24 if (typeof KJUR == "undefined" || !KJUR) KJUR = {};
 25 if (typeof KJUR.asn1 == "undefined" || !KJUR.asn1) KJUR.asn1 = {};
 26 
 27 /**
 28  * ASN.1 classes for OCSP protocol<br/>
 29  * <p>
 30  * This name space provides 
 31  * <a href="https://tools.ietf.org/html/rfc6960">RFC 6960
 32  * Online Certificate Status Protocol (OCSP)</a> ASN.1 request and response generator.
 33  *
 34  * <h4>FEATURES</h4>
 35  * <ul>
 36  * <li>easily generate OCSP data by JSON object</li>
 37  * </ul>
 38  * 
 39  * <h4>OCSP Response Encoder Classes</h4>
 40  * <ul>
 41  * <li>{@link KJUR.asn1.ocsp.OCSPResponse}</li>
 42  * <li>{@link KJUR.asn1.ocsp.ResponseBytes}</li>
 43  * <li>{@link KJUR.asn1.ocsp.BasicOCSPResponse}</li>
 44  * <li>{@link KJUR.asn1.ocsp.ResponseData}</li>
 45  * <li>{@link KJUR.asn1.ocsp.ResponderID}</li>
 46  * <li>{@link KJUR.asn1.ocsp.SingleResponseList}</li>
 47  * <li>{@link KJUR.asn1.ocsp.SingleResponse}</li>
 48  * <li>{@link KJUR.asn1.ocsp.CertID}</li>
 49  * <li>{@link KJUR.asn1.ocsp.CertStatus}</li>
 50  * </ul>
 51  *
 52  * <h4>OCSP Request Encoder Classes</h4>
 53  * <ul>
 54  * <li>{@link KJUR.asn1.ocsp.OCSPRequest}</li>
 55  * <li>{@link KJUR.asn1.ocsp.TBSRequest}</li>
 56  * <li>{@link KJUR.asn1.ocsp.Request}</li>
 57  * <li>{@link KJUR.asn1.ocsp.CertID}</li>
 58  * </ul>
 59  *
 60  * <h4>OCSP Utility classes</h4>
 61  * <ul>
 62  * <li>{@link KJUR.asn1.ocsp.OCSPUtil} - simple request parser</li>
 63  * <li>{@link KJUR.asn1.ocsp.OCSPParser} - request parser</li>
 64  * </ul>
 65  * </p>
 66  * @name KJUR.asn1.ocsp
 67  * @namespace
 68  */
 69 if (typeof KJUR.asn1.ocsp == "undefined" || !KJUR.asn1.ocsp) KJUR.asn1.ocsp = {};
 70 
 71 KJUR.asn1.ocsp.DEFAULT_HASH = "sha1";
 72 
 73 /**
 74  * OCSPResponse ASN.1 class encoder<br/>
 75  * @name KJUR.asn1.ocsp.OCSPResponse
 76  * @class OCSPResponse ASN.1 class encoder
 77  * @param {Array} params JSON object of constructor parameters
 78  * @extends KJUR.asn1.ASN1Object
 79  * @since jsrsasign 9.1.6 asn1ocsp 1.1.0
 80  * @see KJUR.asn1.ocsp.ResponseBytes
 81  *
 82  * @description
 83  * OCSPResponse ASN.1 class is defined in 
 84  * <a href="https://tools.ietf.org/html/rfc6960#section-4.2.1">RFC 6960 4.2.1</a>. 
 85  * <pre>
 86  * OCSPResponse ::= SEQUENCE {
 87  *    responseStatus         OCSPResponseStatus,
 88  *    responseBytes          [0] EXPLICIT ResponseBytes OPTIONAL }
 89  * OCSPResponseStatus ::= ENUMERATED {
 90  *     successful            (0),  -- Response has valid confirmations
 91  *     malformedRequest      (1),  -- Illegal confirmation request
 92  *     internalError         (2),  -- Internal error in issuer
 93  *     tryLater              (3),  -- Try again later
 94  *                                 -- (4) is not used
 95  *     sigRequired           (5),  -- Must sign the request
 96  *     unauthorized          (6)   -- Request unauthorized
 97  * } 
 98  * </pre>
 99  * This constructor accepts all parameter of
100  * {@link KJUR.asn1.ocsp.ResponseBytes} for "successful" response.
101  * Further more following property is needed:
102  * <ul>
103  * <li>{Number or String}resstats - responseStatus value by
104  * a number or name. (ex. 2, "internalError")</li>
105  * </ul>
106  *
107  * @example
108  * // default constructor for "successful"
109  * o = new KJUR.asn1.ocsp.OCSPResponse({
110  *   resstatus: "successful",
111  *   <<ResponseBytes parameters>>
112  * });
113  * // constructor for error
114  * new KJUR.asn1.ocsp.OCSPRequest({resstatus: 1})
115  * new KJUR.asn1.ocsp.OCSPRequest({resstatus: "unauthorized"})
116  */
117 KJUR.asn1.ocsp.OCSPResponse = function(params) {
118     KJUR.asn1.ocsp.OCSPResponse.superclass.constructor.call(this);
119 
120     var _DEREnumerated = KJUR.asn1.DEREnumerated,
121 	_newObject = KJUR.asn1.ASN1Util.newObject,
122 	_ResponseBytes = KJUR.asn1.ocsp.ResponseBytes;
123 
124     var _aSTATUSNAME = ["successful", "malformedRequest", "internalError",
125 			"tryLater", "_not_used_", "sigRequired", "unauthorized"]; 
126 
127     this.params = null;
128 
129     this._getStatusCode = function() {
130 	var code = this.params.resstatus;
131 	if (typeof code == "number") return code;
132 	if (typeof code != "string") return -1;
133 	return _aSTATUSNAME.indexOf(code);
134     };
135 
136     this.setByParam = function(params) {
137 	this.params = params;
138     };
139 
140     this.getEncodedHex = function() {
141 	var params = this.params;
142 
143 	var code = this._getStatusCode();
144 	if (code == -1) {
145 	    throw new Error("responseStatus not supported: " +
146 			    params.resstatus);
147 	}
148 
149 	if (code != 0) {
150 	    return _newObject({seq: [{'enum': {'int': code}}]}).getEncodedHex();
151 	}
152 	
153 	var dResBytes = new _ResponseBytes(params);
154 	return _newObject({seq: [
155 	    {'enum': {'int': 0}},
156 	    {tag: {tag: "a0", explicit: true, obj: dResBytes}}
157 	]}).getEncodedHex();
158     };
159 
160     if (params !== undefined) this.setByParam(params);
161 };
162 YAHOO.lang.extend(KJUR.asn1.ocsp.OCSPResponse, KJUR.asn1.ASN1Object);
163 
164 /**
165  * ResponseBytes ASN.1 class encoder<br/>
166  * @name KJUR.asn1.ocsp.ResponseBytes
167  * @class ResponseBytes ASN.1 class encoder
168  * @param {Array} params JSON object of constructor parameters
169  * @extends KJUR.asn1.ASN1Object
170  * @since jsrsasign 9.1.6 asn1ocsp 1.1.0
171  * @see KJUR.asn1.ocsp.OCSPResponse
172  * @see KJUR.asn1.ocsp.BasicOCSPResponse
173  *
174  * @description
175  * OCSPResponse ASN.1 class is defined in 
176  * <a href="https://tools.ietf.org/html/rfc6960#section-4.2.1">RFC 6960 4.2.1</a>. 
177  * <pre>
178  * ResponseBytes ::=       SEQUENCE {
179  *     responseType   OBJECT IDENTIFIER,
180  *     response       OCTET STRING }
181  * id-pkix-ocsp           OBJECT IDENTIFIER ::= { id-ad-ocsp }
182  * id-pkix-ocsp-basic     OBJECT IDENTIFIER ::= { id-pkix-ocsp 1 }
183  * </pre>
184  * This constructor accepts all parameter of
185  * {@link KJUR.asn1.ocsp.BasicOCSPResponse}.
186  * Further more following property is needed:
187  * <ul>
188  * <li>{String}restype - only "ocspBasic" can be available</li>
189  * </ul>
190  *
191  * @example
192  * o = new KJUR.asn1.ocsp.ResponseBytes({
193  *   restype: "ocspBasic",
194  *   // BasicOCSPResponse properties shall be specified
195  * });
196  */
197 KJUR.asn1.ocsp.ResponseBytes = function(params) {
198     KJUR.asn1.ocsp.ResponseBytes.superclass.constructor.call(this);
199 
200     var _KJUR_asn1 = KJUR.asn1,
201 	_DERSequence = _KJUR_asn1.DERSequence,
202 	_DERObjectIdentifier = _KJUR_asn1.DERObjectIdentifier,
203 	_DEROctetString = _KJUR_asn1.DEROctetString,
204 	_BasicOCSPResponse = _KJUR_asn1.ocsp.BasicOCSPResponse;
205 
206     this.params = null;
207 
208     this.setByParam = function(params) {
209 	this.params = params;
210     };
211 
212     this.getEncodedHex = function() {
213 	var params = this.params;
214 
215 	if (params.restype != "ocspBasic") {
216 	    throw new Error("not supported responseType: " + params.restype);
217 	}
218 
219 	var dBasic = new _BasicOCSPResponse(params);
220 
221 	var a = [];
222 	a.push(new _DERObjectIdentifier({name: "ocspBasic"}));
223 	a.push(new _DEROctetString({hex: dBasic.getEncodedHex()}));
224 
225 	var seq = new _DERSequence({array: a});
226 	return seq.getEncodedHex();
227     };
228 
229     if (params !== undefined) this.setByParam(params);
230 };
231 YAHOO.lang.extend(KJUR.asn1.ocsp.ResponseBytes, KJUR.asn1.ASN1Object);
232 
233 /**
234  * BasicOCSPResponse ASN.1 class encoder<br/>
235  * @name KJUR.asn1.ocsp.BasicOCSPResponse
236  * @class BasicOCSPResponse ASN.1 class encoder
237  * @param {Array} params JSON object of constructor parameters
238  * @extends KJUR.asn1.ASN1Object
239  * @since jsrsasign 9.1.6 asn1ocsp 1.1.0
240  * @see KJUR.asn1.ocsp.OCSPResponse
241  * @see KJUR.asn1.ocsp.ResponseBytes
242  * @see KJUR.asn1.ocsp.BasicOCSPResponse
243  * @see KJUR.asn1.ocsp.ResponseData
244  *
245  * @description
246  * OCSPResponse ASN.1 class is defined in 
247  * <a href="https://tools.ietf.org/html/rfc6960#section-4.2.1">RFC 6960 4.2.1</a>. 
248  * <pre>
249  * BasicOCSPResponse       ::= SEQUENCE {
250  *    tbsResponseData      ResponseData,
251  *    signatureAlgorithm   AlgorithmIdentifier,
252  *    signature            BIT STRING,
253  *    certs            [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL }
254  * </pre>
255  * This constructor accepts all parameter of
256  * {@link KJUR.asn1.ocsp.ResponseData}.
257  * Further more following properties are available:
258  * <ul>
259  * <li>{ASN1Object}tbsresp (OPTION) - {@link KJUR.asn1.ASN1Object} or its
260  * sub class object for tbsReponseData,
261  * genelally {@link KJUR.asn1.ocsp.ResponseData}.
262  * When "tbsresp" not specified, tbsresp will be set by
263  * other parameters internally.</li>
264  * <li>{String}sigalg - signatureAlgrithm name (ex. "SHA256withRSA")</li>
265  * <li>{Object}reskey (OPTION) - specifies OCSP response signing private key.
266  * Parameter "reskey" or "sighex" shall be specified.
267  * Following values can be specified:
268  *   <ul>
269  *   <li>PKCS#1/5 or PKCS#8 PEM string of private key</li>
270  *   <li>RSAKey/DSA/ECDSA key object. {@link KEYUTIL.getKey} is useful
271  *   to generate a key object.</li>
272  *   </ul>
273  * </li>
274  * <li>{String}sighex (OPTION) - hexadecimal string of signature value
275  * (i.e. ASN.1 value(V) of signatureValue BIT STRING without
276  * unused bits)</li>
277  * <li>{Array}certs (OPTION) - array of PEM or hexadecimal string of
278  * certificate such as OCSP responder certificate</li>
279  * </ul>
280  *
281  * @example
282  * // response data will be signed by "reskey"
283  * new KJUR.asn1.ocsp.BasicOCSPResponse({
284  *   ...<<ResponseData properties...>>...
285  *   sigalg: "SHA256withRSA",
286  *   reskey: <<OCSP Responder private key PEM or object>>,
287  *   certs: [<<PEMorHEXstringOfCert1>>,...] });
288  *
289  * // explicitly specify "signature" by "sighex"
290  * new KJUR.asn1.ocsp.BasicOCSPResponse({
291  *   ...<<ResponseData properties...>>...
292  *   sigalg: "SHA256withRSA",
293  *   sighex: "12abcd...",
294  *   certs: [<<PEMorHEXstringOfCert1>>,...] });
295  * 
296  * // explicitly specify "tbsResponseData" and sign
297  * new KJUR.asn1.ocsp.BasicOCSPResponse({
298  * { tbsresp: <<subclass of ASN1Object>>,
299  *   sigalg: "SHA256withRSA",
300  *   reskey: <<OCSP Responder private key PEM or object>>,
301  *   certs: [<<PEMorHEXstringOfCert1>>,...] }
302  */
303 KJUR.asn1.ocsp.BasicOCSPResponse = function(params) {
304     KJUR.asn1.ocsp.BasicOCSPResponse.superclass.constructor.call(this);
305 
306     var _Error = Error,
307 	_KJUR_asn1 = KJUR.asn1,
308 	_ASN1Object = _KJUR_asn1.ASN1Object,
309 	_DERSequence = _KJUR_asn1.DERSequence,
310 	_DERGeneralizedTime = _KJUR_asn1.DERGeneralizedTime,
311 	_DERTaggedObject = _KJUR_asn1.DERTaggedObject,
312 	_DERBitString = _KJUR_asn1.DERBitString,
313 	_Extensions = _KJUR_asn1.x509.Extensions,
314 	_AlgorithmIdentifier = _KJUR_asn1.x509.AlgorithmIdentifier,
315 	_KJUR_asn1_ocsp = _KJUR_asn1.ocsp,
316 	_ResponderID = _KJUR_asn1_ocsp.ResponderID;
317 	_SingleResponseList = _KJUR_asn1_ocsp.SingleResponseList,
318 	_ResponseData = _KJUR_asn1_ocsp.ResponseData;
319 
320     this.params = null;
321 
322     this.setByParam = function(params) {
323 	this.params = params;
324     };
325 
326     this.sign = function() {
327 	var params = this.params;
328 	var hTBS = params.tbsresp.getEncodedHex();
329 	var sig = new KJUR.crypto.Signature({alg: params.sigalg});
330 	sig.init(params.reskey);
331 	sig.updateHex(hTBS);
332 	params.sighex = sig.sign();
333     };
334 
335     this.getEncodedHex = function() {
336 	var params = this.params;
337 
338 	if (params.tbsresp == undefined) {
339 	    params.tbsresp = new _ResponseData(params);
340 	}
341 
342 	if (params.sighex == undefined && params.reskey != undefined) {
343 	    this.sign();
344 	}
345 
346 	var a = [];
347 	a.push(params.tbsresp);
348 	a.push(new _AlgorithmIdentifier({name: params.sigalg}));
349 	a.push(new _DERBitString({hex: "00" + params.sighex}));
350 
351 	if (params.certs != undefined &&
352 	    params.certs.length != undefined) {
353 	    var aCert = [];
354 	    for (var i = 0; i < params.certs.length; i++) {
355 		var sCert = params.certs[i];
356 		var hCert = null;
357 		if (ASN1HEX.isASN1HEX(sCert)) {
358 		    hCert = sCert;
359 		} else if (sCert.match(/-----BEGIN/)) {
360 		    hCert = pemtohex(sCert);
361 		} else {
362 		    throw new _Error("certs[" + i + "] not hex or PEM");
363 		}
364 		aCert.push(new _ASN1Object({tlv: hCert}));
365 	    }
366 	    var seqCert = new _DERSequence({array: aCert});
367 	    a.push(new _DERTaggedObject({tag:'a0',explicit:true,obj:seqCert}));
368 	}
369 	
370 	var seq = new _DERSequence({array: a});
371 	return seq.getEncodedHex();
372     };
373 
374     if (params !== undefined) this.setByParam(params);
375 };
376 YAHOO.lang.extend(KJUR.asn1.ocsp.BasicOCSPResponse, KJUR.asn1.ASN1Object);
377 
378 /**
379  * ResponseData ASN.1 class encoder<br/>
380  * @name KJUR.asn1.ocsp.ResponseData
381  * @class ResponseData ASN.1 class encoder
382  * @param {Array} params JSON object of constructor parameters
383  * @extends KJUR.asn1.ASN1Object
384  * @since jsrsasign 9.1.6 asn1ocsp 1.1.0
385  * @see KJUR.asn1.ocsp.OCSPResponse
386  * @see KJUR.asn1.ocsp.ResponseBytes
387  * @see KJUR.asn1.ocsp.BasicOCSPResponse
388  * @see KJUR.asn1.ocsp.ResponseData
389  * @see KJUR.asn1.ocsp.SingleResponse
390  * @see KJUR.asn1.x509.Extensions
391  * @see KJUR.asn1.DERGeneralizedTime
392  *
393  * @description
394  * ResponseData ASN.1 class is defined in 
395  * <a href="https://tools.ietf.org/html/rfc6960#section-4.2.1">RFC 6960 4.2.1</a>. 
396  * <pre>
397  * ResponseData ::= SEQUENCE {
398  *    version              [0] EXPLICIT Version DEFAULT v1,
399  *    responderID              ResponderID,
400  *    producedAt               GeneralizedTime,
401  *    responses                SEQUENCE OF SingleResponse,
402  *    responseExtensions   [1] EXPLICIT Extensions OPTIONAL }
403  * </pre>
404  * Following properties are available:
405  * <ul>
406  * <li>{Array}respid - JSON object of {@link KJUR.asn1.ocsp.ResponseID} parameter
407  * for "responderID"</li>
408  * <li>{Object}prodat - string or JSON parameter of 
409  * {@link KJUR.asn1.DERGeneralizedTime} (ex. "20200904235959Z")</li>
410  * <li>{Array}responses - array of {@link KJUR.asn1.ocsp.SingleResponse}
411  * parameters</li>
412  * <li>{Array}ext (OPTION) - array of extension parameters
413  * for "responseExtensions".</li>
414  * </ul>
415  *
416  * @example
417  * new KJUR.asn1.ocsp.ResponseData({
418  *   respid: {key: "12ab..."},
419  *   prodat: "20200903235959Z",
420  *   array: [
421  *     <<SingleResponse parameter1>>, ...
422  *   ],
423  *   ext: [
424  *     {extname:"ocspNonce",hex:"12ab..."}
425  *   ]
426  * });
427  */
428 KJUR.asn1.ocsp.ResponseData = function(params) {
429     KJUR.asn1.ocsp.ResponseData.superclass.constructor.call(this);
430 
431     var _Error = Error,
432 	_KJUR_asn1 = KJUR.asn1,
433 	_DERSequence = _KJUR_asn1.DERSequence,
434 	_DERGeneralizedTime = _KJUR_asn1.DERGeneralizedTime,
435 	_DERTaggedObject = _KJUR_asn1.DERTaggedObject,
436 	_Extensions = _KJUR_asn1.x509.Extensions,
437 	_KJUR_asn1_ocsp = _KJUR_asn1.ocsp,
438 	_ResponderID = _KJUR_asn1_ocsp.ResponderID;
439 	_SingleResponseList = _KJUR_asn1_ocsp.SingleResponseList;
440     
441     this.params = null;
442 
443     this.getEncodedHex = function() {
444 	var params = this.params;
445 	if (params.respid != undefined) new _Error("respid not specified");
446 	if (params.prodat != undefined) new _Error("prodat not specified");
447 	if (params.array != undefined) new _Error("array not specified");
448 
449 	var a = [];
450 	a.push(new _ResponderID(params.respid));
451 	a.push(new _DERGeneralizedTime(params.prodat));
452 	a.push(new _SingleResponseList(params.array));
453 
454 	if (params.ext != undefined) {
455 	    var dExt = new _Extensions(params.ext);
456 	    a.push(new _DERTaggedObject({tag:'a1', explicit:true, obj:dExt}));
457 	}
458 
459 	var seq = new _DERSequence({array: a});
460 	return seq.getEncodedHex();
461     };
462 
463     this.setByParam = function(params) {
464 	this.params = params;
465     };
466 
467     if (params !== undefined) this.setByParam(params);
468 };
469 YAHOO.lang.extend(KJUR.asn1.ocsp.ResponseData, KJUR.asn1.ASN1Object);
470 
471 /**
472  * ResponderID ASN.1 class encoder<br/>
473  * @name KJUR.asn1.ocsp.ResponderID
474  * @class ResponderID ASN.1 class encoder
475  * @param {Array} params JSON object of constructor parameters
476  * @extends KJUR.asn1.ASN1Object
477  * @since jsrsasign 9.1.6 asn1ocsp 1.1.0
478  * @see KJUR.asn1.ocsp.OCSPResponse
479  * @see KJUR.asn1.ocsp.ResponseBytes
480  * @see KJUR.asn1.ocsp.BasicOCSPResponse
481  * @see KJUR.asn1.ocsp.ResponseData
482  *
483  * @description
484  * ResponderID ASN.1 class is defined in 
485  * <a href="https://tools.ietf.org/html/rfc6960#section-4.2.1">RFC 6960 4.2.1</a>. 
486  * <pre>
487  * ResponderID ::= CHOICE {
488  *    byName               [1] Name,
489  *    byKey                [2] KeyHash }
490  * KeyHash ::= OCTET STRING -- SHA-1 hash of responder's public key
491  *                             (excluding the tag and length fields)
492  * </pre>
493  * Following properties are available:
494  * <ul>
495  * <li>{Array}name (OPTION) - JSON object of {@link KJUR.asn1.x509.X500Name} parameter
496  * for "byName"</li>
497  * <li>{String}key (OPTION) - hexadecimal string of KeyHash value</li>
498  * </ul>
499  *
500  * @example
501  * new KJUR.asn1.ocsp.ResponderID({name: {str: "/C=JP/O=Resp"}})
502  * new KJUR.asn1.ocsp.ResponderID({name: {array: [[{type:"C",value:"JP",ds:"prn"}]...]}})
503  * new KJUR.asn1.ocsp.ResponderID({key: "12ab..."})
504  */
505 KJUR.asn1.ocsp.ResponderID = function(params) {
506     KJUR.asn1.ocsp.ResponderID.superclass.constructor.call(this);
507     var _KJUR_asn1 = KJUR.asn1,
508 	_newObject = _KJUR_asn1.ASN1Util.newObject,
509 	_X500Name = _KJUR_asn1.x509.X500Name;
510     
511     this.params = null;
512     
513     this.getEncodedHex = function() {
514 	var params = this.params;
515 	if (params.key != undefined) {
516 	    var dTag = _newObject({tag: {tag:"a2",
517 					 explicit:true,
518 					 obj:{octstr:{hex:params.key}}}});
519 	    return dTag.getEncodedHex();
520 	} else if (params.name != undefined) {
521 	    var dTag = _newObject({tag: {tag:"a1",
522 					 explicit:true,
523 					 obj:new _X500Name(params.name)}});
524 	    return dTag.getEncodedHex();
525 	}
526 	throw new Error("key or name not specified");
527     };
528 
529     this.setByParam = function(params) {
530 	this.params = params;
531     };
532 
533     if (params !== undefined) this.setByParam(params);
534 };
535 YAHOO.lang.extend(KJUR.asn1.ocsp.ResponderID, KJUR.asn1.ASN1Object);
536 
537 /**
538  * ASN.1 class encoder for SEQUENCE OF SingleResponse<br/>
539  * @name KJUR.asn1.ocsp.SingleResponseList
540  * @class ASN.1 class encoder for SEQUENCE OF SingleResponse
541  * @param {Array} params array of JSON object for SingleResponse parameters
542  * @extends KJUR.asn1.ASN1Object
543  * @since jsrsasign 9.1.6 asn1ocsp 1.1.0
544  * @see KJUR.asn1.ocsp.OCSPResponse
545  * @see KJUR.asn1.ocsp.ResponseBytes
546  * @see KJUR.asn1.ocsp.BasicOCSPResponse
547  * @see KJUR.asn1.ocsp.ResponseData
548  * @see KJUR.asn1.ocsp.SingleResponse
549  *
550  * @description
551  * ASN.1 class of SEQUENCE OF SingleResponse is defined in 
552  * <a href="https://tools.ietf.org/html/rfc6960#section-4.2.1">RFC 6960 4.2.1</a>. 
553  * <pre>
554  * ResponseData ::= SEQUENCE {
555  *    version              [0] EXPLICIT Version DEFAULT v1,
556  *    responderID              ResponderID,
557  *    producedAt               GeneralizedTime,
558  *    responses                SEQUENCE OF SingleResponse,
559  *    responseExtensions   [1] EXPLICIT Extensions OPTIONAL }
560  * SingleResponse ::= SEQUENCE {
561  *    certID                       CertID,
562  *    certStatus                   CertStatus,
563  *    thisUpdate                   GeneralizedTime,
564  *    nextUpdate         [0]       EXPLICIT GeneralizedTime OPTIONAL,
565  *    singleExtensions   [1]       EXPLICIT Extensions OPTIONAL }
566  * </pre>
567  * Following properties are available:
568  * <ul>
569  * <li>{Array}name (OPTION) - JSON object of {@link KJUR.asn1.x509.X500Name} parameter
570  * for "byName"</li>
571  * <li>{String}key (OPTION) - hexadecimal string of KeyHash value</li>
572  * </ul>
573  *
574  * @example
575  * new KJUR.asn1.ocsp.SingleResponseList([{
576  *   certid: {alg:"sha1",issname:"12ab",isskey:"12ab",sbjsn:"12ab"},
577  *   status: {status: "good"},
578  *   thisupdate: "20200903235959Z"
579  * },{
580  *   certid: {alg:"sha1",issname:"24ab",isskey:"24ab",sbjsn:"24ab"},
581  *   status: {status: "good"},
582  *   thisupdate: "20200904235959Z"
583  * ])
584  */
585 KJUR.asn1.ocsp.SingleResponseList = function(params) {
586     KJUR.asn1.ocsp.SingleResponseList.superclass.constructor.call(this);
587 
588     var _KJUR_asn1 = KJUR.asn1,
589 	_DERSequence = _KJUR_asn1.DERSequence,
590 	_SingleResponse = _KJUR_asn1.ocsp.SingleResponse;
591 
592     this.params = null;
593     
594     this.getEncodedHex = function() {
595 	var params = this.params;
596 
597 	if (typeof params != "object" || params.length == undefined) {
598 	    throw new Error("params not specified properly");
599 	}
600 
601 	var a = [];
602 	for (var i = 0; i < params.length; i++) {
603 	    a.push(new _SingleResponse(params[i]));
604 	}
605 
606 	var seq = new _DERSequence({array: a});
607 	return seq.getEncodedHex();
608     };
609 
610     this.setByParam = function(params) {
611 	this.params = params;
612     };
613 
614     if (params !== undefined) this.setByParam(params);
615 };
616 YAHOO.lang.extend(KJUR.asn1.ocsp.SingleResponseList, KJUR.asn1.ASN1Object);
617 
618 /**
619  * SingleResponse ASN.1 class encoder<br/>
620  * @name KJUR.asn1.ocsp.SingleResponse
621  * @class SingleResponse ASN.1 class encoder
622  * @param {Array} params JSON object for SingleResponse parameter
623  * @extends KJUR.asn1.ASN1Object
624  * @since jsrsasign 9.1.6 asn1ocsp 1.1.0
625  * @see KJUR.asn1.ocsp.OCSPResponse
626  * @see KJUR.asn1.ocsp.ResponseBytes
627  * @see KJUR.asn1.ocsp.BasicOCSPResponse
628  * @see KJUR.asn1.ocsp.ResponseData
629  * @see KJUR.asn1.ocsp.SingleResponse
630  * @see KJUR.asn1.ocsp.CertID
631  * @see KJUR.asn1.ocsp.CertStatus
632  *
633  * @description
634  * ASN.1 class of SEQUENCE OF SingleResponse is defined in 
635  * <a href="https://tools.ietf.org/html/rfc6960#section-4.2.1">RFC 6960 4.2.1</a>. 
636  * <pre>
637  * SingleResponse ::= SEQUENCE {
638  *    certID                       CertID,
639  *    certStatus                   CertStatus,
640  *    thisUpdate                   GeneralizedTime,
641  *    nextUpdate         [0]       EXPLICIT GeneralizedTime OPTIONAL,
642  *    singleExtensions   [1]       EXPLICIT Extensions OPTIONAL }
643  * </pre>
644  * Following properties are available:
645  * <ul>
646  * <li>{Array}certid - JSON object of {@link KJUR.asn1.ocsp.CertID} parameter</li>
647  * <li>{Array}status - JSON object of {@link KJUR.asn1.ocsp.CertStatus} parameter</li>
648  * <li>{Object}thisupdate - {@link KJUR.asn1.DERGeneralizedTime} parameter
649  * for "thisUpdate"</li>
650  * <li>{Object}nextupdate (OPTION) - {@link KJUR.asn1.DERGeneralizedTime} parameter
651  * for "nextUpdate"</li>
652  * <li>{Array}ext (OPTION) - array of JSON object 
653  * {@link KJUR.asn1.x509.Extension} sub class parameter for
654  * "singleExtensions"</li>
655  * </ul>
656  *
657  * @example
658  * new KJUR.asn1.ocsp.SingleResponse({
659  *   certid: {alg:"sha1",issname:"12ab",isskey:"12ab",sbjsn:"12ab"},
660  *   status: {status: "good"},
661  *   thisupdate: "20200903235959Z",
662  *   nextupdate: "20200913235959Z",
663  *   ext: [<<Extension parameters>>...]
664  * })
665  */
666 KJUR.asn1.ocsp.SingleResponse = function(params) {
667     var _Error = Error,
668 	_KJUR = KJUR,
669 	_KJUR_asn1 = _KJUR.asn1,
670 	_DERSequence = _KJUR_asn1.DERSequence,
671 	_DERGeneralizedTime = _KJUR_asn1.DERGeneralizedTime,
672 	_DERTaggedObject = _KJUR_asn1.DERTaggedObject,
673 	_KJUR_asn1_ocsp = _KJUR_asn1.ocsp,
674 	_CertID = _KJUR_asn1_ocsp.CertID,
675 	_CertStatus = _KJUR_asn1_ocsp.CertStatus,
676 	_KJUR_asn1_x509 = _KJUR_asn1.x509,
677 	_Extensions = _KJUR_asn1_x509.Extensions;
678 
679     _KJUR_asn1_ocsp.SingleResponse.superclass.constructor.call(this);
680 
681     this.params = null;
682     
683     this.getEncodedHex = function() {
684 	var params = this.params;
685 	var a = [];
686 
687 	if (params.certid == undefined) throw new _Error("certid unspecified");
688 	if (params.status == undefined) throw new _Error("status unspecified");
689 	if (params.thisupdate == undefined) throw new _Error("thisupdate unspecified");
690 
691 	a.push(new _CertID(params.certid));
692 	a.push(new _CertStatus(params.status));
693 	a.push(new _DERGeneralizedTime(params.thisupdate));
694 
695 	if (params.nextupdate != undefined) {
696 	    var dTime = new _DERGeneralizedTime(params.nextupdate);
697 	    a.push(new _DERTaggedObject({tag:'a0', explicit:true, obj:dTime}));
698 	}
699 
700 	if (params.ext != undefined) {
701 	    var dExt = new _Extensions(params.ext);
702 	    a.push(new _DERTaggedObject({tag:'a1', explicit:true, obj:dExt}));
703 	}
704 
705 	var seq = new _DERSequence({array: a});
706 	return seq.getEncodedHex();
707     };
708 
709     this.setByParam = function(params) {
710 	this.params = params;
711     };
712 
713     if (params !== undefined) this.setByParam(params);
714 };
715 YAHOO.lang.extend(KJUR.asn1.ocsp.SingleResponse, KJUR.asn1.ASN1Object);
716 
717 /**
718  * ASN.1 CertID class for OCSP<br/>
719  * @name KJUR.asn1.ocsp.CertID
720  * @class ASN.1 CertID class for OCSP
721  * @param {Array} params JSON object of parameters
722  * @extends KJUR.asn1.ASN1Object
723  * @since jsrsasign 6.1.0 asn1ocsp 1.0.0
724  * @see KJUR.asn1.ocsp.SingleResponse
725  * @see KJUR.asn1.x509.AlgorithmIdentifier
726  *
727  * @description
728  * CertID ASN.1 class is defined in 
729  * <a href="https://tools.ietf.org/html/rfc6960#section-4.1.1">RFC 6960 4.1.1</a>. 
730  * <pre>
731  * CertID ::= SEQUENCE {
732  *   hashAlgorithm   AlgorithmIdentifier,
733  *   issuerNameHash  OCTET STRING, -- Hash of issuer's DN
734  *   issuerKeyHash   OCTET STRING, -- Hash of issuer's public key
735  *   serialNumber    CertificateSerialNumber }
736  * </pre>
737  * Following properties are available in "params" of the constructor:
738  * <ul>
739  * <li>{String}alg (OPTION) - hash algorithm name. Default is "sha1" (ex, "sha1")</li>
740  * <li>{String}issname (OPTION) - hexadecimal string of issuerNameHash</li>
741  * <li>{String}isskey (OPTION) - hexadecimal string of issuerKeyHash</li>
742  * <li>{String}sbjsn (OPTION) - hexadecimal string of serial number of subject certificate</li>
743  * <li>{String}issuerCert (OPTION) - PEM string of issuer certificate.
744  * Property "issname" and "isskey" will be set by "issuerCert".</li>
745  * <li>{String}subjectCert (OPTION) - PEM string of issuer certificate.
746  * Property "sbjsn" will be set by "subjectCert".</li>
747  * </ul>
748  * <br/>
749  * NOTE: Properties "namehash", "keyhash" and "serial" are
750  * changed to "issname", "isskey", and "sbjsn" respectively
751  * since jsrsasign 9.1.6 asn1ocsp 1.1.0.
752  *
753  * @example
754  * // constructor with explicit values (changed since jsrsasign 9.1.6)
755  * new KJUR.asn1.ocsp.CertID({issname: "1a...", isskey: "ad...", sbjsn: "1234", alg: "sha256"});
756  *
757  * // constructor with certs (sha1 is used by default)
758  * o = new KJUR.asn1.ocsp.CertID({issuerCert: "-----BEGIN...", subjectCert: "-----BEGIN..."});
759  *
760  * // constructor with certs and sha256
761  * o = new KJUR.asn1.ocsp.CertID({issuerCert: "-----BEGIN...", subjectCert: "-----BEGIN...", alg: "sha256"});
762  */
763 KJUR.asn1.ocsp.CertID = function(params) {
764     var _KJUR = KJUR,
765 	_KJUR_asn1 = _KJUR.asn1,
766 	_DEROctetString = _KJUR_asn1.DEROctetString,
767 	_DERInteger = _KJUR_asn1.DERInteger,
768 	_DERSequence = _KJUR_asn1.DERSequence,
769 	_KJUR_asn1_x509 = _KJUR_asn1.x509,
770 	_AlgorithmIdentifier = _KJUR_asn1_x509.AlgorithmIdentifier,
771 	_KJUR_asn1_ocsp = _KJUR_asn1.ocsp,
772 	_DEFAULT_HASH = _KJUR_asn1_ocsp.DEFAULT_HASH,
773 	_KJUR_crypto = _KJUR.crypto,
774 	_hashHex = _KJUR_crypto.Util.hashHex,
775 	_X509 = X509,
776 	_ASN1HEX = ASN1HEX;
777 
778     _KJUR_asn1_ocsp.CertID.superclass.constructor.call(this);
779 
780     this.dHashAlg = null;
781     this.dIssuerNameHash = null;
782     this.dIssuerKeyHash = null;
783     this.dSerialNumber = null;
784 
785     /**
786      * set CertID ASN.1 object by values.<br/>
787      * @name setByValue
788      * @memberOf KJUR.asn1.ocsp.CertID#
789      * @function
790      * @param {String} issuerNameHashHex hexadecimal string of hash value of issuer name
791      * @param {String} issuerKeyHashHex hexadecimal string of hash value of issuer public key
792      * @param {String} serialNumberHex hexadecimal string of certificate serial number to be verified
793      * @param {String} algName hash algorithm name used for above arguments (ex. "sha1") DEFAULT: sha1
794      * @since jsrsasign 6.1.0 asn1ocsp 1.0.0
795      * @example
796      * o = new KJUR.asn1.ocsp.CertID();
797      * o.setByValue("1fac...", "fd3a...", "1234"); // sha1 is used by default
798      * o.setByValue("1fac...", "fd3a...", "1234", "sha256");
799      */
800     this.setByValue = function(issuerNameHashHex, issuerKeyHashHex,
801 			       serialNumberHex, algName) {
802 	if (algName === undefined) algName = _DEFAULT_HASH;
803 	this.dHashAlg =        new _AlgorithmIdentifier({name: algName});
804 	this.dIssuerNameHash = new _DEROctetString({hex: issuerNameHashHex});
805 	this.dIssuerKeyHash =  new _DEROctetString({hex: issuerKeyHashHex});
806 	this.dSerialNumber =   new _DERInteger({hex: serialNumberHex});
807     };
808 
809     /**
810      * set CertID ASN.1 object by PEM certificates.<br/>
811      * @name setByCert
812      * @memberOf KJUR.asn1.ocsp.CertID#
813      * @function
814      * @param {String} issuerCert string of PEM issuer certificate
815      * @param {String} subjectCert string of PEM subject certificate to be verified by OCSP
816      * @param {String} algName hash algorithm name used for above arguments (ex. "sha1") DEFAULT: sha1
817      * @since jsrsasign 6.1.0 asn1ocsp 1.0.0
818      *
819      * @example
820      * o = new KJUR.asn1.ocsp.CertID();
821      * o.setByCert("-----BEGIN...", "-----BEGIN..."); // sha1 is used by default
822      * o.setByCert("-----BEGIN...", "-----BEGIN...", "sha256");
823      */
824     this.setByCert = function(issuerCert, subjectCert, algName) {
825 	if (algName === undefined) algName = _DEFAULT_HASH;
826 
827 	var xSbj = new _X509();
828 	xSbj.readCertPEM(subjectCert);
829 	var xIss = new _X509();
830 	xIss.readCertPEM(issuerCert);
831 
832 	var hISS_SPKI = xIss.getPublicKeyHex();
833 	var issuerKeyHex = _ASN1HEX.getTLVbyList(hISS_SPKI, 0, [1, 0], "30");
834 
835 	var serialNumberHex = xSbj.getSerialNumberHex();
836 	var issuerNameHashHex = _hashHex(xIss.getSubjectHex(), algName);
837 	var issuerKeyHashHex = _hashHex(issuerKeyHex, algName);
838 	this.setByValue(issuerNameHashHex, issuerKeyHashHex,
839 			serialNumberHex, algName);
840 	this.hoge = xSbj.getSerialNumberHex();
841     };
842 
843     this.getEncodedHex = function() {
844 	if (this.dHashAlg === null && 
845 	    this.dIssuerNameHash === null &&
846 	    this.dIssuerKeyHash === null &&
847 	    this.dSerialNumber === null)
848 	    throw "not yet set values";
849 
850 	var a = [this.dHashAlg, this.dIssuerNameHash,
851 		 this.dIssuerKeyHash, this.dSerialNumber];
852 	var seq = new _DERSequence({array: a});
853         this.hTLV = seq.getEncodedHex();
854         return this.hTLV;
855     };
856 
857     if (params !== undefined) {
858 	var p = params;
859 	if (p.issuerCert !== undefined &&
860 	    p.subjectCert !== undefined) {
861 	    var alg = _DEFAULT_HASH;
862 	    if (p.alg === undefined) alg = undefined;
863 	    this.setByCert(p.issuerCert, p.subjectCert, alg);
864 	} else if (p.issname !== undefined &&
865 		   p.isskey !== undefined &&
866 		   p.sbjsn !== undefined) {
867 	    var alg = _DEFAULT_HASH;
868 	    if (p.alg === undefined) alg = undefined;
869 	    this.setByValue(p.issname, p.isskey, p.sbjsn, alg);
870 	} else {
871 	    throw new Error("invalid constructor arguments");
872 	}
873     }
874 };
875 YAHOO.lang.extend(KJUR.asn1.ocsp.CertID, KJUR.asn1.ASN1Object);
876 
877 /**
878  * CertStatus ASN.1 class encoder<br/>
879  * @name KJUR.asn1.ocsp.CertStatus
880  * @class CertStatus ASN.1 class encoder
881  * @param {Array} params JSON object for CertStatus parameter
882  * @extends KJUR.asn1.ASN1Object
883  * @since jsrsasign 9.1.6 asn1ocsp 1.1.0
884  * @see KJUR.asn1.ocsp.OCSPResponse
885  * @see KJUR.asn1.ocsp.ResponseBytes
886  * @see KJUR.asn1.ocsp.BasicOCSPResponse
887  * @see KJUR.asn1.ocsp.ResponseData
888  * @see KJUR.asn1.ocsp.SingleResponse
889  * @see KJUR.asn1.ocsp.CertID
890  * @see KJUR.asn1.ocsp.CertStatus
891  *
892  * @description
893  * ASN.1 class of SEQUENCE OF SingleResponse is defined in 
894  * <a href="https://tools.ietf.org/html/rfc6960#section-4.2.1">RFC 6960 4.2.1</a>. 
895  * <pre>
896  * CertStatus ::= CHOICE {
897  *     good        [0]     IMPLICIT NULL,
898  *     revoked     [1]     IMPLICIT RevokedInfo,
899  *     unknown     [2]     IMPLICIT UnknownInfo }
900  * RevokedInfo ::= SEQUENCE {
901  *     revocationTime              GeneralizedTime,
902  *     revocationReason    [0]     EXPLICIT CRLReason OPTIONAL }
903  * UnknownInfo ::= NULL
904  * CRLReason ::= ENUMERATED {
905  *      unspecified             (0),
906  *      keyCompromise           (1),
907  *      cACompromise            (2),
908  *      affiliationChanged      (3),
909  *      superseded              (4),
910  *      cessationOfOperation    (5),
911  *      certificateHold         (6),
912  *           -- value 7 is not used
913  *      removeFromCRL           (8),
914  *      privilegeWithdrawn      (9),
915  *      aACompromise           (10) }
916  * </pre>
917  * Following properties are available:
918  * <ul>
919  * <li>{String}status - "good", "revoked" or "unknown"</li>
920  * <li>{String}time (OPTION) - revocationTime YYYYMMDDHHmmSSZ (ex. "20200904235959Z")</li>
921  * <li>{Number}reason (OPTION) - revocationReason code number</li>
922  * </ul>
923  *
924  * @example
925  * new KJUR.asn1.ocsp.CertStatus({status: "good"})
926  * new KJUR.asn1.ocsp.CertStatus({status: "revoked", time: "20200903235959Z"})
927  * new KJUR.asn1.ocsp.CertStatus({status: "revoked", time: "20200903235959Z", reason: 3})
928  * new KJUR.asn1.ocsp.CertStatus({status: "unknown"})
929  */
930 KJUR.asn1.ocsp.CertStatus = function(params) {
931     KJUR.asn1.ocsp.CertStatus.superclass.constructor.call(this);
932 
933     this.params = null;
934 
935     this.getEncodedHex = function() {
936 	var params = this.params;
937 	if (params.status == "good") return "8000";
938 	if (params.status == "unknown") return "8200";
939 	if (params.status == "revoked") {
940 	    var a = [{gentime: {str: params.time}}];
941 	    if (params.reason != undefined) {
942 		a.push({tag: {tag: 'a0', 
943 			      explicit: true,
944 			      obj: {'enum': {'int': params.reason}}}});
945 	    }
946 	    var tagParam = {tag: 'a1', explicit: false, obj: {seq: a}};
947 	    return KJUR.asn1.ASN1Util.newObject({tag: tagParam}).getEncodedHex();
948 	}
949 	throw new Error("bad status");
950     };
951 
952     this.setByParam = function(params) {
953 	this.params = params;
954     };
955 
956     if (params !== undefined) this.setByParam(params);
957 };
958 YAHOO.lang.extend(KJUR.asn1.ocsp.CertStatus, KJUR.asn1.ASN1Object);
959 
960 // ---- END OF Classes for OCSP response -----------------------------------
961 
962 /**
963  * ASN.1 Request class for OCSP<br/>
964  * @name KJUR.asn1.ocsp.Request
965  * @class ASN.1 Request class for OCSP
966  * @param {Array} params associative array of parameters
967  * @extends KJUR.asn1.ASN1Object
968  * @since jsrsasign 6.1.0 asn1ocsp 1.0.0
969  * @description
970  * Request ASN.1 class is defined in 
971  * <a href="https://tools.ietf.org/html/rfc6960#section-4.1.1">RFC 6960 4.1.1</a>. 
972  * singleRequestExtensions is not supported yet in this version such as nonce.
973  * <pre>
974  * Request ::= SEQUENCE {
975  *   reqCert                  CertID,
976  *   singleRequestExtensions  [0] EXPLICIT Extensions OPTIONAL }
977  * </pre>
978  * @example
979  * // default constructor
980  * o = new KJUR.asn1.ocsp.Request();
981  * // constructor with certs (sha1 is used by default)
982  * o = new KJUR.asn1.ocsp.Request({issuerCert: "-----BEGIN...", subjectCert: "-----BEGIN..."});
983  * // constructor with certs and sha256
984  * o = new KJUR.asn1.ocsp.Request({issuerCert: "-----BEGIN...", subjectCert: "-----BEGIN...", alg: "sha256"});
985  * // constructor with values
986  * o = new KJUR.asn1.ocsp.Request({namehash: "1a...", keyhash: "ad...", serial: "1234", alg: "sha256"});
987  */
988 KJUR.asn1.ocsp.Request = function(params) {
989     var _KJUR = KJUR,
990 	_KJUR_asn1 = _KJUR.asn1,
991 	_DERSequence = _KJUR_asn1.DERSequence,
992 	_KJUR_asn1_ocsp = _KJUR_asn1.ocsp;
993     
994     _KJUR_asn1_ocsp.Request.superclass.constructor.call(this);
995     this.dReqCert = null;
996     this.dExt = null;
997     
998     this.getEncodedHex = function() {
999 	var a = [];
1000 
1001 	// 1. reqCert
1002 	if (this.dReqCert === null)
1003 	    throw "reqCert not set";
1004 	a.push(this.dReqCert);
1005 
1006 	// 2. singleRequestExtensions (not supported yet)
1007 
1008 	// 3. construct SEQUENCE
1009 	var seq = new _DERSequence({array: a});
1010         this.hTLV = seq.getEncodedHex();
1011         return this.hTLV;
1012     };
1013 
1014     if (typeof params !== "undefined") {
1015 	var o = new _KJUR_asn1_ocsp.CertID(params);
1016 	this.dReqCert = o;
1017     }
1018 };
1019 YAHOO.lang.extend(KJUR.asn1.ocsp.Request, KJUR.asn1.ASN1Object);
1020 
1021 /**
1022  * ASN.1 TBSRequest class for OCSP<br/>
1023  * @name KJUR.asn1.ocsp.TBSRequest
1024  * @class ASN.1 TBSRequest class for OCSP
1025  * @param {Array} params associative array of parameters
1026  * @extends KJUR.asn1.ASN1Object
1027  * @since jsrsasign 6.1.0 asn1ocsp 1.0.0
1028  * @description
1029  * TBSRequest ASN.1 class is defined in 
1030  * <a href="https://tools.ietf.org/html/rfc6960#section-4.1.1">RFC 6960 4.1.1</a>. 
1031  * <pre>
1032  * TBSRequest ::= SEQUENCE {
1033  *   version            [0] EXPLICIT Version DEFAULT v1,
1034  *   requestorName      [1] EXPLICIT GeneralName OPTIONAL,
1035  *   requestList            SEQUENCE OF Request,
1036  *   requestExtensions  [2] EXPLICIT Extensions OPTIONAL }
1037  * </pre>
1038  * @example
1039  * // default constructor
1040  * o = new KJUR.asn1.ocsp.TBSRequest();
1041  * // constructor with requestList parameter
1042  * o = new KJUR.asn1.ocsp.TBSRequest({reqList:[
1043  *   {issuerCert: "-----BEGIN...", subjectCert: "-----BEGIN...", alg:},
1044  *   {issuerCert: "-----BEGIN...", subjectCert: "-----BEGIN...", alg: "sha256"}
1045  * ]});
1046  */
1047 KJUR.asn1.ocsp.TBSRequest = function(params) {
1048     var _KJUR = KJUR,
1049 	_KJUR_asn1 = _KJUR.asn1,
1050 	_DERSequence = _KJUR_asn1.DERSequence,
1051 	_KJUR_asn1_ocsp = _KJUR_asn1.ocsp;
1052 
1053     _KJUR_asn1_ocsp.TBSRequest.superclass.constructor.call(this);
1054     this.version = 0;
1055     this.dRequestorName = null;
1056     this.dRequestList = [];
1057     this.dRequestExt = null;
1058 
1059     /**
1060      * set TBSRequest ASN.1 object by array of parameters.<br/>
1061      * @name setRequestListByParam
1062      * @memberOf KJUR.asn1.ocsp.TBSRequest#
1063      * @function
1064      * @param {Array} aParams array of parameters for Request class
1065      * @since jsrsasign 6.1.0 asn1ocsp 1.0.0
1066      * @example
1067      * o = new KJUR.asn1.ocsp.TBSRequest();
1068      * o.setRequestListByParam([
1069      *   {issuerCert: "-----BEGIN...", subjectCert: "-----BEGIN...", alg:},
1070      *   {issuerCert: "-----BEGIN...", subjectCert: "-----BEGIN...", alg: "sha256"}
1071      * ]);
1072      */
1073     this.setRequestListByParam = function(aParams) {
1074 	var a = [];
1075 	for (var i = 0; i < aParams.length; i++) {
1076 	    var dReq = new _KJUR_asn1_ocsp.Request(aParams[0]);
1077 	    a.push(dReq);
1078 	}
1079 	this.dRequestList = a;
1080     };
1081 
1082     this.getEncodedHex = function() {
1083 	var a = [];
1084 
1085 	// 1. version
1086 	if (this.version !== 0)
1087 	    throw "not supported version: " + this.version;
1088 
1089 	// 2. requestorName
1090 	if (this.dRequestorName !== null)
1091 	    throw "requestorName not supported";
1092 
1093 	// 3. requestList
1094 	var seqRequestList = 
1095 	    new _DERSequence({array: this.dRequestList});
1096 	a.push(seqRequestList);
1097 
1098 	// 4. requestExtensions
1099 	if (this.dRequestExt !== null)
1100 	    throw "requestExtensions not supported";
1101 
1102 	// 5. construct SEQUENCE
1103 	var seq = new _DERSequence({array: a});
1104         this.hTLV = seq.getEncodedHex();
1105         return this.hTLV;
1106     };
1107 
1108     if (params !== undefined) {
1109 	if (params.reqList !== undefined)
1110 	    this.setRequestListByParam(params.reqList);
1111     }
1112 };
1113 YAHOO.lang.extend(KJUR.asn1.ocsp.TBSRequest, KJUR.asn1.ASN1Object);
1114 
1115 
1116 /**
1117  * ASN.1 OCSPRequest class for OCSP<br/>
1118  * @name KJUR.asn1.ocsp.OCSPRequest
1119  * @class ASN.1 OCSPRequest class for OCSP
1120  * @param {Array} params associative array of parameters
1121  * @extends KJUR.asn1.ASN1Object
1122  * @since jsrsasign 6.1.0 asn1ocsp 1.0.0
1123  * @description
1124  * OCSPRequest ASN.1 class is defined in 
1125  * <a href="https://tools.ietf.org/html/rfc6960#section-4.1.1">RFC 6960 4.1.1</a>. 
1126  * A signed request is not supported yet in this version.
1127  * <pre>
1128  * OCSPRequest ::= SEQUENCE {
1129  *   tbsRequest             TBSRequest,
1130  *   optionalSignature  [0] EXPLICIT Signature OPTIONAL }
1131  * </pre>
1132  * @example
1133  * // default constructor
1134  * o = new KJUR.asn1.ocsp.OCSPRequest();
1135  * // constructor with requestList parameter
1136  * o = new KJUR.asn1.ocsp.OCSPRequest({reqList:[
1137  *   {issuerCert: "-----BEGIN...", subjectCert: "-----BEGIN...", alg:},
1138  *   {issuerCert: "-----BEGIN...", subjectCert: "-----BEGIN...", alg: "sha256"}
1139  * ]});
1140  */
1141 KJUR.asn1.ocsp.OCSPRequest = function(params) {
1142     var _KJUR = KJUR,
1143 	_KJUR_asn1 = _KJUR.asn1,
1144 	_DERSequence = _KJUR_asn1.DERSequence,
1145 	_KJUR_asn1_ocsp = _KJUR_asn1.ocsp;
1146 
1147     _KJUR_asn1_ocsp.OCSPRequest.superclass.constructor.call(this);
1148     this.dTbsRequest = null;
1149     this.dOptionalSignature = null;
1150 
1151     this.getEncodedHex = function() {
1152 	var a = [];
1153 
1154 	// 1. tbsRequest
1155 	if (this.dTbsRequest !== null) {
1156 	    a.push(this.dTbsRequest);
1157 	} else {
1158 	    throw "tbsRequest not set";
1159 	}
1160 
1161 	// 2. optionalSignature
1162 	if (this.dOptionalSignature !== null)
1163 	    throw "optionalSignature not supported";
1164 
1165 	// 3. construct SEQUENCE
1166 	var seq = new _DERSequence({array: a});
1167         this.hTLV = seq.getEncodedHex();
1168         return this.hTLV;
1169     };
1170 
1171     if (params !== undefined) {
1172 	if (params.reqList !== undefined) {
1173 	    var o = new _KJUR_asn1_ocsp.TBSRequest(params);
1174 	    this.dTbsRequest = o;
1175 	}
1176     }
1177 };
1178 YAHOO.lang.extend(KJUR.asn1.ocsp.OCSPRequest, KJUR.asn1.ASN1Object);
1179 
1180 /**
1181  * Utility class for OCSP<br/>
1182  * @name KJUR.asn1.ocsp.OCSPUtil
1183  * @class Utility class for OCSP
1184  * @since jsrsasign 6.1.0 asn1ocsp 1.0.0
1185  * @description
1186  * This class provides utility static methods for OCSP.
1187  * <ul>
1188  * <li>{@link KJUR.asn1.ocsp.OCSPUtil.getRequestHex} - generates hexadecimal string of OCSP request</li>
1189  * </ul>
1190  */
1191 KJUR.asn1.ocsp.OCSPUtil = {};
1192 
1193 /**
1194  * generates hexadecimal string of OCSP request<br/>
1195  * @name getRequestHex
1196  * @memberOf KJUR.asn1.ocsp.OCSPUtil
1197  * @function
1198  * @param {String} issuerCert string of PEM issuer certificate
1199  * @param {String} subjectCert string of PEM subject certificate to be verified by OCSP
1200  * @param {String} algName hash algorithm name used for above arguments (ex. "sha1") DEFAULT: sha1
1201  * @return {String} hexadecimal string of generated OCSP request
1202  * @since jsrsasign 6.1.0 asn1ocsp 1.0.0
1203  * @description
1204  * This static method generates hexadecimal string of OCSP request.
1205  * @example
1206  * // generate OCSP request using sha1 algorithnm by default.
1207  * hReq = KJUR.asn1.ocsp.OCSPUtil.getRequestHex("-----BEGIN...", "-----BEGIN...");
1208  */
1209 KJUR.asn1.ocsp.OCSPUtil.getRequestHex = function(issuerCert, subjectCert, alg) {
1210     var _KJUR = KJUR,
1211 	_KJUR_asn1 = _KJUR.asn1,
1212 	_KJUR_asn1_ocsp = _KJUR_asn1.ocsp;
1213 
1214     if (alg === undefined) alg = _KJUR_asn1_ocsp.DEFAULT_HASH;
1215     var param = {alg: alg, issuerCert: issuerCert, subjectCert: subjectCert};
1216     var o = new _KJUR_asn1_ocsp.OCSPRequest({reqList: [param]});
1217     return o.getEncodedHex();
1218 };
1219 
1220 /**
1221  * parse OCSPResponse<br/>
1222  * @name getOCSPResponseInfo
1223  * @memberOf KJUR.asn1.ocsp.OCSPUtil
1224  * @function
1225  * @param {String} h hexadecimal string of DER OCSPResponse
1226  * @return {Object} JSON object of parsed OCSPResponse
1227  * @since jsrsasign 6.1.0 asn1ocsp 1.0.1
1228  * @description
1229  * This static method parse a hexadecimal string of DER OCSPResponse and
1230  * returns JSON object of its parsed result.
1231  * Its result has following properties:
1232  * <ul>
1233  * <li>responseStatus - integer of responseStatus</li>
1234  * <li>certStatus - string of certStatus (ex. good, revoked or unknown)</li>
1235  * <li>thisUpdate - string of thisUpdate in Zulu(ex. 20151231235959Z)</li>
1236  * <li>nextUpdate - string of nextUpdate in Zulu(ex. 20151231235959Z)</li>
1237  * </ul>
1238  * @example
1239  * info = KJUR.asn1.ocsp.OCSPUtil.getOCSPResponseInfo("3082...");
1240  */
1241 KJUR.asn1.ocsp.OCSPUtil.getOCSPResponseInfo = function(h) {
1242     var _ASN1HEX = ASN1HEX,
1243 	_getVbyList = _ASN1HEX.getVbyList,
1244 	_getVbyListEx = _ASN1HEX.getVbyListEx,
1245 	_getIdxbyList = _ASN1HEX.getIdxbyList,
1246 	_getIdxbyListEx = _ASN1HEX.getIdxbyListEx,
1247 	_getV = _ASN1HEX.getV;
1248 
1249     var result = {};
1250     try {
1251 	var v = _getVbyListEx(h, 0, [0], "0a");
1252 	result.responseStatus = parseInt(v, 16);
1253     } catch(ex) {};
1254     if (result.responseStatus !== 0) return result;
1255 
1256     try {
1257 	// certStatus
1258 	var idxCertStatus = _getIdxbyList(h, 0, [1,0,1,0,0,2,0,1]);
1259 	if (h.substr(idxCertStatus, 2) === "80") {
1260 	    result.certStatus = "good";
1261 	} else if (h.substr(idxCertStatus, 2) === "a1") {
1262 	    result.certStatus = "revoked";
1263 	    result.revocationTime = 
1264 		hextoutf8(_getVbyList(h, idxCertStatus, [0]));
1265 	} else if (h.substr(idxCertStatus, 2) === "82") {
1266 	    result.certStatus = "unknown";
1267 	}
1268     } catch (ex) {};
1269 
1270     // thisUpdate
1271     try {
1272 	var idxThisUpdate = _getIdxbyList(h, 0, [1,0,1,0,0,2,0,2]);
1273 	result.thisUpdate = hextoutf8(_getV(h, idxThisUpdate));
1274     } catch (ex) {};
1275 
1276     // nextUpdate
1277     try {
1278 	var idxEncapNextUpdate = _getIdxbyList(h, 0, [1,0,1,0,0,2,0,3]);
1279 	if (h.substr(idxEncapNextUpdate, 2) === "a0") {
1280 	    result.nextUpdate = 
1281 		hextoutf8(_getVbyList(h, idxEncapNextUpdate, [0]));
1282 	}
1283     } catch (ex) {};
1284 
1285     return result;
1286 };
1287 
1288 /**
1289  * OCSP request and response parser<br/>
1290  * @name KJUR.asn1.ocsp.OCSPParser
1291  * @class OCSP request and response parser
1292  * @since jsrsasign 9.1.6 asn1ocsp 1.1.0
1293  *
1294  * @description
1295  * This class provides ASN.1 parser for
1296  * OCSP related ASN.1 data.
1297  * Currntly only OCSP request parsers are
1298  * available.
1299  */
1300 KJUR.asn1.ocsp.OCSPParser = function() {
1301     var _Error = Error,
1302 	_X509 = X509,
1303 	_x509obj = new _X509(),
1304 	_ASN1HEX = ASN1HEX,
1305 	_getV = _ASN1HEX.getV,
1306 	_getTLV = _ASN1HEX.getTLV,
1307 	_getIdxbyList = _ASN1HEX.getIdxbyList,
1308 	_getTLVbyListEx = _ASN1HEX.getTLVbyListEx,
1309 	_getChildIdx = _ASN1HEX.getChildIdx;
1310 
1311     /**
1312      * parse ASN.1 OCSPRequest<br/>
1313      * @name getOCSPRequest
1314      * @memberOf KJUR.asn1.ocsp.OCSPParser#
1315      * @function
1316      * @param {String} h hexadecimal string of ASN.1 OCSPRequest
1317      * @return {Array} array of JSON object of OCSPRequest parameter
1318      * @since jsrsasign 9.1.6 asn1ocsp 1.1.0
1319      *
1320      * @description
1321      * <pre>
1322      * OCSPRequest ::= SEQUENCE {
1323      *   tbsRequest              TBSRequest,
1324      *   optionalSignature  [0]  EXPLICIT Signature OPTIONAL }
1325      * TBSRequest  ::=  SEQUENCE {
1326      *   version            [0]  EXPLICIT Version DEFAULT v1,
1327      *   requestorName      [1]  EXPLICIT GeneralName OPTIONAL,
1328      *   requestList             SEQUENCE OF Request,
1329      *   requestExtensions  [2]  EXPLICIT Extensions OPTIONAL }
1330      * </pre>
1331      *
1332      * @example
1333      * o = new KJUR.asn1.ocsp.OCSPParser();
1334      * o.getOCSPRequest("30...") →
1335      * { array: [{
1336      *    "alg": "sha1",
1337      *    "issname": "105fa67a80089db5279f35ce830b43889ea3c70d",
1338      *    "isskey": "0f80611c823161d52f28e78d4638b42ce1c6d9e2",
1339      *    "sbjsn": "0fef62075d715dc5e1d8bd03775c9686"
1340      * }]}
1341      */
1342     this.getOCSPRequest = function(h) {
1343 	var a = _getChildIdx(h, 0);
1344 
1345 	if (a.length != 1 && a.length != 2) {
1346 	    throw new _Error("wrong number elements: " + a.length);
1347 	}
1348 
1349 	var result = this.getTBSRequest(_getTLV(h, a[0]));
1350 	return result;
1351     };
1352 
1353     /**
1354      * parse ASN.1 TBSRequest of OCSP<br/>
1355      * @name getTBSRequest
1356      * @memberOf KJUR.asn1.ocsp.OCSPParser#
1357      * @function
1358      * @param {String} h hexadecimal string of ASN.1 TBSRequest of OCSP
1359      * @return {Array} array of JSON object of TBSRequest parameter
1360      * @since jsrsasign 9.1.6 asn1ocsp 1.1.0
1361      *
1362      * @description
1363      * <pre>
1364      * TBSRequest  ::=  SEQUENCE {
1365      *   version            [0]  EXPLICIT Version DEFAULT v1,
1366      *   requestorName      [1]  EXPLICIT GeneralName OPTIONAL,
1367      *   requestList             SEQUENCE OF Request,
1368      *   requestExtensions  [2]  EXPLICIT Extensions OPTIONAL }
1369      * </pre>
1370      *
1371      * @example
1372      * o = new KJUR.asn1.ocsp.OCSPParser();
1373      * o.getTBSRequest("30...") →
1374      * {array: [{
1375      *   "alg": "sha1",
1376      *   "issname": "105fa67a80089db5279f35ce830b43889ea3c70d",
1377      *   "isskey": "0f80611c823161d52f28e78d4638b42ce1c6d9e2",
1378      *   "sbjsn": "0fef62075d715dc5e1d8bd03775c9686"
1379      * }]}
1380      */
1381     this.getTBSRequest = function(h) {
1382 	var result = {};
1383 	var hReqList = _getTLVbyListEx(h, 0, [0], "30");
1384 	result.array = this.getRequestList(hReqList);
1385 	var hExt = _getTLVbyListEx(h, 0, ["[2]", 0], "30");
1386 	if (hExt != null) {
1387 	    result.ext = _x509obj.getExtParamArray(hExt);
1388 	}
1389 
1390 	return result;
1391     };
1392 
1393     /**
1394      * parse ASN.1 SEQUENCE OF Request in OCSP<br/>
1395      * @name getRequestList
1396      * @memberOf KJUR.asn1.ocsp.OCSPParser#
1397      * @function
1398      * @param {String} h hexadecimal string of ASN.1 SEQUENCE OF Request in OCSP
1399      * @return {Array} array of JSON object of Request parameter
1400      * @since jsrsasign 9.1.6 asn1ocsp 1.1.0
1401      *
1402      * @description
1403      * <pre>
1404      * TBSRequest  ::=  SEQUENCE {
1405      *   version            [0]  EXPLICIT Version DEFAULT v1,
1406      *   requestorName      [1]  EXPLICIT GeneralName OPTIONAL,
1407      *   requestList             SEQUENCE OF Request,
1408      *   requestExtensions  [2]  EXPLICIT Extensions OPTIONAL }
1409      * Request ::= SEQUENCE {
1410      *   reqCert                  CertID,
1411      *   singleRequestExtensions  [0] EXPLICIT Extensions OPTIONAL }      
1412      * </pre>
1413      *
1414      * @example
1415      * o = new KJUR.asn1.ocsp.OCSPParser();
1416      * o.getRequestList("30...") →
1417      * [{ alg: "sha1"
1418      *   issname: "...hex...",
1419      *   isskey: "...hex...",
1420      *   sbjsn: "...hex...",
1421      *   ext: [<<singleRequestExtension parameters>>...]
1422      * }]
1423      */
1424     this.getRequestList = function(h) {
1425 	var result = [];
1426 	var a = _getChildIdx(h, 0);
1427 	for (var i = 0; i < a.length; i++) {
1428 	    var h = _getTLV(h, a[i]);
1429 	    result.push(this.getRequest(h));
1430 	}
1431 	return result;
1432     };
1433 
1434     /**
1435      * parse ASN.1 Request of OCSP<br/>
1436      * @name getRequest
1437      * @memberOf KJUR.asn1.ocsp.OCSPParser#
1438      * @function
1439      * @param {String} h hexadecimal string of ASN.1 Request of OCSP
1440      * @return JSON object of Request parameter
1441      * @since jsrsasign 9.1.6 asn1ocsp 1.1.0
1442      *
1443      * @description
1444      * <pre>
1445      * Request ::= SEQUENCE {
1446      *   reqCert                  CertID,
1447      *   singleRequestExtensions  [0] EXPLICIT Extensions OPTIONAL }      
1448      * </pre>
1449      *
1450      * @example
1451      * o = new KJUR.asn1.ocsp.OCSPParser();
1452      * o.getRequest("30...") →
1453      * { alg: "sha1"
1454      *   issname: "...hex...",
1455      *   isskey: "...hex...",
1456      *   sbjsn: "...hex...",
1457      *   ext: [<<singleRequestExtension parameters>>...]
1458      * }
1459      */
1460     this.getRequest = function(h) {
1461 	var a = _getChildIdx(h, 0);
1462 	if (a.length != 1 && a.length != 2) {
1463 	    throw new _Error("wrong number elements: " + a.length);
1464 	}
1465 	
1466 	var params = this.getCertID(_getTLV(h, a[0]));
1467 
1468 	if (a.length == 2) {
1469 	    var idxExt = _getIdxbyList(h, 0, [1, 0]);
1470 	    params.ext = _x509obj.getExtParamArray(_getTLV(h, idxExt));
1471 	}
1472 
1473 	return params;
1474     };
1475 
1476     /**
1477      * parse ASN.1 CertID of OCSP<br/>
1478      * @name getCertID
1479      * @memberOf KJUR.asn1.ocsp.OCSPParser#
1480      * @function
1481      * @param {String} h hexadecimal string of CertID
1482      * @return JSON object of CertID parameter
1483      * @since jsrsasign 9.1.6 asn1ocsp 1.1.0
1484      * @see KJUR.asn1.ocsp.CertID
1485      *
1486      * @description
1487      * <pre>
1488      * CertID ::= SEQUENCE {
1489      *   hashAlgorithm   AlgorithmIdentifier,
1490      *   issuerNameHash  OCTET STRING, -- Hash of issuer's DN
1491      *   issuerKeyHash   OCTET STRING, -- Hash of issuer's public key
1492      *   serialNumber    CertificateSerialNumber }
1493      * </pre>
1494      *
1495      * @example
1496      * o = new KJUR.asn1.ocsp.OCSPParser();
1497      * o.getCertID("30...") →
1498      * { alg: "sha1"
1499      *   issname: "...hex...",
1500      *   isskey: "...hex...",
1501      *   sbjsn: "...hex..." }
1502      */
1503     this.getCertID = function(h) {
1504 	var a = _getChildIdx(h, 0);
1505 	if (a.length != 4) {
1506 	    throw new _Error("wrong number elements: " + a.length);
1507 	}
1508 	
1509 	var x = new _X509();
1510 	var result = {};
1511 	result.alg = x.getAlgorithmIdentifierName(_getTLV(h, a[0]));
1512 	result.issname = _getV(h, a[1]);
1513 	result.isskey = _getV(h, a[2]);
1514 	result.sbjsn = _getV(h, a[3]);
1515 	
1516 	return result;
1517     };
1518 };
1519 
1520