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.
984 lines
34 KiB
984 lines
34 KiB
/*! asn1cms-1.0.2.js (c) 2013-2014 Kenji Urushima | kjur.github.com/jsrsasign/license |
|
*/ |
|
/* |
|
* asn1cms.js - ASN.1 DER encoder classes for Cryptographic Message Syntax(CMS) |
|
* |
|
* 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 asn1cms-1.0.js |
|
* @author Kenji Urushima kenji.urushima@gmail.com |
|
* @version 1.0.2 (2014-Jun-07) |
|
* @since jsrsasign 4.2.4 |
|
* @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 Cryptographic Message Syntax(CMS) |
|
* <p> |
|
* This name space provides |
|
* <a href="https://tools.ietf.org/html/rfc5652">RFC 5652 |
|
* Cryptographic Message Syntax (CMS)</a> SignedData generator. |
|
* |
|
* <h4>FEATURES</h4> |
|
* <ul> |
|
* <li>easily generate CMS SignedData</li> |
|
* <li>APIs are very similar to BouncyCastle library ASN.1 classes. So easy to learn.</li> |
|
* </ul> |
|
* |
|
* <h4>PROVIDED CLASSES</h4> |
|
* <ul> |
|
* <li>{@link KJUR.asn1.cms.SignedData}</li> |
|
* <li>{@link KJUR.asn1.cms.SignerInfo}</li> |
|
* <li>{@link KJUR.asn1.cms.AttributeList}</li> |
|
* <li>{@link KJUR.asn1.cms.ContentInfo}</li> |
|
* <li>{@link KJUR.asn1.cms.EncapsulatedContentInfo}</li> |
|
* <li>{@link KJUR.asn1.cms.IssuerAndSerialNumber}</li> |
|
* <li>{@link KJUR.asn1.cms.CMSUtil}</li> |
|
* <li>{@link KJUR.asn1.cms.Attribute}</li> |
|
* <li>{@link KJUR.asn1.cms.ContentType}</li> |
|
* <li>{@link KJUR.asn1.cms.MessageDigest}</li> |
|
* <li>{@link KJUR.asn1.cms.SigningTime}</li> |
|
* <li>{@link KJUR.asn1.cms.SigningCertificate}</li> |
|
* <li>{@link KJUR.asn1.cms.SigningCertificateV2}</li> |
|
* </ul> |
|
* NOTE: Please ignore method summary and document of this namespace. |
|
* This caused by a bug of jsdoc2. |
|
* </p> |
|
* @name KJUR.asn1.cms |
|
* @namespace |
|
*/ |
|
if (typeof KJUR.asn1.cms == "undefined" || !KJUR.asn1.cms) KJUR.asn1.cms = {}; |
|
|
|
/** |
|
* Attribute class for base of CMS attribute |
|
* @name KJUR.asn1.cms.Attribute |
|
* @class Attribute class for base of CMS attribute |
|
* @param {Array} params associative array of parameters |
|
* @extends KJUR.asn1.ASN1Object |
|
* @since jsrsasign 4.2.4 asn1cms 1.0.0 |
|
* @description |
|
* <pre> |
|
* Attributes ::= SET OF Attribute |
|
* Attribute ::= SEQUENCE { |
|
* type OBJECT IDENTIFIER, |
|
* values AttributeSetValue } |
|
* AttributeSetValue ::= SET OF ANY |
|
* </pre> |
|
*/ |
|
KJUR.asn1.cms.Attribute = function(params) { |
|
KJUR.asn1.cms.Attribute.superclass.constructor.call(this); |
|
var valueList = []; // array of values |
|
|
|
this.getEncodedHex = function() { |
|
var attrTypeASN1, attrValueASN1, seq; |
|
attrTypeASN1 = new KJUR.asn1.DERObjectIdentifier({"oid": this.attrTypeOid}); |
|
|
|
attrValueASN1 = new KJUR.asn1.DERSet({"array": this.valueList}); |
|
try { |
|
attrValueASN1.getEncodedHex(); |
|
} catch (ex) { |
|
throw "fail valueSet.getEncodedHex in Attribute(1)/" + ex; |
|
} |
|
|
|
seq = new KJUR.asn1.DERSequence({"array": [attrTypeASN1, attrValueASN1]}); |
|
try { |
|
this.hTLV = seq.getEncodedHex(); |
|
} catch (ex) { |
|
throw "failed seq.getEncodedHex in Attribute(2)/" + ex; |
|
} |
|
|
|
return this.hTLV; |
|
}; |
|
}; |
|
YAHOO.lang.extend(KJUR.asn1.cms.Attribute, KJUR.asn1.ASN1Object); |
|
|
|
/** |
|
* class for CMS ContentType attribute |
|
* @name KJUR.asn1.cms.ContentType |
|
* @class class for CMS ContentType attribute |
|
* @param {Array} params associative array of parameters |
|
* @extends KJUR.asn1.cms.Attribute |
|
* @since jsrsasign 4.2.4 asn1cms 1.0.0 |
|
* @description |
|
* <pre> |
|
* Attribute ::= SEQUENCE { |
|
* type OBJECT IDENTIFIER, |
|
* values AttributeSetValue } |
|
* AttributeSetValue ::= SET OF ANY |
|
* ContentType ::= OBJECT IDENTIFIER |
|
* </pre> |
|
* @example |
|
* o = new KJUR.asn1.cms.ContentType({name: 'data'}); |
|
* o = new KJUR.asn1.cms.ContentType({oid: '1.2.840.113549.1.9.16.1.4'}); |
|
*/ |
|
KJUR.asn1.cms.ContentType = function(params) { |
|
KJUR.asn1.cms.ContentType.superclass.constructor.call(this); |
|
this.attrTypeOid = "1.2.840.113549.1.9.3"; |
|
var contentTypeASN1 = null; |
|
|
|
if (typeof params != "undefined") { |
|
var contentTypeASN1 = new KJUR.asn1.DERObjectIdentifier(params); |
|
this.valueList = [contentTypeASN1]; |
|
} |
|
}; |
|
YAHOO.lang.extend(KJUR.asn1.cms.ContentType, KJUR.asn1.cms.Attribute); |
|
|
|
/** |
|
* class for CMS MessageDigest attribute |
|
* @name KJUR.asn1.cms.MessageDigest |
|
* @class class for CMS MessageDigest attribute |
|
* @param {Array} params associative array of parameters |
|
* @extends KJUR.asn1.cms.Attribute |
|
* @since jsrsasign 4.2.4 asn1cms 1.0.0 |
|
* @description |
|
* <pre> |
|
* Attribute ::= SEQUENCE { |
|
* type OBJECT IDENTIFIER, |
|
* values AttributeSetValue } |
|
* AttributeSetValue ::= SET OF ANY |
|
* MessageDigest ::= OCTET STRING |
|
* </pre> |
|
* @example |
|
* o = new KJUR.asn1.cms.MessageDigest({hex: 'a1a2a3a4...'}); |
|
*/ |
|
KJUR.asn1.cms.MessageDigest = function(params) { |
|
KJUR.asn1.cms.MessageDigest.superclass.constructor.call(this); |
|
this.attrTypeOid = "1.2.840.113549.1.9.4"; |
|
|
|
if (typeof params != "undefined") { |
|
if (params.eciObj instanceof KJUR.asn1.cms.EncapsulatedContentInfo && |
|
typeof params.hashAlg == "string") { |
|
var dataHex = params.eciObj.eContentValueHex; |
|
var hashAlg = params.hashAlg; |
|
var hashValueHex = KJUR.crypto.Util.hashHex(dataHex, hashAlg); |
|
var dAttrValue1 = new KJUR.asn1.DEROctetString({hex: hashValueHex}); |
|
dAttrValue1.getEncodedHex(); |
|
this.valueList = [dAttrValue1]; |
|
} else { |
|
var dAttrValue1 = new KJUR.asn1.DEROctetString(params); |
|
dAttrValue1.getEncodedHex(); |
|
this.valueList = [dAttrValue1]; |
|
} |
|
} |
|
}; |
|
YAHOO.lang.extend(KJUR.asn1.cms.MessageDigest, KJUR.asn1.cms.Attribute); |
|
|
|
/** |
|
* class for CMS SigningTime attribute |
|
* @name KJUR.asn1.cms.SigningTime |
|
* @class class for CMS SigningTime attribute |
|
* @param {Array} params associative array of parameters |
|
* @extends KJUR.asn1.cms.Attribute |
|
* @since jsrsasign 4.2.4 asn1cms 1.0.0 |
|
* @description |
|
* <pre> |
|
* Attribute ::= SEQUENCE { |
|
* type OBJECT IDENTIFIER, |
|
* values AttributeSetValue } |
|
* AttributeSetValue ::= SET OF ANY |
|
* SigningTime ::= Time |
|
* Time ::= CHOICE { |
|
* utcTime UTCTime, |
|
* generalTime GeneralizedTime } |
|
* </pre> |
|
* @example |
|
* o = new KJUR.asn1.cms.SigningTime(); // current time UTCTime by default |
|
* o = new KJUR.asn1.cms.SigningTime({type: 'gen'}); // current time GeneralizedTime |
|
* o = new KJUR.asn1.cms.SigningTime({str: '20140517093800Z'}); // specified GeneralizedTime |
|
* o = new KJUR.asn1.cms.SigningTime({str: '140517093800Z'}); // specified UTCTime |
|
*/ |
|
KJUR.asn1.cms.SigningTime = function(params) { |
|
KJUR.asn1.cms.SigningTime.superclass.constructor.call(this); |
|
this.attrTypeOid = "1.2.840.113549.1.9.5"; |
|
|
|
if (typeof params != "undefined") { |
|
var asn1 = new KJUR.asn1.x509.Time(params); |
|
try { |
|
asn1.getEncodedHex(); |
|
} catch (ex) { |
|
throw "SigningTime.getEncodedHex() failed/" + ex; |
|
} |
|
this.valueList = [asn1]; |
|
} |
|
}; |
|
YAHOO.lang.extend(KJUR.asn1.cms.SigningTime, KJUR.asn1.cms.Attribute); |
|
|
|
/** |
|
* class for CMS SigningCertificate attribute |
|
* @name KJUR.asn1.cms.SigningCertificate |
|
* @class class for CMS SigningCertificate attribute |
|
* @param {Array} params associative array of parameters |
|
* @extends KJUR.asn1.cms.Attribute |
|
* @since jsrsasign 4.5.1 asn1cms 1.0.1 |
|
* @description |
|
* <pre> |
|
* Attribute ::= SEQUENCE { |
|
* type OBJECT IDENTIFIER, |
|
* values AttributeSetValue } |
|
* AttributeSetValue ::= SET OF ANY |
|
* SigningCertificate ::= SEQUENCE { |
|
* certs SEQUENCE OF ESSCertID, |
|
* policies SEQUENCE OF PolicyInformation OPTIONAL } |
|
* ESSCertID ::= SEQUENCE { |
|
* certHash Hash, |
|
* issuerSerial IssuerSerial OPTIONAL } |
|
* IssuerSerial ::= SEQUENCE { |
|
* issuer GeneralNames, |
|
* serialNumber CertificateSerialNumber } |
|
* </pre> |
|
* @example |
|
* o = new KJUR.asn1.cms.SigningCertificate({array: [certPEM]}); |
|
*/ |
|
KJUR.asn1.cms.SigningCertificate = function(params) { |
|
KJUR.asn1.cms.SigningCertificate.superclass.constructor.call(this); |
|
this.attrTypeOid = "1.2.840.113549.1.9.16.2.12"; |
|
var nA = KJUR.asn1; |
|
var nC = KJUR.asn1.cms; |
|
var nY = KJUR.crypto; |
|
|
|
this.setCerts = function(listPEM) { |
|
var list = []; |
|
for (var i = 0; i < listPEM.length; i++) { |
|
var hex = KEYUTIL.getHexFromPEM(listPEM[i]); |
|
var certHashHex = nY.Util.hashHex(hex, 'sha1'); |
|
var dCertHash = new nA.DEROctetString({hex: certHashHex}); |
|
dCertHash.getEncodedHex(); |
|
var dIssuerSerial = |
|
new nC.IssuerAndSerialNumber({cert: listPEM[i]}); |
|
dIssuerSerial.getEncodedHex(); |
|
var dESSCertID = |
|
new nA.DERSequence({array: [dCertHash, dIssuerSerial]}); |
|
dESSCertID.getEncodedHex(); |
|
list.push(dESSCertID); |
|
} |
|
|
|
var dValue = new nA.DERSequence({array: list}); |
|
dValue.getEncodedHex(); |
|
this.valueList = [dValue]; |
|
}; |
|
|
|
if (typeof params != "undefined") { |
|
if (typeof params.array == "object") { |
|
this.setCerts(params.array); |
|
} |
|
} |
|
}; |
|
YAHOO.lang.extend(KJUR.asn1.cms.SigningCertificate, KJUR.asn1.cms.Attribute); |
|
|
|
/** |
|
* class for CMS SigningCertificateV2 attribute |
|
* @name KJUR.asn1.cms.SigningCertificateV2 |
|
* @class class for CMS SigningCertificateV2 attribute |
|
* @param {Array} params associative array of parameters |
|
* @extends KJUR.asn1.cms.Attribute |
|
* @since jsrsasign 4.5.1 asn1cms 1.0.1 |
|
* @description |
|
* <pre> |
|
* oid-signingCertificateV2 = 1.2.840.113549.1.9.16.2.47 |
|
* Attribute ::= SEQUENCE { |
|
* type OBJECT IDENTIFIER, |
|
* values AttributeSetValue } |
|
* AttributeSetValue ::= SET OF ANY |
|
* SigningCertificateV2 ::= SEQUENCE { |
|
* certs SEQUENCE OF ESSCertIDv2, |
|
* policies SEQUENCE OF PolicyInformation OPTIONAL } |
|
* ESSCertIDv2 ::= SEQUENCE { |
|
* hashAlgorithm AlgorithmIdentifier |
|
* DEFAULT {algorithm id-sha256}, |
|
* certHash Hash, |
|
* issuerSerial IssuerSerial OPTIONAL } |
|
* Hash ::= OCTET STRING |
|
* IssuerSerial ::= SEQUENCE { |
|
* issuer GeneralNames, |
|
* serialNumber CertificateSerialNumber } |
|
* </pre> |
|
* @example |
|
* // hash algorithm is sha256 by default: |
|
* o = new KJUR.asn1.cms.SigningCertificateV2({array: [certPEM]}); |
|
* o = new KJUR.asn1.cms.SigningCertificateV2({array: [certPEM], |
|
* hashAlg: 'sha512'}); |
|
*/ |
|
KJUR.asn1.cms.SigningCertificateV2 = function(params) { |
|
KJUR.asn1.cms.SigningCertificateV2.superclass.constructor.call(this); |
|
this.attrTypeOid = "1.2.840.113549.1.9.16.2.47"; |
|
var nA = KJUR.asn1; |
|
var nX = KJUR.asn1.x509; |
|
var nC = KJUR.asn1.cms; |
|
var nY = KJUR.crypto; |
|
|
|
this.setCerts = function(listPEM, hashAlg) { |
|
var list = []; |
|
for (var i = 0; i < listPEM.length; i++) { |
|
var hex = KEYUTIL.getHexFromPEM(listPEM[i]); |
|
|
|
var a = []; |
|
if (hashAlg != "sha256") |
|
a.push(new nX.AlgorithmIdentifier({name: hashAlg})); |
|
|
|
var certHashHex = nY.Util.hashHex(hex, hashAlg); |
|
var dCertHash = new nA.DEROctetString({hex: certHashHex}); |
|
dCertHash.getEncodedHex(); |
|
a.push(dCertHash); |
|
|
|
var dIssuerSerial = |
|
new nC.IssuerAndSerialNumber({cert: listPEM[i]}); |
|
dIssuerSerial.getEncodedHex(); |
|
a.push(dIssuerSerial); |
|
|
|
var dESSCertIDv2 = |
|
new nA.DERSequence({array: a}); |
|
dESSCertIDv2.getEncodedHex(); |
|
list.push(dESSCertIDv2); |
|
} |
|
|
|
var dValue = new nA.DERSequence({array: list}); |
|
dValue.getEncodedHex(); |
|
this.valueList = [dValue]; |
|
}; |
|
|
|
if (typeof params != "undefined") { |
|
if (typeof params.array == "object") { |
|
var hashAlg = "sha256"; // sha2 default |
|
if (typeof params.hashAlg == "string") |
|
hashAlg = params.hashAlg; |
|
this.setCerts(params.array, hashAlg); |
|
} |
|
} |
|
}; |
|
YAHOO.lang.extend(KJUR.asn1.cms.SigningCertificateV2, KJUR.asn1.cms.Attribute); |
|
|
|
/** |
|
* class for IssuerAndSerialNumber ASN.1 structure for CMS |
|
* @name KJUR.asn1.cms.IssuerAndSerialNumber |
|
* @class class for CMS IssuerAndSerialNumber ASN.1 structure for CMS |
|
* @param {Array} params associative array of parameters |
|
* @extends KJUR.asn1.ASN1Object |
|
* @since jsrsasign 4.2.4 asn1cms 1.0.0 |
|
* @description |
|
* <pre> |
|
* IssuerAndSerialNumber ::= SEQUENCE { |
|
* issuer Name, |
|
* serialNumber CertificateSerialNumber } |
|
* CertificateSerialNumber ::= INTEGER |
|
* </pre> |
|
* @example |
|
* // specify by X500Name and DERInteger |
|
* o = new KJUR.asn1.cms.IssuerAndSerialNumber( |
|
* {issuer: {str: '/C=US/O=T1'}, serial {int: 3}}); |
|
* // specify by PEM certificate |
|
* o = new KJUR.asn1.cms.IssuerAndSerialNumber({cert: certPEM}); |
|
* o = new KJUR.asn1.cms.IssuerAndSerialNumber(certPEM); // since 1.0.3 |
|
*/ |
|
KJUR.asn1.cms.IssuerAndSerialNumber = function(params) { |
|
KJUR.asn1.cms.IssuerAndSerialNumber.superclass.constructor.call(this); |
|
var dIssuer = null; |
|
var dSerial = null; |
|
var nA = KJUR.asn1; |
|
var nX = nA.x509; |
|
|
|
/* |
|
* @since asn1cms 1.0.1 |
|
*/ |
|
this.setByCertPEM = function(certPEM) { |
|
var certHex = KEYUTIL.getHexFromPEM(certPEM); |
|
var x = new X509(); |
|
x.hex = certHex; |
|
var issuerTLVHex = x.getIssuerHex(); |
|
this.dIssuer = new nX.X500Name(); |
|
this.dIssuer.hTLV = issuerTLVHex; |
|
var serialVHex = x.getSerialNumberHex(); |
|
this.dSerial = new nA.DERInteger({hex: serialVHex}); |
|
}; |
|
|
|
this.getEncodedHex = function() { |
|
var seq = new KJUR.asn1.DERSequence({"array": [this.dIssuer, |
|
this.dSerial]}); |
|
this.hTLV = seq.getEncodedHex(); |
|
return this.hTLV; |
|
}; |
|
|
|
if (typeof params != "undefined") { |
|
if (typeof params == "string" && |
|
params.indexOf("-----BEGIN ") != -1) { |
|
this.setByCertPEM(params); |
|
} |
|
if (params.issuer && params.serial) { |
|
if (params.issuer instanceof KJUR.asn1.x509.X500Name) { |
|
this.dIssuer = params.issuer; |
|
} else { |
|
this.dIssuer = new KJUR.asn1.x509.X500Name(params.issuer); |
|
} |
|
if (params.serial instanceof KJUR.asn1.DERInteger) { |
|
this.dSerial = params.serial; |
|
} else { |
|
this.dSerial = new KJUR.asn1.DERInteger(params.serial); |
|
} |
|
} |
|
if (typeof params.cert == "string") { |
|
this.setByCertPEM(params.cert); |
|
} |
|
} |
|
}; |
|
YAHOO.lang.extend(KJUR.asn1.cms.IssuerAndSerialNumber, KJUR.asn1.ASN1Object); |
|
|
|
/** |
|
* class for Attributes ASN.1 structure for CMS |
|
* @name KJUR.asn1.cms.AttributeList |
|
* @class class for Attributes ASN.1 structure for CMS |
|
* @param {Array} params associative array of parameters |
|
* @extends KJUR.asn1.ASN1Object |
|
* @since jsrsasign 4.2.4 asn1cms 1.0.0 |
|
* @description |
|
* <pre> |
|
* Attributes ::= SET OF Attribute |
|
* Attribute ::= SEQUENCE { |
|
* type OBJECT IDENTIFIER, |
|
* values AttributeSetValue } |
|
* </pre> |
|
* @example |
|
* // specify by X500Name and DERInteger |
|
* o = new KJUR.asn1.cms.AttributeList({sorted: false}); // ASN.1 BER unsorted SET OF |
|
* o = new KJUR.asn1.cms.AttributeList(); // ASN.1 DER sorted by default |
|
* o.clear(); // clear list of Attributes |
|
* n = o.length(); // get number of Attribute |
|
* o.add(new KJUR.asn1.cms.SigningTime()); // add SigningTime attribute |
|
* hex = o.getEncodedHex(); // get hex encoded ASN.1 data |
|
*/ |
|
KJUR.asn1.cms.AttributeList = function(params) { |
|
KJUR.asn1.cms.AttributeList.superclass.constructor.call(this); |
|
this.list = new Array(); |
|
this.sortFlag = true; |
|
|
|
this.add = function(item) { |
|
if (item instanceof KJUR.asn1.cms.Attribute) { |
|
this.list.push(item); |
|
} |
|
}; |
|
|
|
this.length = function() { |
|
return this.list.length; |
|
}; |
|
|
|
this.clear = function() { |
|
this.list = new Array(); |
|
this.hTLV = null; |
|
this.hV = null; |
|
}; |
|
|
|
this.getEncodedHex = function() { |
|
if (typeof this.hTLV == "string") return this.hTLV; |
|
var set = new KJUR.asn1.DERSet({array: this.list, |
|
sortflag: this.sortFlag}); |
|
this.hTLV = set.getEncodedHex(); |
|
return this.hTLV; |
|
}; |
|
|
|
if (typeof params != "undefined") { |
|
if (typeof params.sortflag != "undefined" && |
|
params.sortflag == false) |
|
this.sortFlag = false; |
|
} |
|
}; |
|
YAHOO.lang.extend(KJUR.asn1.cms.AttributeList, KJUR.asn1.ASN1Object); |
|
|
|
/** |
|
* class for SignerInfo ASN.1 structure of CMS SignedData |
|
* @name KJUR.asn1.cms.SignerInfo |
|
* @class class for Attributes ASN.1 structure of CMS SigndData |
|
* @param {Array} params associative array of parameters |
|
* @extends KJUR.asn1.ASN1Object |
|
* @since jsrsasign 4.2.4 asn1cms 1.0.0 |
|
* @description |
|
* <pre> |
|
* SignerInfo ::= SEQUENCE { |
|
* version CMSVersion, |
|
* sid SignerIdentifier, |
|
* digestAlgorithm DigestAlgorithmIdentifier, |
|
* signedAttrs [0] IMPLICIT SignedAttributes OPTIONAL, |
|
* signatureAlgorithm SignatureAlgorithmIdentifier, |
|
* signature SignatureValue, |
|
* unsignedAttrs [1] IMPLICIT UnsignedAttributes OPTIONAL } |
|
* </pre> |
|
* @example |
|
* o = new KJUR.asn1.cms.SignerInfo(); |
|
* o.setSignerIdentifier(certPEMstring); |
|
* o.dSignedAttrs.add(new KJUR.asn1.cms.ContentType({name: 'data'})); |
|
* o.dSignedAttrs.add(new KJUR.asn1.cms.MessageDigest({hex: 'a1b2...'})); |
|
* o.dSignedAttrs.add(new KJUR.asn1.cms.SigningTime()); |
|
* o.sign(privteKeyParam, "SHA1withRSA"); |
|
*/ |
|
KJUR.asn1.cms.SignerInfo = function(params) { |
|
KJUR.asn1.cms.SignerInfo.superclass.constructor.call(this); |
|
var nA = KJUR.asn1; |
|
var nC = KJUR.asn1.cms; |
|
var nX = KJUR.asn1.x509; |
|
|
|
this.dCMSVersion = new nA.DERInteger({'int': 1}); |
|
this.dSignerIdentifier = null; |
|
this.dDigestAlgorithm = null; |
|
this.dSignedAttrs = new nC.AttributeList(); |
|
this.dSigAlg = null; |
|
this.dSig = null; |
|
this.dUnsignedAttrs = new nC.AttributeList(); |
|
|
|
this.setSignerIdentifier = function(params) { |
|
if (typeof params == "string" && |
|
params.indexOf("CERTIFICATE") != -1 && |
|
params.indexOf("BEGIN") != -1 && |
|
params.indexOf("END") != -1) { |
|
|
|
var certPEM = params; |
|
this.dSignerIdentifier = |
|
new nC.IssuerAndSerialNumber({cert: params}); |
|
} |
|
}; |
|
|
|
/** |
|
* set ContentType/MessageDigest/DigestAlgorithms for SignerInfo/SignedData |
|
* @name setForContentAndHash |
|
* @memberOf KJUR.asn1.cms.SignerInfo |
|
* @param {Array} params JSON parameter to set content related field |
|
* @description |
|
* This method will specify following fields by a parameters: |
|
* <ul> |
|
* <li>add ContentType signed attribute by encapContentInfo</li> |
|
* <li>add MessageDigest signed attribute by encapContentInfo and hashAlg</li> |
|
* <li>add a hash algorithm used in MessageDigest to digestAlgorithms field of SignedData</li> |
|
* <li>set a hash algorithm used in MessageDigest to digestAlgorithm field of SignerInfo</li> |
|
* </ul> |
|
* Argument 'params' is an associative array having following elements: |
|
* <ul> |
|
* <li>eciObj - {@link KJUR.asn1.cms.EncapsulatedContentInfo} object</li> |
|
* <li>sdObj - {@link KJUR.asn1.cms.SignedData} object (Option) to set DigestAlgorithms</li> |
|
* <li>hashAlg - string of hash algorithm name which is used for MessageDigest attribute</li> |
|
* </ul> |
|
* some of elements can be omited. |
|
* @example |
|
* sd = new KJUR.asn1.cms.SignedData(); |
|
* signerInfo.setForContentAndHash({sdObj: sd, |
|
* eciObj: sd.dEncapContentInfo, |
|
* hashAlg: 'sha256'}); |
|
*/ |
|
this.setForContentAndHash = function(params) { |
|
if (typeof params != "undefined") { |
|
if (params.eciObj instanceof KJUR.asn1.cms.EncapsulatedContentInfo) { |
|
this.dSignedAttrs.add(new nC.ContentType({oid: '1.2.840.113549.1.7.1'})); |
|
this.dSignedAttrs.add(new nC.MessageDigest({eciObj: params.eciObj, |
|
hashAlg: params.hashAlg})); |
|
} |
|
if (typeof params.sdObj != "undefined" && |
|
params.sdObj instanceof KJUR.asn1.cms.SignedData) { |
|
if (params.sdObj.digestAlgNameList.join(":").indexOf(params.hashAlg) == -1) { |
|
params.sdObj.digestAlgNameList.push(params.hashAlg); |
|
} |
|
} |
|
if (typeof params.hashAlg == "string") { |
|
this.dDigestAlgorithm = new nX.AlgorithmIdentifier({name: params.hashAlg}); |
|
} |
|
} |
|
}; |
|
|
|
this.sign = function(keyParam, sigAlg) { |
|
// set algorithm |
|
this.dSigAlg = new nX.AlgorithmIdentifier({name: sigAlg}); |
|
|
|
// set signature |
|
var data = this.dSignedAttrs.getEncodedHex(); |
|
var prvKey = KEYUTIL.getKey(keyParam); |
|
var sig = new KJUR.crypto.Signature({alg: sigAlg}); |
|
sig.init(prvKey); |
|
sig.updateHex(data); |
|
var sigValHex = sig.sign(); |
|
this.dSig = new nA.DEROctetString({hex: sigValHex}); |
|
}; |
|
|
|
/* |
|
* @since asn1cms 1.0.3 |
|
*/ |
|
this.addUnsigned = function(attr) { |
|
this.hTLV = null; |
|
this.dUnsignedAttrs.hTLV = null; |
|
this.dUnsignedAttrs.add(attr); |
|
}; |
|
|
|
this.getEncodedHex = function() { |
|
//alert("sattrs.hTLV=" + this.dSignedAttrs.hTLV); |
|
if (this.dSignedAttrs instanceof KJUR.asn1.cms.AttributeList && |
|
this.dSignedAttrs.length() == 0) { |
|
throw "SignedAttrs length = 0 (empty)"; |
|
} |
|
var sa = new nA.DERTaggedObject({obj: this.dSignedAttrs, |
|
tag: 'a0', explicit: false}); |
|
var ua = null;; |
|
if (this.dUnsignedAttrs.length() > 0) { |
|
ua = new nA.DERTaggedObject({obj: this.dUnsignedAttrs, |
|
tag: 'a1', explicit: false}); |
|
} |
|
|
|
var items = [ |
|
this.dCMSVersion, |
|
this.dSignerIdentifier, |
|
this.dDigestAlgorithm, |
|
sa, |
|
this.dSigAlg, |
|
this.dSig, |
|
]; |
|
if (ua != null) items.push(ua); |
|
|
|
var seq = new nA.DERSequence({array: items}); |
|
this.hTLV = seq.getEncodedHex(); |
|
return this.hTLV; |
|
}; |
|
}; |
|
YAHOO.lang.extend(KJUR.asn1.cms.SignerInfo, KJUR.asn1.ASN1Object); |
|
|
|
/** |
|
* class for EncapsulatedContentInfo ASN.1 structure for CMS |
|
* @name KJUR.asn1.cms.EncapsulatedContentInfo |
|
* @class class for EncapsulatedContentInfo ASN.1 structure for CMS |
|
* @param {Array} params associative array of parameters |
|
* @extends KJUR.asn1.ASN1Object |
|
* @since jsrsasign 4.2.4 asn1cms 1.0.0 |
|
* @description |
|
* <pre> |
|
* EncapsulatedContentInfo ::= SEQUENCE { |
|
* eContentType ContentType, |
|
* eContent [0] EXPLICIT OCTET STRING OPTIONAL } |
|
* ContentType ::= OBJECT IDENTIFIER |
|
* </pre> |
|
* @example |
|
* o = new KJUR.asn1.cms.EncapsulatedContentInfo(); |
|
* o.setContentType('1.2.3.4.5'); // specify eContentType by OID |
|
* o.setContentType('data'); // specify eContentType by name |
|
* o.setContentValueHex('a1a2a4...'); // specify eContent data by hex string |
|
* o.setContentValueStr('apple'); // specify eContent data by UTF-8 string |
|
* // for detached contents (i.e. data not concluded in eContent) |
|
* o.isDetached = true; // false as default |
|
*/ |
|
KJUR.asn1.cms.EncapsulatedContentInfo = function(params) { |
|
KJUR.asn1.cms.EncapsulatedContentInfo.superclass.constructor.call(this); |
|
var nA = KJUR.asn1; |
|
var nC = KJUR.asn1.cms; |
|
var nX = KJUR.asn1.x509; |
|
this.dEContentType = new nA.DERObjectIdentifier({name: 'data'}); |
|
this.dEContent = null; |
|
this.isDetached = false; |
|
this.eContentValueHex = null; |
|
|
|
this.setContentType = function(nameOrOid) { |
|
if (nameOrOid.match(/^[0-2][.][0-9.]+$/)) { |
|
this.dEContentType = new nA.DERObjectIdentifier({oid: nameOrOid}); |
|
} else { |
|
this.dEContentType = new nA.DERObjectIdentifier({name: nameOrOid}); |
|
} |
|
}; |
|
|
|
this.setContentValue = function(params) { |
|
if (typeof params != "undefined") { |
|
if (typeof params.hex == "string") { |
|
this.eContentValueHex = params.hex; |
|
} else if (typeof params.str == "string") { |
|
this.eContentValueHex = utf8tohex(params.str); |
|
} |
|
} |
|
}; |
|
|
|
this.setContentValueHex = function(valueHex) { |
|
this.eContentValueHex = valueHex; |
|
}; |
|
|
|
this.setContentValueStr = function(valueStr) { |
|
this.eContentValueHex = utf8tohex(valueStr); |
|
}; |
|
|
|
this.getEncodedHex = function() { |
|
if (typeof this.eContentValueHex != "string") { |
|
throw "eContentValue not yet set"; |
|
} |
|
|
|
var dValue = new nA.DEROctetString({hex: this.eContentValueHex}); |
|
this.dEContent = new nA.DERTaggedObject({obj: dValue, |
|
tag: 'a0', |
|
explicit: true}); |
|
|
|
var a = [this.dEContentType]; |
|
if (! this.isDetached) a.push(this.dEContent); |
|
var seq = new nA.DERSequence({array: a}); |
|
this.hTLV = seq.getEncodedHex(); |
|
return this.hTLV; |
|
}; |
|
}; |
|
YAHOO.lang.extend(KJUR.asn1.cms.EncapsulatedContentInfo, KJUR.asn1.ASN1Object); |
|
|
|
// - type |
|
// - obj |
|
/** |
|
* class for ContentInfo ASN.1 structure for CMS |
|
* @name KJUR.asn1.cms.ContentInfo |
|
* @class class for ContentInfo ASN.1 structure for CMS |
|
* @param {Array} params associative array of parameters |
|
* @extends KJUR.asn1.ASN1Object |
|
* @since jsrsasign 4.2.4 asn1cms 1.0.0 |
|
* @description |
|
* <pre> |
|
* ContentInfo ::= SEQUENCE { |
|
* contentType ContentType, |
|
* content [0] EXPLICIT ANY DEFINED BY contentType } |
|
* ContentType ::= OBJECT IDENTIFIER |
|
* </pre> |
|
* @example |
|
* a = [new KJUR.asn1.DERInteger({int: 1}), |
|
* new KJUR.asn1.DERInteger({int: 2})]; |
|
* seq = new KJUR.asn1.DERSequence({array: a}); |
|
* o = new KJUR.asn1.cms.ContentInfo({type: 'data', obj: seq}); |
|
*/ |
|
KJUR.asn1.cms.ContentInfo = function(params) { |
|
KJUR.asn1.cms.ContentInfo.superclass.constructor.call(this); |
|
var nA = KJUR.asn1; |
|
var nC = KJUR.asn1.cms; |
|
var nX = KJUR.asn1.x509; |
|
|
|
this.dContentType = null; |
|
this.dContent = null; |
|
|
|
this.setContentType = function(params) { |
|
if (typeof params == "string") { |
|
this.dContentType = nX.OID.name2obj(params); |
|
} |
|
}; |
|
|
|
this.getEncodedHex = function() { |
|
var dContent0 = new nA.DERTaggedObject({obj: this.dContent, tag: 'a0', explicit: true}); |
|
var seq = new nA.DERSequence({array: [this.dContentType, dContent0]}); |
|
this.hTLV = seq.getEncodedHex(); |
|
return this.hTLV; |
|
}; |
|
|
|
if (typeof params != "undefined") { |
|
if (params.type) this.setContentType(params.type); |
|
if (params.obj && params.obj instanceof nA.ASN1Object) this.dContent = params.obj; |
|
} |
|
}; |
|
YAHOO.lang.extend(KJUR.asn1.cms.ContentInfo, KJUR.asn1.ASN1Object); |
|
|
|
/** |
|
* class for SignerInfo ASN.1 structure of CMS SignedData |
|
* @name KJUR.asn1.cms.SignedData |
|
* @class class for Attributes ASN.1 structure of CMS SigndData |
|
* @param {Array} params associative array of parameters |
|
* @extends KJUR.asn1.ASN1Object |
|
* @since jsrsasign 4.2.4 asn1cms 1.0.0 |
|
* |
|
* @description |
|
* <pre> |
|
* SignedData ::= SEQUENCE { |
|
* version CMSVersion, |
|
* digestAlgorithms DigestAlgorithmIdentifiers, |
|
* encapContentInfo EncapsulatedContentInfo, |
|
* certificates [0] IMPLICIT CertificateSet OPTIONAL, |
|
* crls [1] IMPLICIT RevocationInfoChoices OPTIONAL, |
|
* signerInfos SignerInfos } |
|
* SignerInfos ::= SET OF SignerInfo |
|
* CertificateSet ::= SET OF CertificateChoices |
|
* DigestAlgorithmIdentifiers ::= SET OF DigestAlgorithmIdentifier |
|
* CertificateSet ::= SET OF CertificateChoices |
|
* RevocationInfoChoices ::= SET OF RevocationInfoChoice |
|
* </pre> |
|
* |
|
* @example |
|
* sd = new KJUR.asn1.cms.SignedData(); |
|
* sd.dEncapContentInfo.setContentValueStr("test string"); |
|
* sd.signerInfoList[0].setForContentAndHash({sdObj: sd, |
|
* eciObj: sd.dEncapContentInfo, |
|
* hashAlg: 'sha256'}); |
|
* sd.signerInfoList[0].dSignedAttrs.add(new KJUR.asn1.cms.SigningTime()); |
|
* sd.signerInfoList[0].setSignerIdentifier(certPEM); |
|
* sd.signerInfoList[0].sign(prvP8PEM, "SHA256withRSA"); |
|
* hex = sd.getContentInfoEncodedHex(); |
|
*/ |
|
KJUR.asn1.cms.SignedData = function(params) { |
|
KJUR.asn1.cms.SignedData.superclass.constructor.call(this); |
|
var nA = KJUR.asn1; |
|
var nC = KJUR.asn1.cms; |
|
var nX = KJUR.asn1.x509; |
|
|
|
this.dCMSVersion = new nA.DERInteger({'int': 1}); |
|
this.dDigestAlgs = null; |
|
this.digestAlgNameList = []; |
|
this.dEncapContentInfo = new nC.EncapsulatedContentInfo(); |
|
this.dCerts = null; |
|
this.certificateList = []; |
|
this.crlList = []; |
|
this.signerInfoList = [new nC.SignerInfo()]; |
|
|
|
this.addCertificatesByPEM = function(certPEM) { |
|
var hex = KEYUTIL.getHexFromPEM(certPEM); |
|
var o = new nA.ASN1Object(); |
|
o.hTLV = hex; |
|
this.certificateList.push(o); |
|
}; |
|
|
|
this.getEncodedHex = function() { |
|
if (typeof this.hTLV == "string") return this.hTLV; |
|
|
|
if (this.dDigestAlgs == null) { |
|
var digestAlgList = []; |
|
for (var i = 0; i < this.digestAlgNameList.length; i++) { |
|
var name = this.digestAlgNameList[i]; |
|
var o = new nX.AlgorithmIdentifier({name: name}); |
|
digestAlgList.push(o); |
|
} |
|
this.dDigestAlgs = new nA.DERSet({array: digestAlgList}); |
|
} |
|
|
|
var a = [this.dCMSVersion, |
|
this.dDigestAlgs, |
|
this.dEncapContentInfo]; |
|
|
|
if (this.dCerts == null) { |
|
if (this.certificateList.length > 0) { |
|
var o1 = new nA.DERSet({array: this.certificateList}); |
|
this.dCerts |
|
= new nA.DERTaggedObject({obj: o1, |
|
tag: 'a0', |
|
explicit: false}); |
|
} |
|
} |
|
if (this.dCerts != null) a.push(this.dCerts); |
|
|
|
var dSignerInfos = new nA.DERSet({array: this.signerInfoList}); |
|
a.push(dSignerInfos); |
|
|
|
var seq = new nA.DERSequence({array: a}); |
|
this.hTLV = seq.getEncodedHex(); |
|
return this.hTLV; |
|
}; |
|
|
|
this.getContentInfo = function() { |
|
this.getEncodedHex(); |
|
var ci = new nC.ContentInfo({type: 'signed-data', obj: this}); |
|
return ci; |
|
}; |
|
|
|
this.getContentInfoEncodedHex = function() { |
|
var ci = this.getContentInfo(); |
|
var ciHex = ci.getEncodedHex(); |
|
return ciHex; |
|
}; |
|
|
|
this.getPEM = function() { |
|
var hex = this.getContentInfoEncodedHex(); |
|
var pem = nA.ASN1Util.getPEMStringFromHex(hex, "CMS"); |
|
return pem; |
|
}; |
|
}; |
|
YAHOO.lang.extend(KJUR.asn1.cms.SignedData, KJUR.asn1.ASN1Object); |
|
|
|
/** |
|
* CMS utiliteis class |
|
* @name KJUR.asn1.cms.CMSUtil |
|
* @class CMS utilities class |
|
*/ |
|
KJUR.asn1.cms.CMSUtil = new function() { |
|
}; |
|
/** |
|
* generate SignedData object specified by JSON parameters |
|
* @name newSignedData |
|
* @memberOf KJUR.asn1.cms.CMSUtil |
|
* @function |
|
* @param {Array} param JSON parameter to generate CMS SignedData |
|
* @return {KJUR.asn1.cms.SignedData} object just generated |
|
* @description |
|
* This method provides more easy way to genereate |
|
* CMS SignedData ASN.1 structure by JSON data. |
|
* @example |
|
* var sd = KJUR.asn1.cms.CMSUtil.newSignedData({ |
|
* content: {str: "jsrsasign"}, |
|
* certs: [certPEM], |
|
* signerInfos: [{ |
|
* hashAlg: 'sha256', |
|
* sAttr: { |
|
* SigningTime: {} |
|
* SigningCertificateV2: {array: [certPEM]}, |
|
* }, |
|
* signerCert: certPEM, |
|
* sigAlg: 'SHA256withRSA', |
|
* signerPrvKey: prvPEM |
|
* }] |
|
* }); |
|
*/ |
|
KJUR.asn1.cms.CMSUtil.newSignedData = function(param) { |
|
var nC = KJUR.asn1.cms; |
|
var nE = KJUR.asn1.cades; |
|
var sd = new nC.SignedData(); |
|
|
|
sd.dEncapContentInfo.setContentValue(param.content); |
|
|
|
if (typeof param.certs == "object") { |
|
for (var i = 0; i < param.certs.length; i++) { |
|
sd.addCertificatesByPEM(param.certs[i]); |
|
} |
|
} |
|
|
|
sd.signerInfoList = []; |
|
for (var i = 0; i < param.signerInfos.length; i++) { |
|
var siParam = param.signerInfos[i]; |
|
var si = new nC.SignerInfo(); |
|
si.setSignerIdentifier(siParam.signerCert); |
|
|
|
si.setForContentAndHash({sdObj: sd, |
|
eciObj: sd.dEncapContentInfo, |
|
hashAlg: siParam.hashAlg}); |
|
|
|
for (attrName in siParam.sAttr) { |
|
var attrParam = siParam.sAttr[attrName]; |
|
if (attrName == "SigningTime") { |
|
var attr = new nC.SigningTime(attrParam); |
|
si.dSignedAttrs.add(attr); |
|
} |
|
if (attrName == "SigningCertificate") { |
|
var attr = new nC.SigningCertificate(attrParam); |
|
si.dSignedAttrs.add(attr); |
|
} |
|
if (attrName == "SigningCertificateV2") { |
|
var attr = new nC.SigningCertificateV2(attrParam); |
|
si.dSignedAttrs.add(attr); |
|
} |
|
if (attrName == "SignaturePolicyIdentifier") { |
|
var attr = new nE.SignaturePolicyIdentifier(attrParam); |
|
si.dSignedAttrs.add(attr); |
|
} |
|
} |
|
|
|
si.sign(siParam.signerPrvKey, siParam.sigAlg); |
|
sd.signerInfoList.push(si); |
|
} |
|
|
|
return sd; |
|
}; |
|
|
|
|