1 /*! asn1csr-1.0.0.js (c) 2015 Kenji Urushima | kjur.github.com/jsrsasign/license
  2  */
  3 /*
  4  * asn1csr.js - ASN.1 DER encoder classes for PKCS#10 CSR
  5  *
  6  * Copyright (c) 2015 Kenji Urushima (kenji.urushima@gmail.com)
  7  *
  8  * This software is licensed under the terms of the MIT License.
  9  * http://kjur.github.com/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 asn1csr-1.0.js
 18  * @author Kenji Urushima kenji.urushima@gmail.com
 19  * @version 1.0.0 (2015-Sep-12)
 20  * @since jsrsasign 4.8.7
 21  * @license <a href="http://kjur.github.io/jsrsasign/license/">MIT License</a>
 22  */
 23 
 24 /**
 25  * kjur's ASN.1 class for CSR/PKCS#10 name space
 26  * <p>
 27  * This name space is a sub name space for {@link KJUR.asn1}.
 28  * This name space contains classes for
 29  * <a href="https://tools.ietf.org/html/rfc2986">RFC 2986</a>
 30  * certificate signing request(CSR/PKCS#10) and its utilities
 31  * to be issued your certificate from certification authorities.
 32  * <h4>PROVIDING ASN.1 STRUCTURES</h4>
 33  * <ul>
 34  * <li>{@link KJUR.asn1.csr.CertificationRequest}</li>
 35  * <li>{@link KJUR.asn1.csr.CertificationRequestInfo}</li>
 36  * </ul>
 37  * <h4>PROVIDING UTILITY CLASSES</h4>
 38  * <ul>
 39  * <li>{@link KJUR.asn1.csr.CSRUtil}</li>
 40  * </ul>
 41  * {@link KJUR.asn1.csr.CSRUtil.newCSRPEM} method is very useful to
 42  * get your certificate signing request (CSR/PKCS#10) file.
 43  * </p>
 44  * @name KJUR.asn1.csr
 45  * @namespace
 46  */
 47 if (typeof KJUR.asn1.csr == "undefined" || !KJUR.asn1.csr) KJUR.asn1.csr = {};
 48 
 49 /**
 50  * ASN.1 CertificationRequest structure class
 51  * @name KJUR.asn1.csr.CertificationRequest
 52  * @class ASN.1 CertificationRequest structure class
 53  * @param {Array} params associative array of parameters (ex. {})
 54  * @extends KJUR.asn1.ASN1Object
 55  * @since jsrsasign 4.8.7 asn1csr 1.0.0
 56  * @description
 57  * <br/>
 58  * @example
 59  * csri = new KJUR.asn1.csr.CertificationRequestInfo();
 60  * csri.setSubjectByParam({'str': '/C=US/O=Test/CN=example.com'});
 61  * csri.setSubjectPublicKeyByGetKey(pubKeyObj);
 62  * csr = new KJUR.asn1.csr.CertificationRequest({'csrinfo': csri});
 63  * csr.sign("SHA256withRSA", prvKeyObj);
 64  * pem = csr.getPEMString();
 65  * 
 66  * // -- DEFINITION OF ASN.1 SYNTAX --
 67  * // CertificationRequest ::= SEQUENCE {
 68  * //   certificationRequestInfo CertificationRequestInfo,
 69  * //   signatureAlgorithm       AlgorithmIdentifier{{ SignatureAlgorithms }},
 70  * //   signature                BIT STRING }
 71  */
 72 KJUR.asn1.csr.CertificationRequest = function(params) {
 73     KJUR.asn1.csr.CertificationRequest.superclass.constructor.call(this);
 74     var asn1CSRInfo = null;
 75     var asn1SignatureAlg = null;
 76     var asn1Sig = null;
 77     var hexSig = null;
 78     var prvKey = null;
 79 
 80     /**
 81      * sign CertificationRequest and set signature value internally
 82      * @name sign
 83      * @memberOf KJUR.asn1.csr.CertificationRequest
 84      * @function
 85      * @description
 86      * This method self-signs CertificateRequestInfo with a subject's
 87      * private key and set signature value internally.
 88      * <br/>
 89      * @example
 90      * csr = new KJUR.asn1.csr.CertificationRequest({'csrinfo': csri});
 91      * csr.sign("SHA256withRSA", prvKeyObj);
 92      */
 93     this.sign = function(sigAlgName, prvKeyObj) {
 94 	if (this.prvKey == null) this.prvKey = prvKeyObj;
 95 
 96 	this.asn1SignatureAlg = 
 97 	    new KJUR.asn1.x509.AlgorithmIdentifier({'name': sigAlgName});
 98 
 99         sig = new KJUR.crypto.Signature({'alg': sigAlgName});
100         sig.initSign(this.prvKey);
101         sig.updateHex(this.asn1CSRInfo.getEncodedHex());
102         this.hexSig = sig.sign();
103 
104         this.asn1Sig = new KJUR.asn1.DERBitString({'hex': '00' + this.hexSig});
105         var seq = new KJUR.asn1.DERSequence({'array': [this.asn1CSRInfo,
106                                                        this.asn1SignatureAlg,
107                                                        this.asn1Sig]});
108         this.hTLV = seq.getEncodedHex();
109         this.isModified = false;
110     };
111 
112     /**
113      * get PEM formatted certificate signing request (CSR/PKCS#10)
114      * @name getPEMString
115      * @memberOf KJUR.asn1.csr.CertificationRequest
116      * @function
117      * @return PEM formatted string of CSR/PKCS#10
118      * @description
119      * This method is to a get CSR PEM string after signed.
120      * <br/>
121      * @example
122      * csr = new KJUR.asn1.csr.CertificationRequest({'csrinfo': csri});
123      * csr.sign();
124      * pem =  csr.getPEMString();
125      * // pem will be following:
126      * // -----BEGIN CERTIFICATE REQUEST-----
127      * // MII ...snip...
128      * // -----END CERTIFICATE REQUEST-----
129      */
130     this.getPEMString = function() {
131 	var pem = KJUR.asn1.ASN1Util.getPEMStringFromHex(this.getEncodedHex(),
132 							 "CERTIFICATE REQUEST");
133 	return pem;
134     };
135 
136     this.getEncodedHex = function() {
137         if (this.isModified == false && this.hTLV != null) return this.hTLV;
138         throw "not signed yet";
139     };
140 
141     if (typeof params != "undefined") {
142         if (typeof params['csrinfo'] != "undefined") {
143             this.asn1CSRInfo = params['csrinfo'];
144         }
145     }
146 };
147 YAHOO.lang.extend(KJUR.asn1.csr.CertificationRequest, KJUR.asn1.ASN1Object);
148 
149 /**
150  * ASN.1 CertificationRequestInfo structure class
151  * @name KJUR.asn1.csr.CertificationRequestInfo
152  * @class ASN.1 CertificationRequestInfo structure class
153  * @param {Array} params associative array of parameters (ex. {})
154  * @extends KJUR.asn1.ASN1Object
155  * @since jsrsasign 4.8.7 asn1csr 1.0.0
156  * @description
157  * <br/>
158  * @example
159  * csri = new KJUR.asn1.csr.CertificationRequestInfo();
160  * csri.setSubjectByParam({'str': '/C=US/O=Test/CN=example.com'});
161  * csri.setSubjectPublicKeyByGetKey(pubKeyObj);
162  *
163  * // -- DEFINITION OF ASN.1 SYNTAX --
164  * // CertificationRequestInfo ::= SEQUENCE {
165  * //   version       INTEGER { v1(0) } (v1,...),
166  * //   subject       Name,
167  * //   subjectPKInfo SubjectPublicKeyInfo{{ PKInfoAlgorithms }},
168  * //   attributes    [0] Attributes{{ CRIAttributes }} }
169  *
170  */
171 KJUR.asn1.csr.CertificationRequestInfo = function(params) {
172     KJUR.asn1.csr.CertificationRequestInfo.superclass.constructor.call(this);
173 
174     this._initialize = function() {
175         this.asn1Array = new Array();
176 
177 	this.asn1Version = new KJUR.asn1.DERInteger({'int': 0});
178 	this.asn1Subject = null;
179 	this.asn1SubjPKey = null;
180 	this.extensionsArray = new Array();
181     };
182 
183     /**
184      * set subject name field by parameter
185      * @name setSubjectByParam
186      * @memberOf KJUR.asn1.csr.CertificationRequestInfo
187      * @function
188      * @param {Array} x500NameParam X500Name parameter
189      * @description
190      * @example
191      * csri.setSubjectByParam({'str': '/C=US/CN=b'});
192      * @see KJUR.asn1.x509.X500Name
193      */
194     this.setSubjectByParam = function(x500NameParam) {
195         this.asn1Subject = new KJUR.asn1.x509.X500Name(x500NameParam);
196     };
197 
198     /**
199      * set subject public key info by RSA/ECDSA/DSA key parameter
200      * @name setSubjectPublicKeyByGetKey
201      * @memberOf KJUR.asn1.csr.CertificationRequestInfo
202      * @function
203      * @param {Object} keyParam public key parameter which passed to {@link KEYUTIL.getKey} argument
204      * @description
205      * @example
206      * csri.setSubjectPublicKeyByGetKeyParam(certPEMString); // or 
207      * csri.setSubjectPublicKeyByGetKeyParam(pkcs8PublicKeyPEMString); // or 
208      * csir.setSubjectPublicKeyByGetKeyParam(kjurCryptoECDSAKeyObject); // et.al.
209      * @see KJUR.asn1.x509.SubjectPublicKeyInfo
210      * @see KEYUTIL.getKey
211      */
212     this.setSubjectPublicKeyByGetKey = function(keyParam) {
213         var keyObj = KEYUTIL.getKey(keyParam);
214         this.asn1SubjPKey = new KJUR.asn1.x509.SubjectPublicKeyInfo(keyObj);
215     };
216 
217     this.getEncodedHex = function() {
218         this.asn1Array = new Array();
219 
220         this.asn1Array.push(this.asn1Version);
221         this.asn1Array.push(this.asn1Subject);
222         this.asn1Array.push(this.asn1SubjPKey);
223 
224         var extSeq = new KJUR.asn1.DERSequence({"array": this.extensionsArray});
225         var extTagObj = new KJUR.asn1.DERTaggedObject({'explicit': false,
226                                                        'tag': 'a0',
227                                                        'obj': extSeq});
228         this.asn1Array.push(extTagObj);
229 
230         var o = new KJUR.asn1.DERSequence({"array": this.asn1Array});
231         this.hTLV = o.getEncodedHex();
232         this.isModified = false;
233         return this.hTLV;
234     };
235 
236     this._initialize();
237 };
238 YAHOO.lang.extend(KJUR.asn1.csr.CertificationRequestInfo, KJUR.asn1.ASN1Object);
239 
240 /**
241  * Certification Request (CSR/PKCS#10) utilities class
242  * @name KJUR.asn1.csr.CSRUtil
243  * @class Certification Request (CSR/PKCS#10) utilities class
244  */
245 KJUR.asn1.csr.CSRUtil = new function() {
246 };
247 
248 /**
249  * generate a PEM format of CSR/PKCS#10 certificate signing request
250  * @name newCSRPEM
251  * @memberOf KJUR.asn1.csr.CSRUtil
252  * @function
253  * @param {Array} param parameter to generate CSR
254  * @since jsrsasign 4.8.7 asn1csr 1.0.0
255  * @description
256  * This method can generate a CSR certificate signing
257  * request by a simple JSON object which has following parameters:
258  * <ul>
259  * <li>subject - parameter to be passed to {@link KJUR.asn1.x509.X500Name}</li>
260  * <li>sbjpubkey - parameter to be passed to {@link KEYUTIL.getKey}</li>
261  * <li>sigalg - signature algorithm name (ex. SHA256withRSA)</li>
262  * <li>sbjprvkey - parameter to be passed to {@link KEYUTIL.getKey}</li>
263  * </ul>
264  *
265  * @example
266  * // 1) by key object
267  * pem = KJUR.asn1.csr.CSRUtil.newCSRPEM({
268  *   subject: {str: '/C=US/O=Test/CN=example.com'},
269  *   sbjpubkey: pubKeyObj,
270  *   sigalg: "SHA256withRSA",
271  *   sbjprvkey: prvKeyObj
272  * });
273  *
274  * // 2) by private/public key PEM 
275  * pem = KJUR.asn1.csr.CSRUtil.newCSRPEM({
276  *   subject: {str: '/C=US/O=Test/CN=example.com'},
277  *   sbjpubkey: pubKeyPEM,
278  *   sigalg: "SHA256withRSA",
279  *   sbjprvkey: prvKeyPEM
280  * });
281  *
282  * // 3) with generateKeypair
283  * kp = KEYUTIL.generateKeypair("RSA", 2048);
284  * pem = KJUR.asn1.csr.CSRUtil.newCSRPEM({
285  *   subject: {str: '/C=US/O=Test/CN=example.com'},
286  *   sbjpubkey: kp.pubKeyObj,
287  *   sigalg: "SHA256withRSA",
288  *   sbjprvkey: kp.prvKeyObj
289  * });
290  */
291 KJUR.asn1.csr.CSRUtil.newCSRPEM = function(param) {
292     var ns1 = KJUR.asn1.csr;
293 
294     if (param.subject === undefined) throw "parameter subject undefined";
295     if (param.sbjpubkey === undefined) throw "parameter sbjpubkey undefined";
296     if (param.sigalg === undefined) throw "parameter sigalg undefined";
297     if (param.sbjprvkey === undefined) throw "parameter sbjpubkey undefined";
298 
299     var csri = new ns1.CertificationRequestInfo();
300     csri.setSubjectByParam(param.subject);
301     csri.setSubjectPublicKeyByGetKey(param.sbjpubkey);
302 
303     var csr = new ns1.CertificationRequest({'csrinfo': csri});
304     var prvKey = KEYUTIL.getKey(param.sbjprvkey);
305     csr.sign(param.sigalg, prvKey);
306 
307     var pem = csr.getPEMString();
308     return pem;
309 };
310 
311