private static unsafe CryptographicAttributeObjectCollection ToCryptographicAttributeObjectCollection(CRYPT_ATTRIBUTES *pCryptAttributes) { CryptographicAttributeObjectCollection collection = new CryptographicAttributeObjectCollection(); for (int i = 0; i < pCryptAttributes->cAttr; i++) { CRYPT_ATTRIBUTE *pCryptAttribute = &(pCryptAttributes->rgAttr[i]); AddCryptAttribute(collection, pCryptAttribute); } return(collection); }
private static unsafe void AddCryptAttribute(CryptographicAttributeObjectCollection collection, CRYPT_ATTRIBUTE *pCryptAttribute) { string oidValue = pCryptAttribute->pszObjId.ToStringAnsi(); Oid oid = new Oid(oidValue); AsnEncodedDataCollection attributeCollection = new AsnEncodedDataCollection(); for (int i = 0; i < pCryptAttribute->cValue; i++) { byte[] encodedAttribute = pCryptAttribute->rgValue[i].ToByteArray(); AsnEncodedData attributeObject = PkcsHelpers.CreateBestPkcs9AttributeObjectAvailable(oid, encodedAttribute); attributeCollection.Add(attributeObject); } collection.Add(new CryptographicAttributeObject(oid, attributeCollection)); }
private static unsafe void AddCryptAttribute(CryptographicAttributeObjectCollection collection, CRYPT_ATTRIBUTE *pCryptAttribute) { string oidValue = pCryptAttribute->pszObjId.ToStringAnsi(); Oid oid = new Oid(oidValue); AsnEncodedDataCollection attributeCollection = new AsnEncodedDataCollection(); for (int i = 0; i < pCryptAttribute->cValue; i++) { // CreateBestPkcs9AttributeObjectAvailable is expected to create a copy of the data so that it has ownership // of the underlying data. ReadOnlySpan <byte> encodedAttribute = pCryptAttribute->rgValue[i].DangerousAsSpan(); AsnEncodedData attributeObject = PkcsHelpers.CreateBestPkcs9AttributeObjectAvailable(oid, encodedAttribute); attributeCollection.Add(attributeObject); } collection.Add(new CryptographicAttributeObject(oid, attributeCollection)); }
// // This returns an allocated native memory block. Its lifetime (and that of any allocated subblocks it may point to) is that of "hb". // private static unsafe CMSG_ENVELOPED_ENCODE_INFO *CreateCmsEnvelopedEncodeInfo(CmsRecipientCollection recipients, AlgorithmIdentifier contentEncryptionAlgorithm, X509Certificate2Collection originatorCerts, CryptographicAttributeObjectCollection unprotectedAttributes, HeapBlockRetainer hb) { CMSG_ENVELOPED_ENCODE_INFO *pEnvelopedEncodeInfo = (CMSG_ENVELOPED_ENCODE_INFO *)(hb.Alloc(sizeof(CMSG_ENVELOPED_ENCODE_INFO))); pEnvelopedEncodeInfo->cbSize = sizeof(CMSG_ENVELOPED_ENCODE_INFO); pEnvelopedEncodeInfo->hCryptProv = IntPtr.Zero; string algorithmOidValue = contentEncryptionAlgorithm.Oid.Value; pEnvelopedEncodeInfo->ContentEncryptionAlgorithm.pszObjId = hb.AllocAsciiString(algorithmOidValue); // Desktop compat: Though it seems like we could copy over the contents of contentEncryptionAlgorithm.Parameters, that property is for retrieving information from decoded Cms's only, and it // massages the raw data so it wouldn't be usable here anyway. To hammer home that fact, the EncryptedCms constructer rather rudely forces contentEncryptionAlgorithm.Parameters to be the empty array. pEnvelopedEncodeInfo->ContentEncryptionAlgorithm.Parameters.cbData = 0; pEnvelopedEncodeInfo->ContentEncryptionAlgorithm.Parameters.pbData = IntPtr.Zero; pEnvelopedEncodeInfo->pvEncryptionAuxInfo = GenerateEncryptionAuxInfoIfNeeded(contentEncryptionAlgorithm, hb); int numRecipients = recipients.Count; pEnvelopedEncodeInfo->cRecipients = numRecipients; pEnvelopedEncodeInfo->rgpRecipients = IntPtr.Zero; CMSG_RECIPIENT_ENCODE_INFO *rgCmsRecipients = (CMSG_RECIPIENT_ENCODE_INFO *)(hb.Alloc(numRecipients, sizeof(CMSG_RECIPIENT_ENCODE_INFO))); for (int index = 0; index < numRecipients; index++) { rgCmsRecipients[index] = EncodeRecipientInfo(recipients[index], contentEncryptionAlgorithm, hb); } pEnvelopedEncodeInfo->rgCmsRecipients = rgCmsRecipients; int numCertificates = originatorCerts.Count; pEnvelopedEncodeInfo->cCertEncoded = numCertificates; pEnvelopedEncodeInfo->rgCertEncoded = null; if (numCertificates != 0) { DATA_BLOB *pCertEncoded = (DATA_BLOB *)(hb.Alloc(numCertificates, sizeof(DATA_BLOB))); for (int i = 0; i < numCertificates; i++) { byte[] certEncoded = originatorCerts[i].Export(X509ContentType.Cert); pCertEncoded[i].cbData = (uint)(certEncoded.Length); pCertEncoded[i].pbData = hb.AllocBytes(certEncoded); } pEnvelopedEncodeInfo->rgCertEncoded = pCertEncoded; } pEnvelopedEncodeInfo->cCrlEncoded = 0; pEnvelopedEncodeInfo->rgCrlEncoded = null; pEnvelopedEncodeInfo->cAttrCertEncoded = 0; pEnvelopedEncodeInfo->rgAttrCertEncoded = null; int numUnprotectedAttributes = unprotectedAttributes.Count; pEnvelopedEncodeInfo->cUnprotectedAttr = numUnprotectedAttributes; pEnvelopedEncodeInfo->rgUnprotectedAttr = null; if (numUnprotectedAttributes != 0) { CRYPT_ATTRIBUTE *pCryptAttribute = (CRYPT_ATTRIBUTE *)(hb.Alloc(numUnprotectedAttributes, sizeof(CRYPT_ATTRIBUTE))); for (int i = 0; i < numUnprotectedAttributes; i++) { CryptographicAttributeObject attribute = unprotectedAttributes[i]; pCryptAttribute[i].pszObjId = hb.AllocAsciiString(attribute.Oid.Value); AsnEncodedDataCollection values = attribute.Values; int numValues = values.Count; pCryptAttribute[i].cValue = numValues; DATA_BLOB *pValues = (DATA_BLOB *)(hb.Alloc(numValues, sizeof(DATA_BLOB))); for (int j = 0; j < numValues; j++) { byte[] rawData = values[j].RawData; pValues[j].cbData = (uint)(rawData.Length); pValues[j].pbData = hb.AllocBytes(rawData); } pCryptAttribute[i].rgValue = pValues; } pEnvelopedEncodeInfo->rgUnprotectedAttr = pCryptAttribute; } return(pEnvelopedEncodeInfo); }