123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410 |
- /**
- * 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 API
- var asn1 = forge.asn1;
- // shortcut for PKCS#7 API
- var 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',
- optional: true
- }]
- }, {
- name: 'RecipientInfo.encryptedKey',
- tagClass: asn1.Class.UNIVERSAL,
- type: asn1.Type.OCTETSTRING,
- constructed: false,
- capture: 'encKey'
- }]
- };
|