Retired Microsoft Blog disclaimer

This directory is a mirror of retired "Decrypt My World" MSDN blog and is provided as is. All posting authorship and copyrights belong to respective authors.

Posts on this page:

Original URL: https://blogs.msdn.microsoft.com/alejacma/2010/08/17/nottimenested-not-detected-when-doing-chain-validation/
Post name: "NotTimeNested" not detected when doing chain validation
Original author: Alejandro Campos Magencio
Posting date: 2010-08-17T04:45:16+00:00


Hi all,

When doing certificate chain validation with X509Chain class in .NET, you may realize that the ChainStatus property doesn't return NotTimeNested, even if the certificate validity period is not nested in the issuing certificate validity period.

.NET is just showing the results of calling CertGetCertificateChain API behind the scenes. This API should have returned CERT_TRUST_IS_NOT_TIME_NESTED in the resultant CERT_CHAIN_CONTEXT.CERT_TRUST_STATUS struct. But it doesn't.

The reason is that CERT_TRUST_IS_NOT_TIME_NESTED error status is not supported anymore. We discontinued that check about a decade ago.

 

Note that CERT_TRUST_IS_NOT_TIME_NESTED has already been removed from this MSDN article: CERT_TRUST_STATUS Structure.

Also note we won't be able to remove NotTimeNested from X509ChainStatusFlags documentation because the flag is part of an existing enumeration. So we will add a note stating that the value will never be set on X509ChainStatusFlags Enumeration docs for NET Framework 4.0& NET Framework 3.5. .NET 2.0 pages are not being updated anymore. So there won’t be any changes on X509ChainStatusFlags Enumeration docs forNET Framework 2.0.

I hope this helps.

Regards,

 

Alex (Alejandro Campos Magencio)

 

 

