public static byte[] createCMS(byte[] buffer, byte[] sign, Certificate cert, boolean detached, byte[] unsignedAttr) throws Exception {
final ContentInfo all = new ContentInfo();
all.contentType = new Asn1ObjectIdentifier(new OID(CMStools.STR_CMS_OID_SIGNED).value);
final SignedData cms = new SignedData();
all.content = cms;
cms.version = new CMSVersion(1);
// digest
cms.digestAlgorithms = new DigestAlgorithmIdentifiers(1);
final DigestAlgorithmIdentifier a = new DigestAlgorithmIdentifier(new OID(CMStools.DIGEST_OID).value);
a.parameters = new Asn1Null();
cms.digestAlgorithms.elements[0] = a;
if (detached)
cms.encapContentInfo = new EncapsulatedContentInfo(new Asn1ObjectIdentifier(new OID(CMStools.STR_CMS_OID_DATA).value), null);
else
cms.encapContentInfo = new EncapsulatedContentInfo(new Asn1ObjectIdentifier(new OID(CMStools.STR_CMS_OID_DATA).value), new Asn1OctetString(buffer));
// certificate
cms.certificates = new CertificateSet(1);
final ru.CryptoPro.JCP.ASN.PKIX1Explicit88.Certificate certificate = new ru.CryptoPro.JCP.ASN.PKIX1Explicit88.Certificate();
final Asn1BerDecodeBuffer decodeBuffer = new Asn1BerDecodeBuffer(cert.getEncoded());
certificate.decode(decodeBuffer);
cms.certificates.elements = new CertificateChoices[1];
cms.certificates.elements[0] = new CertificateChoices();
cms.certificates.elements[0].set_certificate(certificate);
// signer info
cms.signerInfos = new SignerInfos(1);
cms.signerInfos.elements[0] = new SignerInfo();
cms.signerInfos.elements[0].version = new CMSVersion(1);
cms.signerInfos.elements[0].sid = new SignerIdentifier();
final byte[] encodedName = ((X509Certificate) cert).getIssuerX500Principal().getEncoded();
final Asn1BerDecodeBuffer nameBuf = new Asn1BerDecodeBuffer(encodedName);
final Name name = new Name();
name.decode(nameBuf);
final CertificateSerialNumber num = new CertificateSerialNumber(((X509Certificate) cert).getSerialNumber());
cms.signerInfos.elements[0].sid.set_issuerAndSerialNumber(new IssuerAndSerialNumber(name, num));
cms.signerInfos.elements[0].digestAlgorithm = new DigestAlgorithmIdentifier(new OID(CMStools.DIGEST_OID).value);
cms.signerInfos.elements[0].digestAlgorithm.parameters = new Asn1Null();
cms.signerInfos.elements[0].signatureAlgorithm = new SignatureAlgorithmIdentifier(new OID(CMStools.SIGN_OID).value);
cms.signerInfos.elements[0].signatureAlgorithm.parameters = new Asn1Null();
// добавление не подписываемого атрибута OID 1.2.643.5.1.5.2.3.1 в подпись.
if (unsignedAttr != null){
cms.signerInfos.elements[0].unsignedAttrs = new ru.CryptoPro.JCP.ASN.CryptographicMessageSyntax.UnsignedAttributes();
cms.signerInfos.elements[0].unsignedAttrs.elements = new ru.CryptoPro.JCP.ASN.PKIX1Explicit88.Attribute[1];
cms.signerInfos.elements[0].unsignedAttrs.elements[0] = new ru.CryptoPro.JCP.ASN.PKIX1Explicit88.Attribute();
cms.signerInfos.elements[0].unsignedAttrs.elements[0].type = new Asn1ObjectIdentifier(new OID("1.2.643.5.1.5.2.3.1").value);
cms.signerInfos.elements[0].unsignedAttrs.elements[0].values = new ru.CryptoPro.JCP.ASN.PKIX1Explicit88.Attribute_values();
cms.signerInfos.elements[0].unsignedAttrs.elements[0].values.elements = new Asn1OctetString[1];
cms.signerInfos.elements[0].unsignedAttrs.elements[0].values.elements[0] = new Asn1OctetString(unsignedAttr);
}
cms.signerInfos.elements[0].signature = new SignatureValue(sign);
// encode
final Asn1BerEncodeBuffer asnBuf = new Asn1BerEncodeBuffer();
all.encode(asnBuf, true);
return asnBuf.getMsgCopy();