PKCS7ContentInfo ::= SEQUENCE {
	contentType	ContentType ({ pkcs7_check_content_type }),
	content		[0] EXPLICIT SignedData OPTIONAL
}

ContentType ::= OBJECT IDENTIFIER ({ pkcs7_note_OID })

SignedData ::= SEQUENCE {
	version			INTEGER ({ pkcs7_note_signeddata_version }),
	digestAlgorithms	DigestAlgorithmIdentifiers,
	contentInfo		ContentInfo ({ pkcs7_note_content }),
	certificates		CHOICE {
		certSet		[0] IMPLICIT ExtendedCertificatesAndCertificates,
		certSequence	[2] IMPLICIT Certificates
	} OPTIONAL ({ pkcs7_note_certificate_list }),
	crls CHOICE {
		crlSet		[1] IMPLICIT CertificateRevocationLists,
		crlSequence	[3] IMPLICIT CRLSequence
	} OPTIONAL,
	signerInfos		SignerInfos
}

ContentInfo ::= SEQUENCE {
	contentType	ContentType ({ pkcs7_note_OID }),
	content		[0] EXPLICIT Data OPTIONAL
}

Data ::= ANY ({ pkcs7_note_data })

DigestAlgorithmIdentifiers ::= CHOICE {
	daSet			SET OF DigestAlgorithmIdentifier,
	daSequence		SEQUENCE OF DigestAlgorithmIdentifier
}

DigestAlgorithmIdentifier ::= SEQUENCE {
	algorithm   OBJECT IDENTIFIER ({ pkcs7_note_OID }),
	parameters  ANY OPTIONAL
}

--
-- Certificates and certificate lists
--
ExtendedCertificatesAndCertificates ::= SET OF ExtendedCertificateOrCertificate

ExtendedCertificateOrCertificate ::= CHOICE {
  certificate		Certificate,				-- X.509
  extendedCertificate	[0] IMPLICIT ExtendedCertificate	-- PKCS#6
}

ExtendedCertificate ::= Certificate -- cheating

Certificates ::= SEQUENCE OF Certificate

CertificateRevocationLists ::= SET OF CertificateList

CertificateList ::= SEQUENCE OF Certificate -- This may be defined incorrectly

CRLSequence ::= SEQUENCE OF CertificateList

Certificate ::= ANY ({ pkcs7_extract_cert }) -- X.509

--
-- Signer information
--
SignerInfos ::= CHOICE {
	siSet		SET OF SignerInfo,
	siSequence	SEQUENCE OF SignerInfo
}

SignerInfo ::= SEQUENCE {
	version			INTEGER ({ pkcs7_note_signerinfo_version }),
	sid			SignerIdentifier, -- CMS variant, not PKCS#7
	digestAlgorithm		DigestAlgorithmIdentifier ({ pkcs7_sig_note_digest_algo }),
	authenticatedAttributes	CHOICE {
		aaSet		[0] IMPLICIT SetOfAuthenticatedAttribute
					({ pkcs7_sig_note_set_of_authattrs }),
		aaSequence	[2] EXPLICIT SEQUENCE OF AuthenticatedAttribute
			-- Explicit because easier to compute digest on
			-- sequence of attributes and then reuse encoded
			-- sequence in aaSequence.
	} OPTIONAL,
	digestEncryptionAlgorithm
				DigestEncryptionAlgorithmIdentifier ({ pkcs7_sig_note_pkey_algo }),
	encryptedDigest		EncryptedDigest,
	unauthenticatedAttributes CHOICE {
		uaSet		[1] IMPLICIT SET OF UnauthenticatedAttribute,
		uaSequence	[3] IMPLICIT SEQUENCE OF UnauthenticatedAttribute
	} OPTIONAL
} ({ pkcs7_note_signed_info })

SignerIdentifier ::= CHOICE {
	-- RFC5652 sec 5.3
	issuerAndSerialNumber IssuerAndSerialNumber,
        subjectKeyIdentifier [0] IMPLICIT SubjectKeyIdentifier
}

IssuerAndSerialNumber ::= SEQUENCE {
	issuer			Name ({ pkcs7_sig_note_issuer }),
	serialNumber		CertificateSerialNumber ({ pkcs7_sig_note_serial })
}

CertificateSerialNumber ::= INTEGER

SubjectKeyIdentifier ::= OCTET STRING ({ pkcs7_sig_note_skid })

SetOfAuthenticatedAttribute ::= SET OF AuthenticatedAttribute

AuthenticatedAttribute ::= SEQUENCE {
	type			OBJECT IDENTIFIER ({ pkcs7_note_OID }),
	values			SET OF ANY ({ pkcs7_sig_note_authenticated_attr })
}

UnauthenticatedAttribute ::= SEQUENCE {
	type			OBJECT IDENTIFIER,
	values			SET OF ANY
}

DigestEncryptionAlgorithmIdentifier ::= SEQUENCE {
	algorithm		OBJECT IDENTIFIER ({ pkcs7_note_OID }),
	parameters		ANY OPTIONAL
}

EncryptedDigest ::= OCTET STRING ({ pkcs7_sig_note_signature })

---
--- X.500 Name
---
Name ::= SEQUENCE OF RelativeDistinguishedName

RelativeDistinguishedName ::= SET OF AttributeValueAssertion

AttributeValueAssertion ::= SEQUENCE {
	attributeType		OBJECT IDENTIFIER ({ pkcs7_note_OID }),
	attributeValue		ANY
}