Original URL: https://blogs.msdn.microsoft.com/alejacma/2010/08/17/how-to-publish-a-printer-in-active-directory-c/
Post name: How to publish a printer in Active Directory (C#)
Original author: Alejandro Campos Magencio
Posting date: 2010-08-17T03:25:02+00:00


Hi all,

We may publish a printer attached to our machine in Active Directory. To do that on Windows 7, for instance, we can go to "Devices and Printers" console, select "Printer Properties", go to "Sharing" tab, and mark the "List in the directory" checkbox. That action will end up calling SetPrinter API to do the work.

I created a C# WinForms sample which calls SetPrinter through p/invoke.

The form of the ap contains 1 text box for the printer name and 4 buttons: Publish, Update, Unpublish and Status.

Publish, Update and Unpublish operations may fail with error ERROR_IO_PENDING as documented in MSDN, which means that the operation is taking place in the background, and has not finished yet. So we can use Status to check the exact status of those pending operations: PUBLISHED, UNPUBLISHED, PENDING PUBLISH or PENDING UNPUBLISH. If we are e.g. PENDING PUBLISH, we press Status again after a while until we get PUBLISHED if everything went ok.

Update operation will fail with error ERROR_FILE_NOT_FOUND if the printer is not already published, as documented in MSDN.

This sample works on both x86 and x64. Here is the code:

Form1.cs

using System;

using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace AlexPublishPrinter
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private void publishButton_Click(object sender, EventArgs e)
{
Publish(Win32.DSPRINT_PUBLISH, textBox1.Text);
}

private void updateButton_Click(object sender, EventArgs e)
{
Publish(Win32.DSPRINT_UPDATE, textBox1.Text);
}

private void unpublishButton_Click(object sender, EventArgs e)
{
Publish(Win32.DSPRINT_UNPUBLISH, textBox1.Text);
}

private void statusButton_Click(object sender, EventArgs e)
{
GetPublishedStatus(textBox1.Text);
}

private void Publish(uint dwAction, string printerName)
{
IntPtr hPrinter = IntPtr.Zero;
Win32.PRINTER_DEFAULTS printerDefaults = new Win32.PRINTER_DEFAULTS();
Win32.PRINTER_INFO_7 printerInfo = new Win32.PRINTER_INFO_7();

try
{
// Open printer
printerDefaults.pDatatype = IntPtr.Zero;
printerDefaults.pDevMode = IntPtr.Zero;
printerDefaults.DesiredAccess = Win32.PRINTER_ALL_ACCESS;
if (!Win32.OpenPrinter(printerName, out hPrinter, ref printerDefaults))
{
throw new Win32Exception(Marshal.GetLastWin32Error());
}

// Publish printer
printerInfo.pszObjectGUID = IntPtr.Zero;
printerInfo.dwAction = dwAction;
if (!Win32.SetPrinter(hPrinter, 7, ref printerInfo, 0))
{
uint error = (uint)Marshal.GetLastWin32Error();
switch (error)
{
case Win32.ERROR_IO_PENDING:
// According to MSDN, DSPRINT_PUBLISH may fail with this error and attempt to complete the action in the background
MessageBox.Show("ERROR_IO_PENDING");
break;
case Win32.ERROR_FILE_NOT_FOUND:
// According to MSDN, DSPRINT_UPDATE will fail with this error if the printer is not already published
MessageBox.Show("ERROR_FILE_NOT_FOUND");
break;
default:
throw new Win32Exception(Marshal.GetLastWin32Error());
}
}

MessageBox.Show("SUCCESS");
}
catch (Exception ex)
{
// Show errors
MessageBox.Show(ex.Message);
}
finally
{
// Close printer
if (!hPrinter.Equals(IntPtr.Zero))
{
Win32.ClosePrinter(hPrinter);
}
}
}

private void GetPublishedStatus(string printerName)
{
IntPtr hPrinter = IntPtr.Zero;
Win32.PRINTER_DEFAULTS printerDefaults = new Win32.PRINTER_DEFAULTS();
Win32.PRINTER_INFO_7 printerInfo = new Win32.PRINTER_INFO_7();
IntPtr pPrinterInfo = IntPtr.Zero;
int cbNeeded = 0;

try
{
// Open printer
printerDefaults.pDatatype = IntPtr.Zero;
printerDefaults.pDevMode = IntPtr.Zero;
printerDefaults.DesiredAccess = Win32.PRINTER_ALL_ACCESS;
if (!Win32.OpenPrinter(printerName, out hPrinter, ref printerDefaults))
{
throw new Win32Exception(Marshal.GetLastWin32Error());
}

// Get if printer got published
if (!Win32.GetPrinter(hPrinter, 7, IntPtr.Zero, 0, out cbNeeded))
{
int error = Marshal.GetLastWin32Error();
if (error != Win32.ERROR_INSUFFICIENT_BUFFER)
{
throw new Win32Exception(error);
}

pPrinterInfo = Marshal.AllocHGlobal(cbNeeded);

if (!Win32.GetPrinter(hPrinter, 7, pPrinterInfo, cbNeeded, out cbNeeded))
{
throw new Win32Exception(Marshal.GetLastWin32Error());
}

printerInfo = (Win32.PRINTER_INFO_7)Marshal.PtrToStructure(pPrinterInfo, typeof(Win32.PRINTER_INFO_7));
}

switch (printerInfo.dwAction)
{
case Win32.DSPRINT_PUBLISH:
MessageBox.Show("PUBLISHED");
break;
case Win32.DSPRINT_UNPUBLISH:
MessageBox.Show("UNPUBLISHED");
break;
case Win32.DSPRINT_PENDING | Win32.DSPRINT_PUBLISH:
MessageBox.Show("PENDING PUBLISH");
break;
case Win32.DSPRINT_PENDING | Win32.DSPRINT_UNPUBLISH:
MessageBox.Show("PENDING UNPUBLISH");
break;
default:
MessageBox.Show("Unknown status #" + printerInfo.dwAction.ToString());
break;
}
}
catch (Exception ex)
{
// Show errors
MessageBox.Show(ex.Message);
}
finally
{
// Clean up memory
if (!pPrinterInfo.Equals(IntPtr.Zero))
{
Marshal.FreeHGlobal(pPrinterInfo);
}

// Close printer
if (!hPrinter.Equals(IntPtr.Zero))
{
Win32.ClosePrinter(hPrinter);
}
}
}

}
}

Win32.cs

using System;

using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;

