forked from rachanon/stdbWeb
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
775 lines
25 KiB
775 lines
25 KiB
/*! 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 <a href="http://kjur.github.io/jsrsasign/license/">MIT License</a> |
|
*/ |
|
|
|
/** |
|
* 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 |
|
* <p> |
|
* This name space provides |
|
* <a href="https://tools.ietf.org/html/rfc5126">RFC 5126 |
|
* CAdES(CMS Advanced Electronic Signature)</a> generator. |
|
* |
|
* <h4>SUPPORTED FORMATS</h4> |
|
* Following CAdES formats is supported by this library. |
|
* <ul> |
|
* <li>CAdES-BES - CAdES Basic Electronic Signature</li> |
|
* <li>CAdES-EPES - CAdES Explicit Policy-based Electronic Signature</li> |
|
* <li>CAdES-T - Electronic Signature with Time</li> |
|
* </ul> |
|
* </p> |
|
* |
|
* <h4>PROVIDED ATTRIBUTE CLASSES</h4> |
|
* <ul> |
|
* <li>{@link KJUR.asn1.cades.SignaturePolicyIdentifier} - for CAdES-EPES</li> |
|
* <li>{@link KJUR.asn1.cades.SignatureTimeStamp} - for CAdES-T</li> |
|
* <li>{@link KJUR.asn1.cades.CompleteCertificateRefs} - for CAdES-C(for future use)</li> |
|
* </ul> |
|
* NOTE: Currntly CAdES-C is not supported since parser can't |
|
* handle unsigned attribute. |
|
* |
|
* <h4>OTHER CLASSES</h4> |
|
* <ul> |
|
* <li>{@link KJUR.asn1.cades.OtherHashAlgAndValue}</li> |
|
* <li>{@link KJUR.asn1.cades.OtherHash}</li> |
|
* <li>{@link KJUR.asn1.cades.OtherCertID}</li> |
|
* <li>{@link KJUR.asn1.cades.CAdESUtil} - utilities for CAdES</li> |
|
* </ul> |
|
* |
|
* <h4>GENERATE CAdES-BES</h4> |
|
* 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: |
|
* <ul> |
|
* <li>{@link KJUR.asn1.cms.ContentType}</li> |
|
* <li>{@link KJUR.asn1.cms.MessageDigest}</li> |
|
* <li>{@link KJUR.asn1.cms.SigningCertificate} or </li> |
|
* <li>{@link KJUR.asn1.cms.SigningCertificateV2}</li> |
|
* </ul> |
|
* CMSUtil.newSignedData method is very useful to generate CAdES-BES. |
|
* <pre> |
|
* 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(); |
|
* </pre> |
|
* NOTE: ContentType and MessageDigest signed attributes |
|
* are automatically added by default. |
|
* |
|
* <h4>GENERATE CAdES-BES with multiple signers</h4> |
|
* If you need signature by multiple signers, you can |
|
* specify one or more items in 'signerInfos' property as below. |
|
* <pre> |
|
* 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(); |
|
* </pre> |
|
* |
|
* <h4>GENERATE CAdES-EPES</h4> |
|
* When you need a CAdES-EPES signature, |
|
* you just need to add 'SignaturePolicyIdentifier' |
|
* attribute as below. |
|
* <pre> |
|
* 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(); |
|
* </pre> |
|
* |
|
* <h4>GENERATE CAdES-T</h4> |
|
* After a signed CAdES-BES or CAdES-EPES signature have been generated, |
|
* you can generate CAdES-T by adding SigningTimeStamp unsigned attribute. |
|
* <pre> |
|
* 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 |
|
* </pre> |
|
* </p> |
|
* |
|
* <h4>SAMPLE CODES</h4> |
|
* <ul> |
|
* <li><a href="../../tool_cades.html">demo program for CAdES-BES/EPES/T generation</a></li> |
|
* <li><a href="../../test/qunit-do-asn1cades.html">Unit test code for KJUR.asn1.cades package</a></li> |
|
* <li><a href="../../test/qunit-do-asn1tsp.html">Unit test code for KJUR.asn1.tsp package (See SimpleTSAAdaptor test)</a></li> |
|
* <li><a href="../../test/qunit-do-asn1cms.html">Unit test code for KJUR.asn1.cms package (See newSignedData test)</a></li> |
|
* </ul> |
|
* |
|
* @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 |
|
* <pre> |
|
* 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 |
|
* </pre> |
|
* @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 |
|
* <pre> |
|
* OtherHashAlgAndValue ::= SEQUENCE { |
|
* hashAlgorithm AlgorithmIdentifier, |
|
* hashValue OtherHashValue } |
|
* OtherHashValue ::= OCTET STRING |
|
* </pre> |
|
*/ |
|
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 |
|
* <pre> |
|
* id-aa-signatureTimeStampToken OBJECT IDENTIFIER ::= |
|
* 1.2.840.113549.1.9.16.2.14 |
|
* SignatureTimeStampToken ::= TimeStampToken |
|
* </pre> |
|
*/ |
|
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 |
|
* <pre> |
|
* id-aa-ets-certificateRefs OBJECT IDENTIFIER = |
|
* 1.2.840.113549.1.9.16.2.21 |
|
* CompleteCertificateRefs ::= SEQUENCE OF OtherCertID |
|
* </pre> |
|
* @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 |
|
* <pre> |
|
* OtherCertID ::= SEQUENCE { |
|
* otherCertHash OtherHash, |
|
* issuerSerial IssuerSerial OPTIONAL } |
|
* </pre> |
|
* @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 |
|
* <pre> |
|
* OtherHash ::= CHOICE { |
|
* sha1Hash OtherHashValue, -- This contains a SHA-1 hash |
|
* otherHash OtherHashAlgAndValue} |
|
* OtherHashValue ::= OCTET STRING |
|
* </pre> |
|
* @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: |
|
* <ul> |
|
* <li>version - hex of CMSVersion ASN.1 TLV</li> |
|
* <li>algs - hex of DigestAlgorithms ASN.1 TLV</li> |
|
* <li>encapcontent - hex of EncapContentInfo ASN.1 TLV</li> |
|
* <li>certs - hex of Certificates ASN.1 TLV</li> |
|
* <li>revs - hex of RevocationInfoChoices ASN.1 TLV</li> |
|
* <li>si[] - array of SignerInfo properties</li> |
|
* <li>obj - parsed KJUR.asn1.cms.SignedData object</li> |
|
* </ul> |
|
* @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: |
|
* <ul> |
|
* <li>version - hex TLV of version</li> |
|
* <li>si - hex TLV of SignerIdentifier</li> |
|
* <li>digalg - hex TLV of DigestAlgorithm</li> |
|
* <li>sattrs - hex TLV of SignedAttributes</li> |
|
* <li>sigalg - hex TLV of SignatureAlgorithm</li> |
|
* <li>sig - hex TLV of signature</li> |
|
* <li>sigval = hex V of signature</li> |
|
* <li>obj - parsed KJUR.asn1.cms.SignerInfo object</li> |
|
* </ul> |
|
* 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; |
|
}; |
|
|
|
|