| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409 | /** * Javascript implementation of ASN.1 validators for PKCS#7 v1.5. * * @author Dave Longley * @author Stefan Siegl * * Copyright (c) 2012-2015 Digital Bazaar, Inc. * Copyright (c) 2012 Stefan Siegl <stesie@brokenpipe.de> * * The ASN.1 representation of PKCS#7 is as follows * (see RFC #2315 for details, http://www.ietf.org/rfc/rfc2315.txt): * * A PKCS#7 message consists of a ContentInfo on root level, which may * contain any number of further ContentInfo nested into it. * * ContentInfo ::= SEQUENCE { *   contentType                ContentType, *   content               [0]  EXPLICIT ANY DEFINED BY contentType OPTIONAL * } * * ContentType ::= OBJECT IDENTIFIER * * EnvelopedData ::= SEQUENCE { *   version                    Version, *   recipientInfos             RecipientInfos, *   encryptedContentInfo       EncryptedContentInfo * } * * EncryptedData ::= SEQUENCE { *   version                    Version, *   encryptedContentInfo       EncryptedContentInfo * } * * id-signedData OBJECT IDENTIFIER ::= { iso(1) member-body(2) *   us(840) rsadsi(113549) pkcs(1) pkcs7(7) 2 } * * SignedData ::= SEQUENCE { *   version           INTEGER, *   digestAlgorithms  DigestAlgorithmIdentifiers, *   contentInfo       ContentInfo, *   certificates      [0] IMPLICIT Certificates OPTIONAL, *   crls              [1] IMPLICIT CertificateRevocationLists OPTIONAL, *   signerInfos       SignerInfos * } * * SignerInfos ::= SET OF SignerInfo * * SignerInfo ::= SEQUENCE { *   version                    Version, *   issuerAndSerialNumber      IssuerAndSerialNumber, *   digestAlgorithm            DigestAlgorithmIdentifier, *   authenticatedAttributes    [0] IMPLICIT Attributes OPTIONAL, *   digestEncryptionAlgorithm  DigestEncryptionAlgorithmIdentifier, *   encryptedDigest            EncryptedDigest, *   unauthenticatedAttributes  [1] IMPLICIT Attributes OPTIONAL * } * * EncryptedDigest ::= OCTET STRING * * Attributes ::= SET OF Attribute * * Attribute ::= SEQUENCE { *   attrType    OBJECT IDENTIFIER, *   attrValues  SET OF AttributeValue * } * * AttributeValue ::= ANY * * Version ::= INTEGER * * RecipientInfos ::= SET OF RecipientInfo * * EncryptedContentInfo ::= SEQUENCE { *   contentType                 ContentType, *   contentEncryptionAlgorithm  ContentEncryptionAlgorithmIdentifier, *   encryptedContent       [0]  IMPLICIT EncryptedContent OPTIONAL * } * * ContentEncryptionAlgorithmIdentifier ::= AlgorithmIdentifier * * The AlgorithmIdentifier contains an Object Identifier (OID) and parameters * for the algorithm, if any. In the case of AES and DES3, there is only one, * the IV. * * AlgorithmIdentifer ::= SEQUENCE { *    algorithm OBJECT IDENTIFIER, *    parameters ANY DEFINED BY algorithm OPTIONAL * } * * EncryptedContent ::= OCTET STRING * * RecipientInfo ::= SEQUENCE { *   version                     Version, *   issuerAndSerialNumber       IssuerAndSerialNumber, *   keyEncryptionAlgorithm      KeyEncryptionAlgorithmIdentifier, *   encryptedKey                EncryptedKey * } * * IssuerAndSerialNumber ::= SEQUENCE { *   issuer                      Name, *   serialNumber                CertificateSerialNumber * } * * CertificateSerialNumber ::= INTEGER * * KeyEncryptionAlgorithmIdentifier ::= AlgorithmIdentifier * * EncryptedKey ::= OCTET STRING */var forge = require('./forge');require('./asn1');require('./util');// shortcut for ASN.1 APIvar asn1 = forge.asn1;// shortcut for PKCS#7 APIvar p7v = module.exports = forge.pkcs7asn1 = forge.pkcs7asn1 || {};forge.pkcs7 = forge.pkcs7 || {};forge.pkcs7.asn1 = p7v;var contentInfoValidator = {  name: 'ContentInfo',  tagClass: asn1.Class.UNIVERSAL,  type: asn1.Type.SEQUENCE,  constructed: true,  value: [{    name: 'ContentInfo.ContentType',    tagClass: asn1.Class.UNIVERSAL,    type: asn1.Type.OID,    constructed: false,    capture: 'contentType'  }, {    name: 'ContentInfo.content',    tagClass: asn1.Class.CONTEXT_SPECIFIC,    type: 0,    constructed: true,    optional: true,    captureAsn1: 'content'  }]};p7v.contentInfoValidator = contentInfoValidator;var encryptedContentInfoValidator = {  name: 'EncryptedContentInfo',  tagClass: asn1.Class.UNIVERSAL,  type: asn1.Type.SEQUENCE,  constructed: true,  value: [{    name: 'EncryptedContentInfo.contentType',    tagClass: asn1.Class.UNIVERSAL,    type: asn1.Type.OID,    constructed: false,    capture: 'contentType'  }, {    name: 'EncryptedContentInfo.contentEncryptionAlgorithm',    tagClass: asn1.Class.UNIVERSAL,    type: asn1.Type.SEQUENCE,    constructed: true,    value: [{      name: 'EncryptedContentInfo.contentEncryptionAlgorithm.algorithm',      tagClass: asn1.Class.UNIVERSAL,      type: asn1.Type.OID,      constructed: false,      capture: 'encAlgorithm'    }, {      name: 'EncryptedContentInfo.contentEncryptionAlgorithm.parameter',      tagClass: asn1.Class.UNIVERSAL,      captureAsn1: 'encParameter'    }]  }, {    name: 'EncryptedContentInfo.encryptedContent',    tagClass: asn1.Class.CONTEXT_SPECIFIC,    type: 0,    /* The PKCS#7 structure output by OpenSSL somewhat differs from what     * other implementations do generate.     *     * OpenSSL generates a structure like this:     * SEQUENCE {     *    ...     *    [0]     *       26 DA 67 D2 17 9C 45 3C B1 2A A8 59 2F 29 33 38     *       C3 C3 DF 86 71 74 7A 19 9F 40 D0 29 BE 85 90 45     *       ...     * }     *     * Whereas other implementations (and this PKCS#7 module) generate:     * SEQUENCE {     *    ...     *    [0] {     *       OCTET STRING     *          26 DA 67 D2 17 9C 45 3C B1 2A A8 59 2F 29 33 38     *          C3 C3 DF 86 71 74 7A 19 9F 40 D0 29 BE 85 90 45     *          ...     *    }     * }     *     * In order to support both, we just capture the context specific     * field here.  The OCTET STRING bit is removed below.     */    capture: 'encryptedContent',    captureAsn1: 'encryptedContentAsn1'  }]};p7v.envelopedDataValidator = {  name: 'EnvelopedData',  tagClass: asn1.Class.UNIVERSAL,  type: asn1.Type.SEQUENCE,  constructed: true,  value: [{    name: 'EnvelopedData.Version',    tagClass: asn1.Class.UNIVERSAL,    type: asn1.Type.INTEGER,    constructed: false,    capture: 'version'  }, {    name: 'EnvelopedData.RecipientInfos',    tagClass: asn1.Class.UNIVERSAL,    type: asn1.Type.SET,    constructed: true,    captureAsn1: 'recipientInfos'  }].concat(encryptedContentInfoValidator)};p7v.encryptedDataValidator = {  name: 'EncryptedData',  tagClass: asn1.Class.UNIVERSAL,  type: asn1.Type.SEQUENCE,  constructed: true,  value: [{    name: 'EncryptedData.Version',    tagClass: asn1.Class.UNIVERSAL,    type: asn1.Type.INTEGER,    constructed: false,    capture: 'version'  }].concat(encryptedContentInfoValidator)};var signerValidator = {  name: 'SignerInfo',  tagClass: asn1.Class.UNIVERSAL,  type: asn1.Type.SEQUENCE,  constructed: true,  value: [{    name: 'SignerInfo.version',    tagClass: asn1.Class.UNIVERSAL,    type: asn1.Type.INTEGER,    constructed: false  }, {    name: 'SignerInfo.issuerAndSerialNumber',    tagClass: asn1.Class.UNIVERSAL,    type: asn1.Type.SEQUENCE,    constructed: true,    value: [{      name: 'SignerInfo.issuerAndSerialNumber.issuer',      tagClass: asn1.Class.UNIVERSAL,      type: asn1.Type.SEQUENCE,      constructed: true,      captureAsn1: 'issuer'    }, {      name: 'SignerInfo.issuerAndSerialNumber.serialNumber',      tagClass: asn1.Class.UNIVERSAL,      type: asn1.Type.INTEGER,      constructed: false,      capture: 'serial'    }]  }, {    name: 'SignerInfo.digestAlgorithm',    tagClass: asn1.Class.UNIVERSAL,    type: asn1.Type.SEQUENCE,    constructed: true,    value: [{      name: 'SignerInfo.digestAlgorithm.algorithm',      tagClass: asn1.Class.UNIVERSAL,      type: asn1.Type.OID,      constructed: false,      capture: 'digestAlgorithm'    }, {      name: 'SignerInfo.digestAlgorithm.parameter',      tagClass: asn1.Class.UNIVERSAL,      constructed: false,      captureAsn1: 'digestParameter',      optional: true    }]  }, {    name: 'SignerInfo.authenticatedAttributes',    tagClass: asn1.Class.CONTEXT_SPECIFIC,    type: 0,    constructed: true,    optional: true,    capture: 'authenticatedAttributes'  }, {    name: 'SignerInfo.digestEncryptionAlgorithm',    tagClass: asn1.Class.UNIVERSAL,    type: asn1.Type.SEQUENCE,    constructed: true,    capture: 'signatureAlgorithm'  }, {    name: 'SignerInfo.encryptedDigest',    tagClass: asn1.Class.UNIVERSAL,    type: asn1.Type.OCTETSTRING,    constructed: false,    capture: 'signature'  }, {    name: 'SignerInfo.unauthenticatedAttributes',    tagClass: asn1.Class.CONTEXT_SPECIFIC,    type: 1,    constructed: true,    optional: true,    capture: 'unauthenticatedAttributes'  }]};p7v.signedDataValidator = {  name: 'SignedData',  tagClass: asn1.Class.UNIVERSAL,  type: asn1.Type.SEQUENCE,  constructed: true,  value: [{    name: 'SignedData.Version',    tagClass: asn1.Class.UNIVERSAL,    type: asn1.Type.INTEGER,    constructed: false,    capture: 'version'  }, {    name: 'SignedData.DigestAlgorithms',    tagClass: asn1.Class.UNIVERSAL,    type: asn1.Type.SET,    constructed: true,    captureAsn1: 'digestAlgorithms'  },  contentInfoValidator,  {    name: 'SignedData.Certificates',    tagClass: asn1.Class.CONTEXT_SPECIFIC,    type: 0,    optional: true,    captureAsn1: 'certificates'  }, {    name: 'SignedData.CertificateRevocationLists',    tagClass: asn1.Class.CONTEXT_SPECIFIC,    type: 1,    optional: true,    captureAsn1: 'crls'  }, {    name: 'SignedData.SignerInfos',    tagClass: asn1.Class.UNIVERSAL,    type: asn1.Type.SET,    capture: 'signerInfos',    optional: true,    value: [signerValidator]  }]};p7v.recipientInfoValidator = {  name: 'RecipientInfo',  tagClass: asn1.Class.UNIVERSAL,  type: asn1.Type.SEQUENCE,  constructed: true,  value: [{    name: 'RecipientInfo.version',    tagClass: asn1.Class.UNIVERSAL,    type: asn1.Type.INTEGER,    constructed: false,    capture: 'version'  }, {    name: 'RecipientInfo.issuerAndSerial',    tagClass: asn1.Class.UNIVERSAL,    type: asn1.Type.SEQUENCE,    constructed: true,    value: [{      name: 'RecipientInfo.issuerAndSerial.issuer',      tagClass: asn1.Class.UNIVERSAL,      type: asn1.Type.SEQUENCE,      constructed: true,      captureAsn1: 'issuer'    }, {      name: 'RecipientInfo.issuerAndSerial.serialNumber',      tagClass: asn1.Class.UNIVERSAL,      type: asn1.Type.INTEGER,      constructed: false,      capture: 'serial'    }]  }, {    name: 'RecipientInfo.keyEncryptionAlgorithm',    tagClass: asn1.Class.UNIVERSAL,    type: asn1.Type.SEQUENCE,    constructed: true,    value: [{      name: 'RecipientInfo.keyEncryptionAlgorithm.algorithm',      tagClass: asn1.Class.UNIVERSAL,      type: asn1.Type.OID,      constructed: false,      capture: 'encAlgorithm'    }, {      name: 'RecipientInfo.keyEncryptionAlgorithm.parameter',      tagClass: asn1.Class.UNIVERSAL,      constructed: false,      captureAsn1: 'encParameter'    }]  }, {    name: 'RecipientInfo.encryptedKey',    tagClass: asn1.Class.UNIVERSAL,    type: asn1.Type.OCTETSTRING,    constructed: false,    capture: 'encKey'  }]};
 |