/*! asn1cades-1.0.0.js (c) 2013-2014 Kenji Urushima | kjur.github.com/jsrsasign/license */ /* * asn1cades.js - ASN.1 DER encoder classes for RFC 5126 CAdES long term signature * * Copyright (c) 2014 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. */ /** * @fileOverview * @name asn1cades-1.0.js * @author Kenji Urushima kenji.urushima@gmail.com * @version 1.0.0 (2014-May-28) * @since jsrsasign 4.7.0 * @license MIT License */ /** * kjur's class library name space * // already documented in asn1-1.0.js * @name KJUR * @namespace kjur's class library name space */ if (typeof KJUR == "undefined" || !KJUR) KJUR = {}; /** * kjur's ASN.1 class library name space * // already documented in asn1-1.0.js * @name KJUR.asn1 * @namespace */ if (typeof KJUR.asn1 == "undefined" || !KJUR.asn1) KJUR.asn1 = {}; /** * kjur's ASN.1 class for RFC 5126 CAdES long term signature *
* This name space provides * RFC 5126 * CAdES(CMS Advanced Electronic Signature) generator. * *
* sd = KJUR.asn1.cms.CMSUtil.newSignedData({ * content: {str: "aaa"}, * certs: [certPEM], * signerInfos: [{ * hashAlg: 'sha256', * sAttr: {SigningCertificateV2: {array: [certPEM]}}, * signerCert: certPEM, * sigAlg: 'SHA256withRSA', * signerPrvKey: pkcs8PrvKeyPEM * }] * }); * signedDataHex = sd.getContentInfoEncodedHex(); ** NOTE: ContentType and MessageDigest signed attributes * are automatically added by default. * *
* sd = KJUR.asn1.cms.CMSUtil.newSignedData({ * content: {str: "aaa"}, * certs: [certPEM1, certPEM2], * signerInfos: [{ * hashAlg: 'sha256', * sAttr: {SigningCertificateV2: {array: [certPEM1]}}, * signerCert: certPEM1, * sigAlg: 'SHA256withRSA', * signerPrvKey: pkcs8PrvKeyPEM1 * },{ * hashAlg: 'sha1', * sAttr: {SigningCertificateV2: {array: [certPEM2]}}, * signerCert: certPEM2, * sigAlg: 'SHA1withRSA', * signerPrvKey: pkcs8PrvKeyPEM2 * }] * }); * signedDataHex = sd.getContentInfoEncodedHex(); ** *
* sd = KJUR.asn1.cms.CMSUtil.newSignedData({ * content: {str: "aaa"}, * certs: [certPEM], * signerInfos: [{ * hashAlg: 'sha256', * sAttr: { * SigningCertificateV2: {array: [certPEM]}, * SignaturePolicyIdentifier: { * oid: '1.2.3.4.5', * hash: {alg: 'sha1', hash: 'b1b2b3b4b...'} * }, * }, * signerCert: certPEM, * sigAlg: 'SHA256withRSA', * signerPrvKey: pkcs8PrvKeyPEM * }] * }); * signedDataHex = sd.getContentInfoEncodedHex(); ** *
* beshex = "30..."; // hex of CAdES-BES or EPES data * info = KJUR.asn1.cades.CAdESUtil.parseSignedDataForAddingUnsigned(beshex); * // You can refer a hexadecimal string of signature value * // in the first signerInfo in the CAdES-BES/EPES with a variable: * // 'info.si[0].sigval'. You need to get RFC 3161 TimeStampToken * // from a trusted time stamp authority. Otherwise you can also * // get it by 'KJUR.asn1.tsp' module. We suppose that we could * // get proper time stamp. * tsthex0 = "30..."; // hex of TimeStampToken for signerInfo[0] sigval * si0 = info.obj.signerInfoList[0]; * si0.addUnsigned(new KJUR.asn1.cades.SignatureTimeStamp({tst: tsthex0}); * esthex = info.obj.getContentInfoEncodedHex(); // CAdES-T ** * *
* SignaturePolicyIdentifier ::= CHOICE { * signaturePolicyId SignaturePolicyId, * signaturePolicyImplied SignaturePolicyImplied } -- not used * * SignaturePolicyImplied ::= NULL * SignaturePolicyId ::= SEQUENCE { * sigPolicyId SigPolicyId, * sigPolicyHash SigPolicyHash, * sigPolicyQualifiers SEQUENCE SIZE (1..MAX) OF * SigPolicyQualifierInfo OPTIONAL } * SigPolicyId ::= OBJECT IDENTIFIER * SigPolicyHash ::= OtherHashAlgAndValue ** @example * var o = new KJUR.asn1.cades.SignaturePolicyIdentifier({ * oid: '1.2.3.4.5', * hash: {alg: 'sha1', hash: 'a1a2a3a4...'} * }); */ /* * id-aa-ets-sigPolicyId OBJECT IDENTIFIER ::= { iso(1) * member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs9(9) * smime(16) id-aa(2) 15 } * * signature-policy-identifier attribute values have ASN.1 type * SignaturePolicyIdentifier: * * SigPolicyQualifierInfo ::= SEQUENCE { * sigPolicyQualifierId SigPolicyQualifierId, * sigQualifier ANY DEFINED BY sigPolicyQualifierId } * * sigpolicyQualifierIds defined in the present document: * SigPolicyQualifierId ::= OBJECT IDENTIFIER * id-spq-ets-uri OBJECT IDENTIFIER ::= { iso(1) * member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs9(9) * smime(16) id-spq(5) 1 } * * SPuri ::= IA5String * * id-spq-ets-unotice OBJECT IDENTIFIER ::= { iso(1) * member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs9(9) * smime(16) id-spq(5) 2 } * * SPUserNotice ::= SEQUENCE { * noticeRef NoticeReference OPTIONAL, * explicitText DisplayText OPTIONAL} * * NoticeReference ::= SEQUENCE { * organization DisplayText, * noticeNumbers SEQUENCE OF INTEGER } * * DisplayText ::= CHOICE { * visibleString VisibleString (SIZE (1..200)), * bmpString BMPString (SIZE (1..200)), * utf8String UTF8String (SIZE (1..200)) } */ KJUR.asn1.cades.SignaturePolicyIdentifier = function(params) { KJUR.asn1.cades.SignaturePolicyIdentifier.superclass.constructor.call(this); this.attrTypeOid = "1.2.840.113549.1.9.16.2.15"; var nA = KJUR.asn1; var nC = KJUR.asn1.cades; if (typeof params != "undefined") { if (typeof params.oid == "string" && typeof params.hash == "object") { var dOid = new nA.DERObjectIdentifier({oid: params.oid}); var dHash = new nC.OtherHashAlgAndValue(params.hash); var seq = new nA.DERSequence({array: [dOid, dHash]}); this.valueList = [seq]; } } }; YAHOO.lang.extend(KJUR.asn1.cades.SignaturePolicyIdentifier, KJUR.asn1.cms.Attribute); /** * class for OtherHashAlgAndValue ASN.1 object * @name KJUR.asn1.cades.OtherHashAlgAndValue * @class class for OtherHashAlgAndValue ASN.1 object * @param {Array} params associative array of parameters * @extends KJUR.asn1.ASN1Object * @since jsrsasign 4.7.0 asn1cades 1.0.0 * @description *
* OtherHashAlgAndValue ::= SEQUENCE { * hashAlgorithm AlgorithmIdentifier, * hashValue OtherHashValue } * OtherHashValue ::= OCTET STRING **/ KJUR.asn1.cades.OtherHashAlgAndValue = function(params) { KJUR.asn1.cades.OtherHashAlgAndValue.superclass.constructor.call(this); var nA = KJUR.asn1; var nX = KJUR.asn1.x509; this.dAlg = null; this.dHash = null; this.getEncodedHex = function() { var seq = new nA.DERSequence({array: [this.dAlg, this.dHash]}); this.hTLV = seq.getEncodedHex(); return this.hTLV; }; if (typeof params != "undefined") { if (typeof params.alg == "string" && typeof params.hash == "string") { this.dAlg = new nX.AlgorithmIdentifier({name: params.alg}); this.dHash = new nA.DEROctetString({hex: params.hash}); } } }; YAHOO.lang.extend(KJUR.asn1.cades.OtherHashAlgAndValue, KJUR.asn1.ASN1Object); /** * class for RFC 5126 CAdES SignatureTimeStamp attribute * @name KJUR.asn1.cades.SignatureTimeStamp * @class class for RFC 5126 CAdES SignatureTimeStamp attribute * @param {Array} params associative array of parameters * @extends KJUR.asn1.cms.Attribute * @since jsrsasign 4.7.0 asn1cades 1.0.0 * @description *
* id-aa-signatureTimeStampToken OBJECT IDENTIFIER ::= * 1.2.840.113549.1.9.16.2.14 * SignatureTimeStampToken ::= TimeStampToken **/ KJUR.asn1.cades.SignatureTimeStamp = function(params) { KJUR.asn1.cades.SignatureTimeStamp.superclass.constructor.call(this); this.attrTypeOid = "1.2.840.113549.1.9.16.2.14"; this.tstHex = null; var nA = KJUR.asn1; if (typeof params != "undefined") { if (typeof params.res != "undefined") { if (typeof params.res == "string" && params.res.match(/^[0-9A-Fa-f]+$/)) { } else if (params.res instanceof KJUR.asn1.ASN1Object) { } else { throw "res param shall be ASN1Object or hex string"; } } if (typeof params.tst != "undefined") { if (typeof params.tst == "string" && params.tst.match(/^[0-9A-Fa-f]+$/)) { var d = new nA.ASN1Object(); this.tstHex = params.tst; d.hTLV = this.tstHex; d.getEncodedHex(); this.valueList = [d]; } else if (params.tst instanceof KJUR.asn1.ASN1Object) { } else { throw "tst param shall be ASN1Object or hex string"; } } } }; YAHOO.lang.extend(KJUR.asn1.cades.SignatureTimeStamp, KJUR.asn1.cms.Attribute); /** * class for RFC 5126 CAdES CompleteCertificateRefs attribute * @name KJUR.asn1.cades.CompleteCertificateRefs * @class class for RFC 5126 CAdES CompleteCertificateRefs attribute * @param {Array} params associative array of parameters * @extends KJUR.asn1.cms.Attribute * @since jsrsasign 4.7.0 asn1cades 1.0.0 * @description *
* id-aa-ets-certificateRefs OBJECT IDENTIFIER = * 1.2.840.113549.1.9.16.2.21 * CompleteCertificateRefs ::= SEQUENCE OF OtherCertID ** @example * o = new KJUR.asn1.cades.CompleteCertificateRefs([certPEM1,certPEM2]); */ KJUR.asn1.cades.CompleteCertificateRefs = function(params) { KJUR.asn1.cades.CompleteCertificateRefs.superclass.constructor.call(this); this.attrTypeOid = "1.2.840.113549.1.9.16.2.21"; var nA = KJUR.asn1; var nD = KJUR.asn1.cades; /** * set value by array * @name setByArray * @memberOf KJUR.asn1.cades.CompleteCertificateRefs * @function * @param {Array} a array of {@link KJUR.asn1.cades.OtherCertID} argument * @return unspecified * @description */ this.setByArray = function(a) { this.valueList = []; for (var i = 0; i < a.length; i++) { var o = new nD.OtherCertID(a[i]); this.valueList.push(o); } }; if (typeof params != "undefined") { if (typeof params == "object" && typeof params.length == "number") { this.setByArray(params); } } }; YAHOO.lang.extend(KJUR.asn1.cades.CompleteCertificateRefs, KJUR.asn1.cms.Attribute); /** * class for OtherCertID ASN.1 object * @name KJUR.asn1.cades.OtherCertID * @class class for OtherCertID ASN.1 object * @param {Array} params associative array of parameters * @extends KJUR.asn1.ASN1Object * @since jsrsasign 4.7.0 asn1cades 1.0.0 * @description *
* OtherCertID ::= SEQUENCE { * otherCertHash OtherHash, * issuerSerial IssuerSerial OPTIONAL } ** @example * o = new KJUR.asn1.cades.OtherCertID(certPEM); * o = new KJUR.asn1.cades.OtherCertID({cert:certPEM, hasis: false}); */ KJUR.asn1.cades.OtherCertID = function(params) { KJUR.asn1.cades.OtherCertID.superclass.constructor.call(this); var nA = KJUR.asn1; var nC = KJUR.asn1.cms; var nD = KJUR.asn1.cades; this.hasIssuerSerial = true; this.dOtherCertHash = null; this.dIssuerSerial = null; /** * set value by PEM string of certificate * @name setByCertPEM * @memberOf KJUR.asn1.cades.OtherCertID * @function * @param {String} certPEM PEM string of certificate * @return unspecified * @description * This method will set value by a PEM string of a certificate. * This will add IssuerAndSerialNumber by default * which depends on hasIssuerSerial flag. */ this.setByCertPEM = function(certPEM) { this.dOtherCertHash = new nD.OtherHash(certPEM); if (this.hasIssuerSerial) this.dIssuerSerial = new nC.IssuerAndSerialNumber(certPEM); }; this.getEncodedHex = function() { if (this.hTLV != null) return this.hTLV; if (this.dOtherCertHash == null) throw "otherCertHash not set"; var a = [this.dOtherCertHash]; if (this.dIssuerSerial != null) a.push(this.dIssuerSerial); var seq = new nA.DERSequence({array: a}); this.hTLV = seq.getEncodedHex(); return this.hTLV; }; if (typeof params != "undefined") { if (typeof params == "string" && params.indexOf("-----BEGIN ") != -1) { this.setByCertPEM(params); } if (typeof params == "object") { if (params.hasis === false) this.hasIssuerSerial = false; if (typeof params.cert == "string") this.setByCertPEM(params.cert); } } }; YAHOO.lang.extend(KJUR.asn1.cades.OtherCertID, KJUR.asn1.ASN1Object); /** * class for OtherHash ASN.1 object * @name KJUR.asn1.cades.OtherHash * @class class for OtherHash ASN.1 object * @param {Array} params associative array of parameters * @extends KJUR.asn1.ASN1Object * @since jsrsasign 4.7.0 asn1cades 1.0.0 * @description *
* OtherHash ::= CHOICE { * sha1Hash OtherHashValue, -- This contains a SHA-1 hash * otherHash OtherHashAlgAndValue} * OtherHashValue ::= OCTET STRING ** @example * o = new KJUR.asn1.cades.OtherHash("1234"); * o = new KJUR.asn1.cades.OtherHash(certPEMStr); // default alg=sha256 * o = new KJUR.asn1.cades.OtherHash({alg: 'sha256', hash: '1234'}); * o = new KJUR.asn1.cades.OtherHash({alg: 'sha256', cert: certPEM}); * o = new KJUR.asn1.cades.OtherHash({cert: certPEM}); */ KJUR.asn1.cades.OtherHash = function(params) { KJUR.asn1.cades.OtherHash.superclass.constructor.call(this); var nA = KJUR.asn1; var nD = KJUR.asn1.cades; this.alg = 'sha256'; this.dOtherHash = null; /** * set value by PEM string of certificate * @name setByCertPEM * @memberOf KJUR.asn1.cades.OtherHash * @function * @param {String} certPEM PEM string of certificate * @return unspecified * @description * This method will set value by a PEM string of a certificate. * An algorithm used to hash certificate data will * be defined by 'alg' property and 'sha256' is default. */ this.setByCertPEM = function(certPEM) { if (certPEM.indexOf("-----BEGIN ") == -1) throw "certPEM not to seem PEM format"; var hex = X509.pemToHex(certPEM); var hash = KJUR.crypto.Util.hashHex(hex, this.alg); this.dOtherHash = new nD.OtherHashAlgAndValue({alg: this.alg, hash: hash}); }; this.getEncodedHex = function() { if (this.dOtherHash == null) throw "OtherHash not set"; return this.dOtherHash.getEncodedHex(); }; if (typeof params != "undefined") { if (typeof params == "string") { if (params.indexOf("-----BEGIN ") != -1) { this.setByCertPEM(params); } else if (params.match(/^[0-9A-Fa-f]+$/)) { this.dOtherHash = new nA.DEROctetString({hex: params}); } else { throw "unsupported string value for params"; } } else if (typeof params == "object") { if (typeof params.cert == "string") { if (typeof params.alg == "string") this.alg = params.alg; this.setByCertPEM(params.cert); } else { this.dOtherHash = new nD.OtherHashAlgAndValue(params); } } } }; YAHOO.lang.extend(KJUR.asn1.cades.OtherHash, KJUR.asn1.ASN1Object); // == BEGIN UTILITIES ===================================================== /** * CAdES utiliteis class * @name KJUR.asn1.cades.CAdESUtil * @class CAdES utilities class * @since jsrsasign 4.7.0 asn1cades 1.0.0 */ KJUR.asn1.cades.CAdESUtil = new function() { }; /* * */ KJUR.asn1.cades.CAdESUtil.addSigTS = function(dCMS, siIdx, sigTSHex) { }; /** * parse CMS SignedData to add unsigned attributes * @name parseSignedDataForAddingUnsigned * @memberOf KJUR.asn1.cades.CAdESUtil * @function * @param {String} hex hexadecimal string of ContentInfo of CMS SignedData * @return {Object} associative array of parsed data * @description * This method will parse a hexadecimal string of * ContentInfo with CMS SignedData to add a attribute * to unsigned attributes field in a signerInfo field. * Parsed result will be an associative array which has * following properties: *