namespace AlexPublishPrinter
{
class Win32
{
public const uint ERROR_INSUFFICIENT_BUFFER = 122;
public const uint ERROR_IO_PENDING = 997;
public const uint ERROR_FILE_NOT_FOUND = 0x80070002;
public const uint DSPRINT_PUBLISH = 0x00000001;
public const uint DSPRINT_UPDATE = 0x00000002;
public const uint DSPRINT_PENDING = 0x80000000;
public const uint DSPRINT_UNPUBLISH = 0x00000004;
public const uint STANDARD_RIGHTS_REQUIRED = 0x000F0000;
public const uint PRINTER_ACCESS_ADMINISTER = 0x00000004;
public const uint PRINTER_ACCESS_USE = 0x00000008;
public const uint PRINTER_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED | PRINTER_ACCESS_ADMINISTER | PRINTER_ACCESS_USE;

[StructLayout(LayoutKind.Sequential)]
public struct PRINTER_DEFAULTS
{
public IntPtr pDatatype;
public IntPtr pDevMode;
public uint DesiredAccess;
}

[StructLayout(LayoutKind.Sequential)]
public struct PRINTER_INFO_7
{
public IntPtr pszObjectGUID;
public uint dwAction;
}

[DllImport("winspool.drv", CharSet = CharSet.Auto, SetLastError = true)]
public static extern bool OpenPrinter(
string pPrinterName,
out IntPtr phPrinter,
ref PRINTER_DEFAULTS pDefault
);

[DllImport("winspool.drv", SetLastError = true)]
public static extern bool SetPrinter(
IntPtr hPrinter,
int Level,
ref PRINTER_INFO_7 pPrinter,
int Command
);

[DllImport("winspool.drv", SetLastError = true)]
public static extern bool GetPrinter(
IntPtr hPrinter,
int Level,
IntPtr pPrinter,
int cbBuf,
out int pcbNeeded
);

[DllImport("winspool.drv", SetLastError = true)]
public static extern bool ClosePrinter(
IntPtr hPrinter
);
}
}

I hope this helps.

Regards,

Alex (Alejandro Campos Magencio)

