// http://msdn.microsoft.com/en-us/library/windows/desktop/aa380882(v=vs.85).aspx internal static extern bool CryptUnprotectData( [In] DATA_BLOB *pDataIn, [In] IntPtr ppszDataDescr, [In] DATA_BLOB *pOptionalEntropy, [In] IntPtr pvReserved, [In] IntPtr pPromptStruct, [In] uint dwFlags, [Out] out DATA_BLOB pDataOut);
internal static extern bool CryptUnprotectData( #endif DATA_BLOB *pDataIn, IntPtr ppszDataDescr, DATA_BLOB *pOptionalEntropy, IntPtr pvReserved, IntPtr pPromptStruct, uint dwFlags, DATA_BLOB *pDataOut);
private unsafe static extern bool CryptUnprotectData( DATA_BLOB *pDataIn, String szDataDescr, DATA_BLOB *pOptionalEntropy, IntPtr pvReserved, IntPtr pPromptStruct, uint dwFlags, DATA_BLOB *pDataOut );
private static byte[]? DecodeDssKeyValue(byte[] encodedKeyValue) { unsafe { return(encodedKeyValue.DecodeObject( CryptDecodeObjectStructType.X509_DSS_PUBLICKEY, static delegate(void *pvDecoded, int cbDecoded) { Debug.Assert(cbDecoded >= sizeof(DATA_BLOB)); DATA_BLOB *pBlob = (DATA_BLOB *)pvDecoded; return pBlob->ToByteArray(); })); } }
public static SubjectIdentifier ToSubjectIdentifier(this CERT_ID certId) { switch (certId.dwIdChoice) { case CertIdChoice.CERT_ID_ISSUER_SERIAL_NUMBER: { const int dwStrType = (int)(CertNameStrTypeAndFlags.CERT_X500_NAME_STR | CertNameStrTypeAndFlags.CERT_NAME_STR_REVERSE_FLAG); string issuer; unsafe { DATA_BLOB *dataBlobPtr = &certId.u.IssuerSerialNumber.Issuer; int nc = Interop.Crypt32.CertNameToStr((int)MsgEncodingType.All, dataBlobPtr, dwStrType, null, 0); if (nc <= 1) // The API actually return 1 when it fails; which is not what the documentation says. { throw Interop.CPError.GetLastWin32Error().ToCryptographicException(); } Span <char> name = nc <= 128 ? stackalloc char[128] : new char[nc]; fixed(char *namePtr = name) { nc = Interop.Crypt32.CertNameToStr((int)MsgEncodingType.All, dataBlobPtr, dwStrType, namePtr, nc); if (nc <= 1) // The API actually return 1 when it fails; which is not what the documentation says. { throw Interop.CPError.GetLastWin32Error().ToCryptographicException(); } issuer = new string(namePtr); } } byte[] serial = certId.u.IssuerSerialNumber.SerialNumber.ToByteArray(); X509IssuerSerial issuerSerial = new X509IssuerSerial(issuer, serial.ToSerialString()); return(new SubjectIdentifier(SubjectIdentifierType.IssuerAndSerialNumber, issuerSerial)); } case CertIdChoice.CERT_ID_KEY_IDENTIFIER: { byte[] ski = certId.u.KeyId.ToByteArray(); return(new SubjectIdentifier(SubjectIdentifierType.SubjectKeyIdentifier, ski.ToSkiString())); } default: throw new CryptographicException(SR.Format(SR.Cryptography_Cms_Invalid_Subject_Identifier_Type, certId.dwIdChoice)); } }
public static AlgorithmIdentifier ToAlgorithmIdentifier(this CRYPT_ALGORITHM_IDENTIFIER cryptAlgorithmIdentifer) { string oidValue = cryptAlgorithmIdentifer.pszObjId.ToStringAnsi(); AlgId algId = oidValue.ToAlgId(); int keyLength; switch (algId) { case AlgId.CALG_RC2: { if (cryptAlgorithmIdentifer.Parameters.cbData == 0) { keyLength = 0; } else { CRYPT_RC2_CBC_PARAMETERS rc2Parameters; unsafe { int cbSize = sizeof(CRYPT_RC2_CBC_PARAMETERS); if (!Interop.Crypt32.CryptDecodeObject(CryptDecodeObjectStructType.PKCS_RC2_CBC_PARAMETERS, cryptAlgorithmIdentifer.Parameters.pbData, (int)(cryptAlgorithmIdentifer.Parameters.cbData), &rc2Parameters, ref cbSize)) { throw Interop.CPError.GetLastWin32Error().ToCryptographicException(); } } switch (rc2Parameters.dwVersion) { case CryptRc2Version.CRYPT_RC2_40BIT_VERSION: keyLength = KeyLengths.Rc2_40Bit; break; case CryptRc2Version.CRYPT_RC2_56BIT_VERSION: keyLength = KeyLengths.Rc2_56Bit; break; case CryptRc2Version.CRYPT_RC2_64BIT_VERSION: keyLength = KeyLengths.Rc2_64Bit; break; case CryptRc2Version.CRYPT_RC2_128BIT_VERSION: keyLength = KeyLengths.Rc2_128Bit; break; default: keyLength = 0; break; } } break; } case AlgId.CALG_RC4: { int saltLength = 0; if (cryptAlgorithmIdentifer.Parameters.cbData != 0) { using (SafeHandle sh = Interop.Crypt32.CryptDecodeObjectToMemory(CryptDecodeObjectStructType.X509_OCTET_STRING, cryptAlgorithmIdentifer.Parameters.pbData, (int)cryptAlgorithmIdentifer.Parameters.cbData)) { unsafe { DATA_BLOB *pDataBlob = (DATA_BLOB *)(sh.DangerousGetHandle()); saltLength = (int)(pDataBlob->cbData); } } } // For RC4, keyLength = 128 - (salt length * 8). keyLength = KeyLengths.Rc4Max_128Bit - saltLength * 8; break; } case AlgId.CALG_DES: // DES key length is fixed at 64 (or 56 without the parity bits). keyLength = KeyLengths.Des_64Bit; break; case AlgId.CALG_3DES: // 3DES key length is fixed at 192 (or 168 without the parity bits). keyLength = KeyLengths.TripleDes_192Bit; break; default: // We've exhausted all the algorithm types that the desktop used to set the KeyLength for. Key lengths are not a viable way of // identifying algorithms in the long run so we will not extend this list any further. keyLength = 0; break; } AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(Oid.FromOidValue(oidValue, OidGroup.All), keyLength); switch (oidValue) { case Oids.RsaOaep: algorithmIdentifier.Parameters = cryptAlgorithmIdentifer.Parameters.ToByteArray(); break; } return(algorithmIdentifier); }
// // 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); }
internal static unsafe partial bool CertSetCertificateContextProperty(SafeCertContextHandle pCertContext, CertContextPropId dwPropId, CertSetPropertyFlags dwFlags, DATA_BLOB *pvData);