/*! 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. * *

SUPPORTED FORMATS

* Following CAdES formats is supported by this library. * *

* *

PROVIDED ATTRIBUTE CLASSES

* * NOTE: Currntly CAdES-C is not supported since parser can't * handle unsigned attribute. * *

OTHER CLASSES

* * *

GENERATE CAdES-BES

* To generate CAdES-BES, {@link KJUR.asn.cades} namespace * classes are not required and already {@link KJUR.asn.cms} namespace * provides attributes for CAdES-BES. * Create {@link KJUR.asn1.cms.SignedData} with following * mandatory attribute in CAdES-BES: * * CMSUtil.newSignedData method is very useful to generate CAdES-BES. *
 * 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. * *

GENERATE CAdES-BES with multiple signers

* If you need signature by multiple signers, you can * specify one or more items in 'signerInfos' property as below. *
 * 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();
 * 
* *

GENERATE CAdES-EPES

* When you need a CAdES-EPES signature, * you just need to add 'SignaturePolicyIdentifier' * attribute as below. *
 * 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();
 * 
* *

GENERATE CAdES-T

* After a signed CAdES-BES or CAdES-EPES signature have been generated, * you can generate CAdES-T by adding SigningTimeStamp unsigned attribute. *
 * 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
 * 
*

* *

SAMPLE CODES

* * * @name KJUR.asn1.cades * @namespace */ if (typeof KJUR.asn1.cades == "undefined" || !KJUR.asn1.cades) KJUR.asn1.cades = {}; /** * class for RFC 5126 CAdES SignaturePolicyIdentifier attribute * @name KJUR.asn1.cades.SignaturePolicyIdentifier * @class class for RFC 5126 CAdES SignaturePolicyIdentifier attribute * @param {Array} params associative array of parameters * @extends KJUR.asn1.cms.Attribute * @since jsrsasign 4.7.0 asn1cades 1.0.0 * @description *
 * 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: * * @example * info = KJUR.asn1.cades.CAdESUtil.parseSignedDataForAddingUnsigned(beshex); * sd = info.obj; */ KJUR.asn1.cades.CAdESUtil.parseSignedDataForAddingUnsigned = function(hex) { var nA = KJUR.asn1; var nC = KJUR.asn1.cms; var nU = KJUR.asn1.cades.CAdESUtil; var r = {}; // 1. not oid signed-data then error if (ASN1HEX.getDecendantHexTLVByNthList(hex, 0, [0]) != "06092a864886f70d010702") throw "hex is not CMS SignedData"; var iSD = ASN1HEX.getDecendantIndexByNthList(hex, 0, [1, 0]); var aSDChildIdx = ASN1HEX.getPosArrayOfChildren_AtObj(hex, iSD); if (aSDChildIdx.length < 4) throw "num of SignedData elem shall be 4 at least"; // 2. HEXs of SignedData children // 2.1. SignedData.CMSVersion var iVersion = aSDChildIdx.shift(); r.version = ASN1HEX.getHexOfTLV_AtObj(hex, iVersion); // 2.2. SignedData.DigestAlgorithms var iAlgs = aSDChildIdx.shift(); r.algs = ASN1HEX.getHexOfTLV_AtObj(hex, iAlgs); // 2.3. SignedData.EncapContentInfo var iEncapContent = aSDChildIdx.shift(); r.encapcontent = ASN1HEX.getHexOfTLV_AtObj(hex, iEncapContent); // 2.4. [0]Certs r.certs = null; r.revs = null; r.si = []; var iNext = aSDChildIdx.shift(); if (hex.substr(iNext, 2) == "a0") { r.certs = ASN1HEX.getHexOfTLV_AtObj(hex, iNext); iNext = aSDChildIdx.shift(); } // 2.5. [1]Revs if (hex.substr(iNext, 2) == "a1") { r.revs = ASN1HEX.getHexOfTLV_AtObj(hex, iNext); iNext = aSDChildIdx.shift(); } // 2.6. SignerInfos var iSignerInfos = iNext; if (hex.substr(iSignerInfos, 2) != "31") throw "Can't find signerInfos"; var aSIIndex = ASN1HEX.getPosArrayOfChildren_AtObj(hex, iSignerInfos); //alert(aSIIndex.join("-")); for (var i = 0; i < aSIIndex.length; i++) { var iSI = aSIIndex[i]; var pSI = nU.parseSignerInfoForAddingUnsigned(hex, iSI, i); r.si[i] = pSI; } // x. obj(SignedData) var tmp = null; r.obj = new nC.SignedData(); tmp = new nA.ASN1Object(); tmp.hTLV = r.version; r.obj.dCMSVersion = tmp; tmp = new nA.ASN1Object(); tmp.hTLV = r.algs; r.obj.dDigestAlgs = tmp; tmp = new nA.ASN1Object(); tmp.hTLV = r.encapcontent; r.obj.dEncapContentInfo = tmp; tmp = new nA.ASN1Object(); tmp.hTLV = r.certs; r.obj.dCerts = tmp; r.obj.signerInfoList = []; for (var i = 0; i < r.si.length; i++) { r.obj.signerInfoList.push(r.si[i].obj); } return r; }; /** * parse SignerInfo to add unsigned attributes * @name parseSignerInfoForAddingUnsigned * @memberOf KJUR.asn1.cades.CAdESUtil * @function * @param {String} hex hexadecimal string of SignerInfo * @return {Object} associative array of parsed data * @description * This method will parse a hexadecimal string of * SignerInfo to add a attribute * to unsigned attributes field in a signerInfo field. * Parsed result will be an associative array which has * following properties: * * NOTE: Parsing of unsigned attributes will be provided in the * future version. That's way this version provides support * for CAdES-T and not for CAdES-C. */ KJUR.asn1.cades.CAdESUtil.parseSignerInfoForAddingUnsigned = function(hex, iSI, nth) { var nA = KJUR.asn1; var nC = KJUR.asn1.cms; var r = {}; var aSIChildIdx = ASN1HEX.getPosArrayOfChildren_AtObj(hex, iSI); //alert(aSIChildIdx.join("=")); if (aSIChildIdx.length != 6) throw "not supported items for SignerInfo (!=6)"; // 1. SignerInfo.CMSVersion var iVersion = aSIChildIdx.shift(); r.version = ASN1HEX.getHexOfTLV_AtObj(hex, iVersion); // 2. SignerIdentifier(IssuerAndSerialNumber) var iIdentifier = aSIChildIdx.shift(); r.si = ASN1HEX.getHexOfTLV_AtObj(hex, iIdentifier); // 3. DigestAlgorithm var iDigestAlg = aSIChildIdx.shift(); r.digalg = ASN1HEX.getHexOfTLV_AtObj(hex, iDigestAlg); // 4. SignedAttrs var iSignedAttrs = aSIChildIdx.shift(); r.sattrs = ASN1HEX.getHexOfTLV_AtObj(hex, iSignedAttrs); // 5. SigAlg var iSigAlg = aSIChildIdx.shift(); r.sigalg = ASN1HEX.getHexOfTLV_AtObj(hex, iSigAlg); // 6. Signature var iSig = aSIChildIdx.shift(); r.sig = ASN1HEX.getHexOfTLV_AtObj(hex, iSig); r.sigval = ASN1HEX.getHexOfV_AtObj(hex, iSig); // 7. obj(SignerInfo) var tmp = null; r.obj = new nC.SignerInfo(); tmp = new nA.ASN1Object(); tmp.hTLV = r.version; r.obj.dCMSVersion = tmp; tmp = new nA.ASN1Object(); tmp.hTLV = r.si; r.obj.dSignerIdentifier = tmp; tmp = new nA.ASN1Object(); tmp.hTLV = r.digalg; r.obj.dDigestAlgorithm = tmp; tmp = new nA.ASN1Object(); tmp.hTLV = r.sattrs; r.obj.dSignedAttrs = tmp; tmp = new nA.ASN1Object(); tmp.hTLV = r.sigalg; r.obj.dSigAlg = tmp; tmp = new nA.ASN1Object(); tmp.hTLV = r.sig; r.obj.dSig = tmp; r.obj.dUnsignedAttrs = new nC.AttributeList(); return r; };