Original URL: https://blogs.msdn.microsoft.com/alejacma/2010/08/11/pinvoking-cryptoapi-in-net-part-2-c/
Post name: P/Invoking CryptoAPI in .NET. Part 2 (C#)
Original author: Alejandro Campos Magencio
Posting date: 2010-08-11T03:24:36+00:00


Hi all,

Some time ago I postedthe following sample How to call CryptMsg API in streaming mode (C#).Well, I continued working on that CryptMsg sample, and I got many consts, structs and API declarations that may help you if you need to p/invoke CryptoAPI in C#. You may also want to check this other post of mine:P/Invoking CryptoAPI in .NET (C# version), to see more CryptoAPI declarations.

using System;

using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Security.Cryptography.X509Certificates;
using System.ComponentModel;
using System.Security.Cryptography;

namespace LargeCMS
{
partial class Win32
{
#region "CONSTS"

internal const int X509_ASN_ENCODING = 0x00000001;
internal const int PKCS_7_ASN_ENCODING = 0x00010000;

internal const int CMSG_SIGNED = 2;
internal const int CMSG_ENVELOPED = 3;
internal const int CMSG_DETACHED_FLAG = 0x00000004;
internal const int CMSG_AUTHENTICATED_ATTRIBUTES_FLAG = 0x00000008;
internal const int CMSG_ENVELOPE_ALGORITHM_PARAM = 15;
internal const int CMSG_ENCODED_SIGNER = 8;
internal const int CMSG_ENCODED_MESSAGE = 29;
internal const int CMSG_CTRL_VERIFY_SIGNATURE = 1;
internal const int CMSG_CTRL_DECRYPT = 2;
internal const int CMSG_CTRL_VERIFY_SIGNATURE_EX = 19;
internal const int CMSG_CTRL_ADD_SIGNER = 6;
internal const int CMSG_CTRL_ADD_CERT = 10;
internal const int CMSG_SIGNER_COUNT_PARAM = 5;
internal const int CMSG_SIGNER_INFO_PARAM = 6;
internal const int CMSG_SIGNER_CERT_INFO_PARAM = 7;
internal const int CMSG_CERT_COUNT_PARAM = 11;
internal const int CMSG_CERT_PARAM = 12;
internal const int CMSG_RECIPIENT_COUNT_PARAM = 17;
internal const int CMSG_RECIPIENT_INFO_PARAM = 19;
internal const int CMSG_VERIFY_SIGNER_CERT = 2;
internal const int CMSG_RC4_NO_SALT_FLAG = 0x40000000;

internal const int AT_KEYEXCHANGE = 1;
internal const int AT_SIGNATURE = 2;

internal const String szOID_OIWSEC_rsaSign = "1.3.14.3.2.11";
internal const String szOID_OIWSEC_shaRSA = "1.3.14.3.2.15";
internal const String szOID_OIWSEC_sha = "1.3.14.3.2.18";
internal const String szOID_OIWSEC_sha1 = "1.3.14.3.2.26";
internal const String szOID_OIWSEC_sha1RSASign = "1.3.14.3.2.29";
internal const String szOID_RSA_RC4 = "1.2.840.113549.3.4";
internal const String szOID_RSA_DES_EDE3_CBC = "1.2.840.113549.3.7";
internal const String szOID_RSA_signingTime = "1.2.840.113549.1.9.5";

internal const int X509_NAME = 7;

internal const int CERT_STORE_PROV_MSG = 1;
internal const int CERT_CLOSE_STORE_FORCE_FLAG = 1;
internal const int CERT_KEY_PROV_INFO_PROP_ID = 2;
internal const int CERT_STORE_PROV_SYSTEM = 10;

internal const int CERT_SYSTEM_STORE_CURRENT_USER = 1 << 16;

#endregion

#region "STRUCTS"

[StructLayout(LayoutKind.Sequential)]
internal struct CRYPT_ALGORITHM_IDENTIFIER
{
public string pszObjId;
public BLOB Parameters;

public void Dispose()
{
Parameters.Dispose();
}
}

[StructLayout(LayoutKind.Sequential)]
internal struct CERT_ID
{
public int dwIdChoice;
public BLOB IssuerSerialNumberOrKeyIdOrHashId;
}

[StructLayout(LayoutKind.Sequential)]
internal struct CRYPT_ATTRIBUTE
{
public string pszObjId;
public int cValue;
public IntPtr rgValue;

public void Dispose()
{
if (!rgValue.Equals(IntPtr.Zero)) { Marshal.FreeHGlobal(rgValue); }
}
}

[StructLayout(LayoutKind.Sequential)]
internal struct CMSG_SIGNER_ENCODE_INFO
{
public int cbSize;
public IntPtr pCertInfo;
public IntPtr hCryptProvOrhNCryptKey;
public int dwKeySpec;
public CRYPT_ALGORITHM_IDENTIFIER HashAlgorithm;
public IntPtr pvHashAuxInfo;
public int cAuthAttr;
public IntPtr rgAuthAttr;
public int cUnauthAttr;
public IntPtr rgUnauthAttr;
public CERT_ID SignerId;
public CRYPT_ALGORITHM_IDENTIFIER HashEncryptionAlgorithm;
public IntPtr pvHashEncryptionAuxInfo;

public void Dispose()
{
if (!hCryptProvOrhNCryptKey.Equals(IntPtr.Zero)) { Win32.CryptReleaseContext(hCryptProvOrhNCryptKey, 0); }
if (!rgAuthAttr.Equals(IntPtr.Zero)) { Marshal.FreeHGlobal(rgAuthAttr); }
if (!rgUnauthAttr.Equals(IntPtr.Zero)) { Marshal.FreeHGlobal(rgUnauthAttr); }
}
}

[StructLayout(LayoutKind.Sequential)]
internal struct CERT_CONTEXT
{
public int dwCertEncodingType;
public IntPtr pbCertEncoded;
public int cbCertEncoded;
public IntPtr pCertInfo;
public IntPtr hCertStore;
}

[StructLayout(LayoutKind.Sequential)]
internal struct BLOB
{
public int cbData;
public IntPtr pbData;

public void Dispose()
{
if (!pbData.Equals(IntPtr.Zero)) { Marshal.FreeHGlobal(pbData); }
}
}

[StructLayout(LayoutKind.Sequential)]
internal struct CRYPT_BIT_BLOB
{
public int cbData;
public IntPtr pbData;
public int cUnusedBits;
}

[StructLayout(LayoutKind.Sequential)]
internal struct CMSG_SIGNED_ENCODE_INFO
{
public int cbSize;
public int cSigners;
public IntPtr rgSigners;
public int cCertEncoded;
public IntPtr rgCertEncoded;
public int cCrlEncoded;
public IntPtr rgCrlEncoded;
public int cAttrCertEncoded;
public IntPtr rgAttrCertEncoded;

public void Dispose()
{
if (!rgSigners.Equals(IntPtr.Zero)) { Marshal.FreeHGlobal(rgSigners); }
if (!rgCertEncoded.Equals(IntPtr.Zero)) { Marshal.FreeHGlobal(rgCertEncoded); }
if (!rgCrlEncoded.Equals(IntPtr.Zero)) { Marshal.FreeHGlobal(rgCrlEncoded); }
if (!rgAttrCertEncoded.Equals(IntPtr.Zero)) { Marshal.FreeHGlobal(rgAttrCertEncoded); }
}
}

[StructLayout(LayoutKind.Sequential)]
internal struct CRYPT_ATTRIBUTES
{
public int cAttr;
public IntPtr rgAttr;
}

[StructLayout(LayoutKind.Sequential)]
internal struct CMSG_SIGNER_INFO
{
public int dwVersion;
public BLOB Issuer;
public BLOB SerialNumber;
public CRYPT_ALGORITHM_IDENTIFIER HashAlgorithm;
public CRYPT_ALGORITHM_IDENTIFIER HashEncryptionAlgorithm;
public BLOB EncryptedHash;
public CRYPT_ATTRIBUTES AuthAttrs;
public CRYPT_ATTRIBUTES UnauthAttrs;
}

[StructLayout(LayoutKind.Sequential)]
internal struct CMSG_STREAM_INFO
{
public int cbContent;
public StreamOutputCallbackDelegate pfnStreamOutput;
public IntPtr pvArg;
}

[StructLayout(LayoutKind.Sequential)]
internal struct CERT_PUBLIC_KEY_INFO
{
public CRYPT_ALGORITHM_IDENTIFIER Algorithm;
public CRYPT_BIT_BLOB PublicKey;
}

[StructLayout(LayoutKind.Sequential)]
internal struct FILETIME
{
public int dwLowDateTime;
public int dwHighDateTime;
}

[StructLayout(LayoutKind.Sequential)]
internal struct CERT_INFO
{
public int dwVersion;
public BLOB SerialNumber;
public CRYPT_ALGORITHM_IDENTIFIER SignatureAlgorithm;
public BLOB Issuer;
public FILETIME NotBefore;
public FILETIME NotAfter;
public BLOB Subject;
public CERT_PUBLIC_KEY_INFO SubjectPublicKeyInfo;
public CRYPT_BIT_BLOB IssuerUniqueId;
public CRYPT_BIT_BLOB SubjectUniqueId;
public int cExtension;
public IntPtr rgExtension;
}

[StructLayout(LayoutKind.Sequential)]
internal struct CMSG_CTRL_VERIFY_SIGNATURE_EX_PARA
{
public int cbSize;
public IntPtr hCryptProv;
public int dwSignerIndex;
public int dwSignerType;
public IntPtr pvSigner;
}

[StructLayout(LayoutKind.Sequential)]
internal struct CMSG_ENVELOPED_ENCODE_INFO
{
public int cbSize;
public IntPtr hCryptProv;
public CRYPT_ALGORITHM_IDENTIFIER ContentEncryptionAlgorithm;
public IntPtr pvEncryptionAuxInfo;
public int cRecipients;
public IntPtr rgpRecipients;
public IntPtr rgCmsRecipients;
public int cCertEncoded;
public IntPtr rgCertEncoded;
public int cCrlEncoded;
public IntPtr rgCrlEncoded;
public int cAttrCertEncoded;
public IntPtr rgAttrCertEncoded;
public int cUnprotectedAttr;
public IntPtr rgUnprotectedAttr;

public void Dispose()
{
ContentEncryptionAlgorithm.Dispose();
if (!pvEncryptionAuxInfo.Equals(IntPtr.Zero)) { Marshal.FreeHGlobal(pvEncryptionAuxInfo); }
if (!rgpRecipients.Equals(IntPtr.Zero)) { Marshal.FreeHGlobal(rgpRecipients); }
}
}

[StructLayout(LayoutKind.Sequential)]
internal struct CMSG_RC4_AUX_INFO
{
public int cbSize;
public int dwBitLen;
}

[StructLayout(LayoutKind.Sequential)]
internal struct CMSG_CTRL_DECRYPT_PARA
{
public int cbSize;
public IntPtr hCryptProvOrNCryptKey;
public int dwKeySpec;
public int dwRecipientIndex;
}

[StructLayout(LayoutKind.Sequential)]
internal struct CRYPT_KEY_PROV_INFO
{
[MarshalAs(UnmanagedType.LPWStr)]public string pwszContainerName;
[MarshalAs(UnmanagedType.LPWStr)]public string pwszProvName;
public int dwProvType;
public int dwFlags;
public int cProvParam;
public IntPtr rgProvParam;
public int dwKeySpec;
}

#endregion

#region "DELEGATES"

internal delegate Boolean StreamOutputCallbackDelegate(IntPtr pvArg, IntPtr pbData, int cbData, Boolean fFinal);

#endregion

#region "API"

[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
internal static extern Boolean CryptAcquireContext(
out SafeCSPHandle hProv,
string pszContainer,
string pszProvider,
int dwProvType,
int dwFlags
);

[DllImport("crypt32.dll", CharSet = CharSet.Ansi, SetLastError = true)]
internal static extern bool CryptEncodeObject(
int dwCertEncodingType,
string lpszStructType,
ref long pvStructInfo,
SafeNTHeapHandle pbEncoded,
ref int pcbEncoded
);

[DllImport("crypt32.dll", CharSet = CharSet.Ansi, SetLastError = true)]
internal static extern Boolean CryptDecodeObject(
int dwCertEncodingType,
string lpszStructType,
IntPtr pbEncoded,
int cbEncoded,
int dwFlags,
out long pvStructInfo,
ref int pcbStructInfo
);
[DllImport("crypt32.dll", CharSet = CharSet.Ansi, SetLastError = true)]
internal static extern Boolean CryptDecodeObject(
int dwCertEncodingType,
int lpszStructType,
IntPtr pbEncoded,
int cbEncoded,
int dwFlags,
StringBuilder pvStructInfo,
ref int pcbStructInfo
);

[DllImport("Crypt32.dll", SetLastError = true)]
internal static extern SafeMsgHandle CryptMsgOpenToEncode(
int dwMsgEncodingType,
int dwFlags,
int dwMsgType,
ref CMSG_SIGNED_ENCODE_INFO pvMsgEncodeInfo,
string pszInnerContentObjID,
ref CMSG_STREAM_INFO pStreamInfo
);
[DllImport("Crypt32.dll", SetLastError = true)]
internal static extern SafeMsgHandle CryptMsgOpenToEncode(
int dwMsgEncodingType,
int dwFlags,
int dwMsgType,
ref CMSG_ENVELOPED_ENCODE_INFO pvMsgEncodeInfo,
string pszInnerContentObjID,
ref CMSG_STREAM_INFO pStreamInfo
);

[DllImport("Crypt32.dll", SetLastError = true)]
internal static extern SafeMsgHandle CryptMsgOpenToDecode(
int dwMsgEncodingType,
int dwFlags,
int dwMsgType,
IntPtr hCryptProv,
IntPtr pRecipientInfo,
ref CMSG_STREAM_INFO pStreamInfo
);
[DllImport("Crypt32.dll", SetLastError = true)]
internal static extern SafeMsgHandle CryptMsgOpenToDecode(
int dwMsgEncodingType,
int dwFlags,
int dwMsgType,
IntPtr hCryptProv,
IntPtr pRecipientInfo,
IntPtr pStreamInfo
);

[DllImport("Crypt32.dll", SetLastError = true)]
internal static extern Boolean CryptMsgClose(
IntPtr hCryptMsg
);

[DllImport("Crypt32.dll", SetLastError = true)]
internal static extern Boolean CryptMsgUpdate(
IntPtr hCryptMsg,
Byte[] pbData,
int cbData,
Boolean fFinal
);

[DllImport("Crypt32.dll", SetLastError = true)]
internal static extern Boolean CryptMsgUpdate(
IntPtr hCryptMsg,
IntPtr pbData,
int cbData,
Boolean fFinal
);

[DllImport("Crypt32.dll", SetLastError = true)]
internal static extern Boolean CryptMsgGetParam(
SafeMsgHandle hCryptMsg,
int dwParamType,
int dwIndex,
SafeNTHeapHandle pvData,
ref int pcbData
);
[DllImport("Crypt32.dll", SetLastError = true)]
internal static extern Boolean CryptMsgGetParam(
SafeMsgHandle hCryptMsg,
int dwParamType,
int dwIndex,
out int pvData,
ref int pcbData
);

[DllImport("Crypt32.dll", SetLastError = true)]
internal static extern Boolean CryptMsgControl(
SafeMsgHandle hCryptMsg,
int dwFlags,
int dwCtrlType,
IntPtr pvCtrlPara
);
[DllImport("Crypt32.dll", SetLastError = true)]
internal static extern Boolean CryptMsgControl(
SafeMsgHandle hCryptMsg,
int dwFlags,
int dwCtrlType,
ref CMSG_SIGNER_ENCODE_INFO pvCtrlPara
);
[DllImport("Crypt32.dll", SetLastError = true)]
internal static extern Boolean CryptMsgControl(
SafeMsgHandle hCryptMsg,
int dwFlags,
int dwCtrlType,
ref BLOB pvCtrlPara
);
[DllImport("Crypt32.dll", SetLastError = true)]
internal static extern Boolean CryptMsgControl(
SafeMsgHandle hCryptMsg,
int dwFlags,
int dwCtrlType,
ref CMSG_CTRL_VERIFY_SIGNATURE_EX_PARA pvCtrlPara
);
[DllImport("Crypt32.dll", SetLastError = true)]
internal static extern Boolean CryptMsgControl(
SafeMsgHandle hCryptMsg,
int dwFlags,
int dwCtrlType,
ref CMSG_CTRL_DECRYPT_PARA pvCtrlPara
);

[DllImport("advapi32.dll", SetLastError = true)]
internal static extern Boolean CryptReleaseContext(
IntPtr hProv,
int dwFlags
);

[DllImport("Crypt32.dll", SetLastError = true)]
internal static extern SafeCertContextHandle CertCreateCertificateContext(
int dwCertEncodingType,
SafeNTHeapHandle pbCertEncoded,
int cbCertEncoded
);

[DllImport("Crypt32.dll", SetLastError = true)]
internal static extern Boolean CertFreeCertificateContext(
IntPtr pCertContext
);

[DllImport("Crypt32.dll", SetLastError = true)]
internal static extern SafeStoreHandle CertOpenStore(
int lpszStoreProvider,
int dwMsgAndCertEncodingType,
IntPtr hCryptProv,
int dwFlags,
SafeMsgHandle pvPara
);

[DllImport("Crypt32.dll", SetLastError = true)]
internal static extern SafeStoreHandle CertOpenSystemStore(
IntPtr hprov,
string szSubsystemProtocol
);

[DllImport("Crypt32.dll", SetLastError = true)]
internal static extern SafeCertContextHandle CertGetSubjectCertificateFromStore(
SafeStoreHandle hCertStore,
int dwCertEncodingType,
SafeNTHeapHandle pCertId
);

[DllImport("Crypt32.dll", SetLastError = true)]
internal static extern IntPtr CertCloseStore(
IntPtr hCertStore,
int dwFlags
);

[DllImport("Crypt32.dll", SetLastError = true)]
internal static extern bool CertGetCertificateContextProperty(
SafeCertContextHandle pCertContext,
int dwPropId,
SafeNTHeapHandle pvData,
ref int pcbData
);

[DllImport("msvcrt.dll", EntryPoint = "memset", CallingConvention = CallingConvention.Cdecl, SetLastError = false)]
internal static extern IntPtr MemSet(
IntPtr ptr,
int value,
int num
);

#endregion
}
}

I hope this helps.

Regards,

Alex (Alejandro Campos Magencio)

Original URL: https://blogs.msdn.microsoft.com/alejacma/2010/08/11/how-to-call-cryptencodeobject-in-net-c/
Post name: How to call CryptEncodeObject in .NET (C#)
Original author: Alejandro Campos Magencio
Posting date: 2010-08-11T02:58:07+00:00


Hi all,

The other day a colleague of mine was having some issues to call CryptEncodeObject from C#. In order to assist, Icreated this sample for him:

using System;

using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

public const int X509_ASN_ENCODING = 0x00000001;
public const int PKCS_7_ASN_ENCODING = 0x00010000;
public const int X509_ENHANCED_KEY_USAGE = 36;

[StructLayout(LayoutKind.Sequential)]
private struct CERT_ENHKEY_USAGE
{
public int cUsageIdentifier;
public IntPtr rgpszUsageIdentifier;
}

[DllImport("crypt32.dll", CharSet = CharSet.Ansi, SetLastError = true)]
private static extern bool CryptEncodeObject(
int dwCertEncodingType,
int lpszStructType,
ref CERT_ENHKEY_USAGE pvStructInfo,
byte[] pbEncoded,
ref int pcbEncoded
);

private void button1_Click(object sender, EventArgs e)
{
// Variables
CERT_ENHKEY_USAGE usage = new CERT_ENHKEY_USAGE();
IntPtr OID = IntPtr.Zero;
int blobSize = 0;
byte[] blob = null;

try
{
// Prepare data to encode (CERT_ENHKEY_USAGE struct)
OID = Marshal.StringToHGlobalAnsi("1.3.6.1.4.1.311.101.11");
usage.rgpszUsageIdentifier = Marshal.AllocHGlobal(Marshal.SizeOf(OID));
Marshal.WriteIntPtr(usage.rgpszUsageIdentifier, OID);
usage.cUsageIdentifier = 1;

// Get size of encoded data
if (!CryptEncodeObject(
X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
X509_ENHANCED_KEY_USAGE,
ref usage,
null,
ref blobSize
))
{
int error = Marshal.GetLastWin32Error();
throw new Win32Exception(error);
}

// Get encoded data
blob = new byte[blobSize];
if (!CryptEncodeObject(
X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
X509_ENHANCED_KEY_USAGE,
ref usage,
blob,
ref blobSize
))
{
int error = Marshal.GetLastWin32Error();
throw new Win32Exception(error);
}

// Everything went well
MessageBox.Show("We got " + blob.Length.ToString() + " encoded bytes");
}
catch (Exception ex)
{
// Errors?
MessageBox.Show(ex.Message);
}
finally
{
// Clean up
if (!OID.Equals(IntPtr.Zero)) { Marshal.FreeHGlobal(OID); }
if (!usage.rgpszUsageIdentifier.Equals(IntPtr.Zero)) { Marshal.FreeHGlobal(usage.rgpszUsageIdentifier); }
}
}
}
}

I hope this helps.

Note I didn't have the opportunity to test it much, so if you have any issues with it, please let me know. Thx!

Regards,

Alex (Alejandro Campos Magencio)

Original URL: https://blogs.msdn.microsoft.com/alejacma/2010/08/03/im-on-twitter-now/
Post name: I’m on Twitter now!
Original author: Alejandro Campos Magencio
Posting date: 2010-08-03T15:22:46+00:00


Hi all,

I just joined the twitter community today:https://twitter.com/alejacma. I don't have much time to create lengthy posts lately, soI decided to give an opportunity to micro-blogging. I will keep posting Crypto, WinSDK and debugging stuff in there, and I hope to reach more and more people everyday in this way, too. So see you around one way or the other!

Cheers,

 

Alex (Alejandro Campos Magencio)