123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257 |
- var forge = require('./forge');
- require('./aes');
- require('./asn1');
- require('./des');
- require('./oids');
- require('./pem');
- require('./pkcs7asn1');
- require('./random');
- require('./util');
- require('./x509');
- var asn1 = forge.asn1;
- var p7 = module.exports = forge.pkcs7 = forge.pkcs7 || {};
- p7.messageFromPem = function(pem) {
- var msg = forge.pem.decode(pem)[0];
- if(msg.type !== 'PKCS7') {
- var error = new Error('Could not convert PKCS#7 message from PEM; PEM ' +
- 'header type is not "PKCS#7".');
- error.headerType = msg.type;
- throw error;
- }
- if(msg.procType && msg.procType.type === 'ENCRYPTED') {
- throw new Error('Could not convert PKCS#7 message from PEM; PEM is encrypted.');
- }
-
- var obj = asn1.fromDer(msg.body);
- return p7.messageFromAsn1(obj);
- };
- p7.messageToPem = function(msg, maxline) {
-
- var pemObj = {
- type: 'PKCS7',
- body: asn1.toDer(msg.toAsn1()).getBytes()
- };
- return forge.pem.encode(pemObj, {maxline: maxline});
- };
- p7.messageFromAsn1 = function(obj) {
-
- var capture = {};
- var errors = [];
- if(!asn1.validate(obj, p7.asn1.contentInfoValidator, capture, errors)) {
- var error = new Error('Cannot read PKCS#7 message. ' +
- 'ASN.1 object is not an PKCS#7 ContentInfo.');
- error.errors = errors;
- throw error;
- }
- var contentType = asn1.derToOid(capture.contentType);
- var msg;
- switch(contentType) {
- case forge.pki.oids.envelopedData:
- msg = p7.createEnvelopedData();
- break;
- case forge.pki.oids.encryptedData:
- msg = p7.createEncryptedData();
- break;
- case forge.pki.oids.signedData:
- msg = p7.createSignedData();
- break;
- default:
- throw new Error('Cannot read PKCS#7 message. ContentType with OID ' +
- contentType + ' is not (yet) supported.');
- }
- msg.fromAsn1(capture.content.value[0]);
- return msg;
- };
- p7.createSignedData = function() {
- var msg = null;
- msg = {
- type: forge.pki.oids.signedData,
- version: 1,
- certificates: [],
- crls: [],
-
- signers: [],
-
- digestAlgorithmIdentifiers: [],
- contentInfo: null,
- signerInfos: [],
- fromAsn1: function(obj) {
-
- _fromAsn1(msg, obj, p7.asn1.signedDataValidator);
- msg.certificates = [];
- msg.crls = [];
- msg.digestAlgorithmIdentifiers = [];
- msg.contentInfo = null;
- msg.signerInfos = [];
- if(msg.rawCapture.certificates) {
- var certs = msg.rawCapture.certificates.value;
- for(var i = 0; i < certs.length; ++i) {
- msg.certificates.push(forge.pki.certificateFromAsn1(certs[i]));
- }
- }
-
- },
- toAsn1: function() {
-
- if(!msg.contentInfo) {
- msg.sign();
- }
- var certs = [];
- for(var i = 0; i < msg.certificates.length; ++i) {
- certs.push(forge.pki.certificateToAsn1(msg.certificates[i]));
- }
- var crls = [];
-
-
- var signedData = asn1.create(asn1.Class.CONTEXT_SPECIFIC, 0, true, [
- asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
-
- asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false,
- asn1.integerToDer(msg.version).getBytes()),
-
- asn1.create(
- asn1.Class.UNIVERSAL, asn1.Type.SET, true,
- msg.digestAlgorithmIdentifiers),
-
- msg.contentInfo
- ])
- ]);
- if(certs.length > 0) {
-
- signedData.value[0].value.push(
- asn1.create(asn1.Class.CONTEXT_SPECIFIC, 0, true, certs));
- }
- if(crls.length > 0) {
-
- signedData.value[0].value.push(
- asn1.create(asn1.Class.CONTEXT_SPECIFIC, 1, true, crls));
- }
-
- signedData.value[0].value.push(
- asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SET, true,
- msg.signerInfos));
-
- return asn1.create(
- asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
-
- asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false,
- asn1.oidToDer(msg.type).getBytes()),
-
- signedData
- ]);
- },
-
- addSigner: function(signer) {
- var issuer = signer.issuer;
- var serialNumber = signer.serialNumber;
- if(signer.certificate) {
- var cert = signer.certificate;
- if(typeof cert === 'string') {
- cert = forge.pki.certificateFromPem(cert);
- }
- issuer = cert.issuer.attributes;
- serialNumber = cert.serialNumber;
- }
- var key = signer.key;
- if(!key) {
- throw new Error(
- 'Could not add PKCS#7 signer; no private key specified.');
- }
- if(typeof key === 'string') {
- key = forge.pki.privateKeyFromPem(key);
- }
-
- var digestAlgorithm = signer.digestAlgorithm || forge.pki.oids.sha1;
- switch(digestAlgorithm) {
- case forge.pki.oids.sha1:
- case forge.pki.oids.sha256:
- case forge.pki.oids.sha384:
- case forge.pki.oids.sha512:
- case forge.pki.oids.md5:
- break;
- default:
- throw new Error(
- 'Could not add PKCS#7 signer; unknown message digest algorithm: ' +
- digestAlgorithm);
- }
-
-
- var authenticatedAttributes = signer.authenticatedAttributes || [];
- if(authenticatedAttributes.length > 0) {
- var contentType = false;
- var messageDigest = false;
- for(var i = 0; i < authenticatedAttributes.length; ++i) {
- var attr = authenticatedAttributes[i];
- if(!contentType && attr.type === forge.pki.oids.contentType) {
- contentType = true;
- if(messageDigest) {
- break;
- }
- continue;
- }
- if(!messageDigest && attr.type === forge.pki.oids.messageDigest) {
- messageDigest = true;
- if(contentType) {
- break;
- }
- continue;
- }
- }
- if(!contentType || !messageDigest) {
- throw new Error('Invalid signer.authenticatedAttributes. If ' +
- 'signer.authenticatedAttributes is specified, then it must ' +
- 'contain at least two attributes, PKCS #9 content-type and ' +
- 'PKCS #9 message-digest.');
- }
- }
- msg.signers.push({
- key: key,
- version: 1,
- issuer: issuer,
- serialNumber: serialNumber,
- digestAlgorithm: digestAlgorithm,
- signatureAlgorithm: forge.pki.oids.rsaEncryption,
- signature: null,
- authenticatedAttributes: authenticatedAttributes,
- unauthenticatedAttributes: []
- });
- },
-
- sign: function(options) {
- options = options || {};
-
- if(typeof msg.content !== 'object' || msg.contentInfo === null) {
-
- msg.contentInfo = asn1.create(
- asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
-
- asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false,
- asn1.oidToDer(forge.pki.oids.data).getBytes())
- ]);
-
- if('content' in msg) {
- var content;
- if(msg.content instanceof forge.util.ByteBuffer) {
- content = msg.content.bytes();
- } else if(typeof msg.content === 'string') {
- content = forge.util.encodeUtf8(msg.content);
- }
- if (options.detached) {
- msg.detachedContent = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OCTETSTRING, false, content);
- } else {
- msg.contentInfo.value.push(
-
- asn1.create(asn1.Class.CONTEXT_SPECIFIC, 0, true, [
- asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OCTETSTRING, false,
- content)
- ]));
- }
- }
- }
-
- if(msg.signers.length === 0) {
- return;
- }
-
- var mds = addDigestAlgorithmIds();
-
- addSignerInfos(mds);
- },
- verify: function() {
- throw new Error('PKCS#7 signature verification not yet implemented.');
- },
-
- addCertificate: function(cert) {
-
- if(typeof cert === 'string') {
- cert = forge.pki.certificateFromPem(cert);
- }
- msg.certificates.push(cert);
- },
-
- addCertificateRevokationList: function(crl) {
- throw new Error('PKCS#7 CRL support not yet implemented.');
- }
- };
- return msg;
- function addDigestAlgorithmIds() {
- var mds = {};
- for(var i = 0; i < msg.signers.length; ++i) {
- var signer = msg.signers[i];
- var oid = signer.digestAlgorithm;
- if(!(oid in mds)) {
-
- mds[oid] = forge.md[forge.pki.oids[oid]].create();
- }
- if(signer.authenticatedAttributes.length === 0) {
-
- signer.md = mds[oid];
- } else {
-
-
-
- signer.md = forge.md[forge.pki.oids[oid]].create();
- }
- }
-
- msg.digestAlgorithmIdentifiers = [];
- for(var oid in mds) {
- msg.digestAlgorithmIdentifiers.push(
-
- asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
-
- asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false,
- asn1.oidToDer(oid).getBytes()),
-
- asn1.create(asn1.Class.UNIVERSAL, asn1.Type.NULL, false, '')
- ]));
- }
- return mds;
- }
- function addSignerInfos(mds) {
- var content;
- if (msg.detachedContent) {
-
- content = msg.detachedContent;
- } else {
-
-
-
-
- content = msg.contentInfo.value[1];
-
- content = content.value[0];
- }
- if(!content) {
- throw new Error(
- 'Could not sign PKCS#7 message; there is no content to sign.');
- }
-
- var contentType = asn1.derToOid(msg.contentInfo.value[0].value);
-
- var bytes = asn1.toDer(content);
-
-
- bytes.getByte();
-
- asn1.getBerValueLength(bytes);
- bytes = bytes.getBytes();
-
- for(var oid in mds) {
- mds[oid].start().update(bytes);
- }
-
- var signingTime = new Date();
- for(var i = 0; i < msg.signers.length; ++i) {
- var signer = msg.signers[i];
- if(signer.authenticatedAttributes.length === 0) {
-
-
- if(contentType !== forge.pki.oids.data) {
- throw new Error(
- 'Invalid signer; authenticatedAttributes must be present ' +
- 'when the ContentInfo content type is not PKCS#7 Data.');
- }
- } else {
-
-
- signer.authenticatedAttributesAsn1 = asn1.create(
- asn1.Class.CONTEXT_SPECIFIC, 0, true, []);
-
-
- var attrsAsn1 = asn1.create(
- asn1.Class.UNIVERSAL, asn1.Type.SET, true, []);
- for(var ai = 0; ai < signer.authenticatedAttributes.length; ++ai) {
- var attr = signer.authenticatedAttributes[ai];
- if(attr.type === forge.pki.oids.messageDigest) {
-
- attr.value = mds[signer.digestAlgorithm].digest();
- } else if(attr.type === forge.pki.oids.signingTime) {
-
- if(!attr.value) {
- attr.value = signingTime;
- }
- }
-
-
-
- attrsAsn1.value.push(_attributeToAsn1(attr));
- signer.authenticatedAttributesAsn1.value.push(_attributeToAsn1(attr));
- }
-
- bytes = asn1.toDer(attrsAsn1).getBytes();
- signer.md.start().update(bytes);
- }
-
- signer.signature = signer.key.sign(signer.md, 'RSASSA-PKCS1-V1_5');
- }
-
- msg.signerInfos = _signersToAsn1(msg.signers);
- }
- };
- p7.createEncryptedData = function() {
- var msg = null;
- msg = {
- type: forge.pki.oids.encryptedData,
- version: 0,
- encryptedContent: {
- algorithm: forge.pki.oids['aes256-CBC']
- },
-
- fromAsn1: function(obj) {
-
- _fromAsn1(msg, obj, p7.asn1.encryptedDataValidator);
- },
-
- decrypt: function(key) {
- if(key !== undefined) {
- msg.encryptedContent.key = key;
- }
- _decryptContent(msg);
- }
- };
- return msg;
- };
- p7.createEnvelopedData = function() {
- var msg = null;
- msg = {
- type: forge.pki.oids.envelopedData,
- version: 0,
- recipients: [],
- encryptedContent: {
- algorithm: forge.pki.oids['aes256-CBC']
- },
-
- fromAsn1: function(obj) {
-
- var capture = _fromAsn1(msg, obj, p7.asn1.envelopedDataValidator);
- msg.recipients = _recipientsFromAsn1(capture.recipientInfos.value);
- },
- toAsn1: function() {
-
- return asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
-
- asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false,
- asn1.oidToDer(msg.type).getBytes()),
-
- asn1.create(asn1.Class.CONTEXT_SPECIFIC, 0, true, [
- asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
-
- asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false,
- asn1.integerToDer(msg.version).getBytes()),
-
- asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SET, true,
- _recipientsToAsn1(msg.recipients)),
-
- asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true,
- _encryptedContentToAsn1(msg.encryptedContent))
- ])
- ])
- ]);
- },
-
- findRecipient: function(cert) {
- var sAttr = cert.issuer.attributes;
- for(var i = 0; i < msg.recipients.length; ++i) {
- var r = msg.recipients[i];
- var rAttr = r.issuer;
- if(r.serialNumber !== cert.serialNumber) {
- continue;
- }
- if(rAttr.length !== sAttr.length) {
- continue;
- }
- var match = true;
- for(var j = 0; j < sAttr.length; ++j) {
- if(rAttr[j].type !== sAttr[j].type ||
- rAttr[j].value !== sAttr[j].value) {
- match = false;
- break;
- }
- }
- if(match) {
- return r;
- }
- }
- return null;
- },
-
- decrypt: function(recipient, privKey) {
- if(msg.encryptedContent.key === undefined && recipient !== undefined &&
- privKey !== undefined) {
- switch(recipient.encryptedContent.algorithm) {
- case forge.pki.oids.rsaEncryption:
- case forge.pki.oids.desCBC:
- var key = privKey.decrypt(recipient.encryptedContent.content);
- msg.encryptedContent.key = forge.util.createBuffer(key);
- break;
- default:
- throw new Error('Unsupported asymmetric cipher, ' +
- 'OID ' + recipient.encryptedContent.algorithm);
- }
- }
- _decryptContent(msg);
- },
-
- addRecipient: function(cert) {
- msg.recipients.push({
- version: 0,
- issuer: cert.issuer.attributes,
- serialNumber: cert.serialNumber,
- encryptedContent: {
-
-
-
- algorithm: forge.pki.oids.rsaEncryption,
- key: cert.publicKey
- }
- });
- },
-
- encrypt: function(key, cipher) {
-
- if(msg.encryptedContent.content === undefined) {
- cipher = cipher || msg.encryptedContent.algorithm;
- key = key || msg.encryptedContent.key;
- var keyLen, ivLen, ciphFn;
- switch(cipher) {
- case forge.pki.oids['aes128-CBC']:
- keyLen = 16;
- ivLen = 16;
- ciphFn = forge.aes.createEncryptionCipher;
- break;
- case forge.pki.oids['aes192-CBC']:
- keyLen = 24;
- ivLen = 16;
- ciphFn = forge.aes.createEncryptionCipher;
- break;
- case forge.pki.oids['aes256-CBC']:
- keyLen = 32;
- ivLen = 16;
- ciphFn = forge.aes.createEncryptionCipher;
- break;
- case forge.pki.oids['des-EDE3-CBC']:
- keyLen = 24;
- ivLen = 8;
- ciphFn = forge.des.createEncryptionCipher;
- break;
- default:
- throw new Error('Unsupported symmetric cipher, OID ' + cipher);
- }
- if(key === undefined) {
- key = forge.util.createBuffer(forge.random.getBytes(keyLen));
- } else if(key.length() != keyLen) {
- throw new Error('Symmetric key has wrong length; ' +
- 'got ' + key.length() + ' bytes, expected ' + keyLen + '.');
- }
-
-
- msg.encryptedContent.algorithm = cipher;
- msg.encryptedContent.key = key;
- msg.encryptedContent.parameter = forge.util.createBuffer(
- forge.random.getBytes(ivLen));
- var ciph = ciphFn(key);
- ciph.start(msg.encryptedContent.parameter.copy());
- ciph.update(msg.content);
-
-
- if(!ciph.finish()) {
- throw new Error('Symmetric encryption failed.');
- }
- msg.encryptedContent.content = ciph.output;
- }
-
- for(var i = 0; i < msg.recipients.length; ++i) {
- var recipient = msg.recipients[i];
-
- if(recipient.encryptedContent.content !== undefined) {
- continue;
- }
- switch(recipient.encryptedContent.algorithm) {
- case forge.pki.oids.rsaEncryption:
- recipient.encryptedContent.content =
- recipient.encryptedContent.key.encrypt(
- msg.encryptedContent.key.data);
- break;
- default:
- throw new Error('Unsupported asymmetric cipher, OID ' +
- recipient.encryptedContent.algorithm);
- }
- }
- }
- };
- return msg;
- };
- function _recipientFromAsn1(obj) {
-
- var capture = {};
- var errors = [];
- if(!asn1.validate(obj, p7.asn1.recipientInfoValidator, capture, errors)) {
- var error = new Error('Cannot read PKCS#7 RecipientInfo. ' +
- 'ASN.1 object is not an PKCS#7 RecipientInfo.');
- error.errors = errors;
- throw error;
- }
- return {
- version: capture.version.charCodeAt(0),
- issuer: forge.pki.RDNAttributesAsArray(capture.issuer),
- serialNumber: forge.util.createBuffer(capture.serial).toHex(),
- encryptedContent: {
- algorithm: asn1.derToOid(capture.encAlgorithm),
- parameter: capture.encParameter.value,
- content: capture.encKey
- }
- };
- }
- function _recipientToAsn1(obj) {
- return asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
-
- asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false,
- asn1.integerToDer(obj.version).getBytes()),
-
- asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
-
- forge.pki.distinguishedNameToAsn1({attributes: obj.issuer}),
-
- asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false,
- forge.util.hexToBytes(obj.serialNumber))
- ]),
-
- asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
-
- asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false,
- asn1.oidToDer(obj.encryptedContent.algorithm).getBytes()),
-
- asn1.create(asn1.Class.UNIVERSAL, asn1.Type.NULL, false, '')
- ]),
-
- asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OCTETSTRING, false,
- obj.encryptedContent.content)
- ]);
- }
- function _recipientsFromAsn1(infos) {
- var ret = [];
- for(var i = 0; i < infos.length; ++i) {
- ret.push(_recipientFromAsn1(infos[i]));
- }
- return ret;
- }
- function _recipientsToAsn1(recipients) {
- var ret = [];
- for(var i = 0; i < recipients.length; ++i) {
- ret.push(_recipientToAsn1(recipients[i]));
- }
- return ret;
- }
- function _signerFromAsn1(obj) {
-
- var capture = {};
- var errors = [];
- if(!asn1.validate(obj, p7.asn1.signerInfoValidator, capture, errors)) {
- var error = new Error('Cannot read PKCS#7 SignerInfo. ' +
- 'ASN.1 object is not an PKCS#7 SignerInfo.');
- error.errors = errors;
- throw error;
- }
- var rval = {
- version: capture.version.charCodeAt(0),
- issuer: forge.pki.RDNAttributesAsArray(capture.issuer),
- serialNumber: forge.util.createBuffer(capture.serial).toHex(),
- digestAlgorithm: asn1.derToOid(capture.digestAlgorithm),
- signatureAlgorithm: asn1.derToOid(capture.signatureAlgorithm),
- signature: capture.signature,
- authenticatedAttributes: [],
- unauthenticatedAttributes: []
- };
-
- var authenticatedAttributes = capture.authenticatedAttributes || [];
- var unauthenticatedAttributes = capture.unauthenticatedAttributes || [];
- return rval;
- }
- function _signerToAsn1(obj) {
-
- var rval = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
-
- asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false,
- asn1.integerToDer(obj.version).getBytes()),
-
- asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
-
- forge.pki.distinguishedNameToAsn1({attributes: obj.issuer}),
-
- asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false,
- forge.util.hexToBytes(obj.serialNumber))
- ]),
-
- asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
-
- asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false,
- asn1.oidToDer(obj.digestAlgorithm).getBytes()),
-
- asn1.create(asn1.Class.UNIVERSAL, asn1.Type.NULL, false, '')
- ])
- ]);
-
- if(obj.authenticatedAttributesAsn1) {
-
- rval.value.push(obj.authenticatedAttributesAsn1);
- }
-
- rval.value.push(asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
-
- asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false,
- asn1.oidToDer(obj.signatureAlgorithm).getBytes()),
-
- asn1.create(asn1.Class.UNIVERSAL, asn1.Type.NULL, false, '')
- ]));
-
- rval.value.push(asn1.create(
- asn1.Class.UNIVERSAL, asn1.Type.OCTETSTRING, false, obj.signature));
-
- if(obj.unauthenticatedAttributes.length > 0) {
-
- var attrsAsn1 = asn1.create(asn1.Class.CONTEXT_SPECIFIC, 1, true, []);
- for(var i = 0; i < obj.unauthenticatedAttributes.length; ++i) {
- var attr = obj.unauthenticatedAttributes[i];
- attrsAsn1.values.push(_attributeToAsn1(attr));
- }
- rval.value.push(attrsAsn1);
- }
- return rval;
- }
- function _signersFromAsn1(signerInfoAsn1s) {
- var ret = [];
- for(var i = 0; i < signerInfoAsn1s.length; ++i) {
- ret.push(_signerFromAsn1(signerInfoAsn1s[i]));
- }
- return ret;
- }
- function _signersToAsn1(signers) {
- var ret = [];
- for(var i = 0; i < signers.length; ++i) {
- ret.push(_signerToAsn1(signers[i]));
- }
- return ret;
- }
- function _attributeToAsn1(attr) {
- var value;
-
- if(attr.type === forge.pki.oids.contentType) {
- value = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false,
- asn1.oidToDer(attr.value).getBytes());
- } else if(attr.type === forge.pki.oids.messageDigest) {
- value = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OCTETSTRING, false,
- attr.value.bytes());
- } else if(attr.type === forge.pki.oids.signingTime) {
-
-
- var jan_1_1950 = new Date('1950-01-01T00:00:00Z');
- var jan_1_2050 = new Date('2050-01-01T00:00:00Z');
- var date = attr.value;
- if(typeof date === 'string') {
-
- var timestamp = Date.parse(date);
- if(!isNaN(timestamp)) {
- date = new Date(timestamp);
- } else if(date.length === 13) {
-
- date = asn1.utcTimeToDate(date);
- } else {
-
- date = asn1.generalizedTimeToDate(date);
- }
- }
- if(date >= jan_1_1950 && date < jan_1_2050) {
- value = asn1.create(
- asn1.Class.UNIVERSAL, asn1.Type.UTCTIME, false,
- asn1.dateToUtcTime(date));
- } else {
- value = asn1.create(
- asn1.Class.UNIVERSAL, asn1.Type.GENERALIZEDTIME, false,
- asn1.dateToGeneralizedTime(date));
- }
- }
-
-
-
-
- return asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
-
- asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false,
- asn1.oidToDer(attr.type).getBytes()),
- asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SET, true, [
-
- value
- ])
- ]);
- }
- function _encryptedContentToAsn1(ec) {
- return [
-
- asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false,
- asn1.oidToDer(forge.pki.oids.data).getBytes()),
-
- asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
-
- asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false,
- asn1.oidToDer(ec.algorithm).getBytes()),
-
- asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OCTETSTRING, false,
- ec.parameter.getBytes())
- ]),
-
- asn1.create(asn1.Class.CONTEXT_SPECIFIC, 0, true, [
- asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OCTETSTRING, false,
- ec.content.getBytes())
- ])
- ];
- }
- function _fromAsn1(msg, obj, validator) {
- var capture = {};
- var errors = [];
- if(!asn1.validate(obj, validator, capture, errors)) {
- var error = new Error('Cannot read PKCS#7 message. ' +
- 'ASN.1 object is not a supported PKCS#7 message.');
- error.errors = error;
- throw error;
- }
-
- var contentType = asn1.derToOid(capture.contentType);
- if(contentType !== forge.pki.oids.data) {
- throw new Error('Unsupported PKCS#7 message. ' +
- 'Only wrapped ContentType Data supported.');
- }
- if(capture.encryptedContent) {
- var content = '';
- if(forge.util.isArray(capture.encryptedContent)) {
- for(var i = 0; i < capture.encryptedContent.length; ++i) {
- if(capture.encryptedContent[i].type !== asn1.Type.OCTETSTRING) {
- throw new Error('Malformed PKCS#7 message, expecting encrypted ' +
- 'content constructed of only OCTET STRING objects.');
- }
- content += capture.encryptedContent[i].value;
- }
- } else {
- content = capture.encryptedContent;
- }
- msg.encryptedContent = {
- algorithm: asn1.derToOid(capture.encAlgorithm),
- parameter: forge.util.createBuffer(capture.encParameter.value),
- content: forge.util.createBuffer(content)
- };
- }
- if(capture.content) {
- var content = '';
- if(forge.util.isArray(capture.content)) {
- for(var i = 0; i < capture.content.length; ++i) {
- if(capture.content[i].type !== asn1.Type.OCTETSTRING) {
- throw new Error('Malformed PKCS#7 message, expecting ' +
- 'content constructed of only OCTET STRING objects.');
- }
- content += capture.content[i].value;
- }
- } else {
- content = capture.content;
- }
- msg.content = forge.util.createBuffer(content);
- }
- msg.version = capture.version.charCodeAt(0);
- msg.rawCapture = capture;
- return capture;
- }
- function _decryptContent(msg) {
- if(msg.encryptedContent.key === undefined) {
- throw new Error('Symmetric key not available.');
- }
- if(msg.content === undefined) {
- var ciph;
- switch(msg.encryptedContent.algorithm) {
- case forge.pki.oids['aes128-CBC']:
- case forge.pki.oids['aes192-CBC']:
- case forge.pki.oids['aes256-CBC']:
- ciph = forge.aes.createDecryptionCipher(msg.encryptedContent.key);
- break;
- case forge.pki.oids['desCBC']:
- case forge.pki.oids['des-EDE3-CBC']:
- ciph = forge.des.createDecryptionCipher(msg.encryptedContent.key);
- break;
- default:
- throw new Error('Unsupported symmetric cipher, OID ' +
- msg.encryptedContent.algorithm);
- }
- ciph.start(msg.encryptedContent.parameter);
- ciph.update(msg.encryptedContent.content);
- if(!ciph.finish()) {
- throw new Error('Symmetric decryption failed.');
- }
- msg.content = ciph.output;
- }
- }
|