// 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);
Exemple #3
0
 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();
         }));
     }
 }
Exemple #5
0
        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));
            }
        }
Exemple #6
0
        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);
        }
Exemple #7
0
            //
            // 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);
            }
Exemple #8
0
 internal static unsafe partial bool CertSetCertificateContextProperty(SafeCertContextHandle pCertContext, CertContextPropId dwPropId, CertSetPropertyFlags dwFlags, DATA_BLOB *pvData);