i wrote about parsing the san of a certificate before, here is another way to do it:
1) add a reference to CertEnroll 1.0 Type Library
2) use IX509ExtensionAlternativeNames to get a collection of IAlternativeName objects
3) get the data using the IAlternativeName.strValue and IAlternativeName.Type attributes
Here's an example: private string GetSAN(X509Certificate2 cert)
{
X509Extension ext = cert.Extensions["2.5.29.17"]; // get the SAN extension
if (null != ext)
{
try
{
string temp = string.Empty;
IX509ExtensionAlternativeNames an = new CX509ExtensionAlternativeNames();
an.InitializeDecode(EncodingType.XCN_CRYPT_STRING_BASE64, Convert.ToBase64String(ext.RawData));
foreach (IAlternativeName name in an.AlternativeNames)
{
temp += name.Type+":"+name.strValue+Environment.NewLine;
}
return temp;
}
catch (Exception ex)
{
return ex.Message;
}
}
return "no SAN present";
}
If you have to parse the Subject Alternative Name (aka SAN) of a Certificate CertGetNameString is your friend: [DllImport("crypt32.dll", EntryPoint = "CertGetNameString", CharSet = CharSet.Auto, SetLastError = true)]
static extern UInt32 CertGetNameString(
IntPtr CertContext,
UInt32 lType,
UInt32 lFlags,
IntPtr pTypeParameter,
StringBuilder str,
UInt32 cch);
private const int CERT_NAME_EMAIL_TYPE = 1;
private const int CERT_NAME_UPN_TYPE = 8;
private const int CERT_NAME_NO_FLAG = 0;
private const int SIZE = 255;
private static void ParseSan(X509Certificate2 cc)
{
Oid oid = new Oid("2.5.29.17");
X509Extension ext = cc.Extensions[oid.Value]; // get the SAN extension
if (null != ext)
{
StringBuilder Buffer = new StringBuilder(SIZE);
UInt32 nChars = CertGetNameString(cc.Handle,
CERT_NAME_EMAIL_TYPE,
CERT_NAME_NO_FLAG,
IntPtr.Zero,
Buffer,
SIZE);
if (nChars == 1)
{
nChars = CertGetNameString(cc.Handle,
CERT_NAME_UPN_TYPE,
CERT_NAME_NO_FLAG,
IntPtr.Zero,
Buffer,
SIZE);
}
Console.WriteLine("{1}:'{0}'", Buffer.ToString(), cc.Thumbprint);
}
}
http://www.moserware.com/ has great posts about programming.
amongst them a nice explanation of the AES encryption
Check it out...
Sometime you need to get the integer value (or combination of values) for the Key Usage (i.e. for use in CertReq.EXE's INF files)
This is X509 Certificate Key Usage as defined in .NET:
Key Usage |
Description |
0x0000 |
None |
0x0001 |
EncipherOnly |
0x0002 |
CrlSign |
0x0004 |
KeyCertSign |
0x0008 |
KeyAgreement |
0x0010 |
DataEncipherment |
0x0020 |
KeyEncipherment |
0x0040 |
NonRepudiation |
0x0080 |
DigitalSignature |
0x8000 |
DecipherOnly |
Of course it can be a combination of values 
To get it out of a certificate use this snippet (certificate is a valid X509Certificate2 object): // either "Key Usage" or the OID "2.5.29.15" can be used here
string keyUsageOID = "2.5.29.15";
X509KeyUsageExtension keyUsageExtension = certificate.Extensions[keyUsageOID] as X509KeyUsageExtension;
if (keyUsageExtension != null)
{
Console.WriteLine("Key Usage is 0x{0:x4}, {1}",
Convert.ToInt32(keyUsageExtension.KeyUsages),
keyUsageExtension.KeyUsages);
// test for signature
bool hasSignatureKeyUsage = (keyUsageExtension.KeyUsages & X509KeyUsageFlags.DigitalSignature) == X509KeyUsageFlags.DigitalSignature;
// just for fun: test for CRL signing too
bool hasCrlSignKeyUsage = (keyUsageExtension.KeyUsages & X509KeyUsageFlags.CrlSign) == X509KeyUsageFlags.CrlSign;
}
// either Enhanced Key Usage or the OID 2.5.29.37
string enhancedKeyUsageOID = "2.5.29.37";
X509EnhancedKeyUsageExtension enhancedkeyUsageExtension = certificate.Extensions[enhancedKeyUsageOID] as X509EnhancedKeyUsageExtension;
if (enhancedkeyUsageExtension != null)
foreach (Oid oid in enhancedkeyUsageExtension.EnhancedKeyUsages)
Console.WriteLine("Enhanced Key Usage is {0} ({1})",
oid.FriendlyName,
oid.Value);
Alejandro Campos Magencio has written a nice post on how to import a certificate without user interaction:
http://blogs.msdn.com/alejacma/archive/2008/01/31/how-to-import-a-certificate-without-user-interaction-c-c.aspx
It is built around CryptUIWizImport which is described here: http://msdn.microsoft.com/en-us/library/aa380598.aspx
Be sure to check all flags available:
Value |
Meaning |
- CRYPTUI_WIZ_NO_UI
- 0x0001
|
This function will perform the import based on the information in the CRYPTUI_WIZ_IMPORT_SRC_INFO structure pointed to by pImportSrc into the store specified by hDestCertStore without displaying any user interface. If this flag is not specified, this function will display a wizard to guide the user through the import process. |
- CRYPTUI_WIZ_IGNORE_NO_UI_FLAG_FOR_CSPS
- 0x0002
|
Suppress all user interfaces generated by cryptographic service providers (CSPs). This option can be overridden by the CRYPTUI_WIZ_NO_UI_EXCEPT_CSP option. |
- CRYPTUI_WIZ_NO_UI_EXCEPT_CSP
- 0x0003
|
Suppress all user interfaces except those generated by CSPs. This option overrides the CRYPTUI_WIZ_IGNORE_NO_UI_FLAG_FOR_CSPS option. |
- CRYPTUI_WIZ_IMPORT_ALLOW_CERT
- 0x00020000
|
Allow certificates to be imported. |
- CRYPTUI_WIZ_IMPORT_ALLOW_CRL
- 0x00040000
|
Allow CRLs to be imported. |
- CRYPTUI_WIZ_IMPORT_ALLOW_CTL
- 0x00080000
|
Allow CTLs to be imported. |
- CRYPTUI_WIZ_IMPORT_NO_CHANGE_DEST_STORE
- 0x00010000
|
Do not allow the user to change the destination certificate store represented by the hDestCertStore parameter. |
- CRYPTUI_WIZ_IMPORT_TO_LOCALMACHINE
- 0x00100000
|
Import the object to the certificate store for the local computer. This applies only to Personal Information Exchange (PFX) imports. |
- CRYPTUI_WIZ_IMPORT_TO_CURRENTUSER
- 0x00200000
|
Import the object to the certificate store for the current user. This applies only to PFX imports. |
- CRYPTUI_WIZ_IMPORT_REMOTE_DEST_STORE
- 0x00400000
|
Import the object to a remote certificate store. Set this flag if the hDestCertStore parameter represents a remote certificate store. |
If you need to zip a file or files you can use the java zip utilities supplied with VS.
All you have to do is to add vjslib.dll and vjslibcws.dll .net assemblies as project references.
They are present whe you install Visual J#. It can easily handle multiple files.
// ZIP Test
string inputFileName = @"C:\test.txt"; string zipFileName = Path.ChangeExtension(inputFileName, "ZIP"); string zipEntryName = Path.GetFileName(inputFileName); java.io.FileOutputStream fileStream = new java.io.FileOutputStream(zipFileName); java.util.zip.ZipOutputStream outputStream = new java.util.zip.ZipOutputStream(fileStream); java.io.FileInputStream inputStream = new java.io.FileInputStream(inputFileName); java.util.zip.ZipEntry zipEntry = new java.util.zip.ZipEntry( zipEntryName); outputStream.putNextEntry(zipEntry); sbyte[] buffer = new sbyte[2048]; int bytes = 0; while ((bytes = inputStream.read(buffer, 0, buffer.Length)) > 0) { outputStream.write(buffer, 0, bytes); } outputStream.closeEntry(); inputStream.close(); outputStream.close();
This was a nice try, but J# has been removed from VS2008.
Run your c# app as admin, like 'runas'? Here is the solution:
To delete a certificate store you created using the .NET API (X509Store) you have to use the P/Invoke version of CertOpenStore with the CERT_STORE_DELETE flag: First, import the function: [DllImport("crypt32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern IntPtr CertOpenStore(
IntPtr storeProvider,
uint dwMsgAndCertEncodingType,
IntPtr hCryptProv,
uint dwFlags,
String cchNameString);
Next define some constants ( wincrypt.h is your friend): const int CERT_STORE_PROV_SYSTEM = 10;
const int CERT_SYSTEM_STORE_CURRENT_USER = 0x1 << 16;
const int CERT_STORE_DELETE_FLAG = 0x10; Finally, call the open function: CertOpenStore( (IntPtr)CERT_STORE_PROV_SYSTEM, 0, IntPtr.Zero, CERT_SYSTEM_STORE_CURRENT_USER | CERT_STORE_DELETE_FLAG, storeName);
For some reason I needed to add a Control to a Toolstrip. There are some ToolStrip enabled controls in the framework, but I needed a checkbox. So, after a short time with Windows Live Search, I found the ToolStripControlHost class which comes quite handy for that task. Just create your control, create a ToolStripControlHost , and add that to the toolstrip. Voila, thats it.
CheckBox cb = new CheckBox();
cb.Text = "Test";
ToolStripControlHost ch = new ToolStripControlHost(cb);
this.toolStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { ch });
MSDN describes that here in great detail...
Basic Authenitcation is a - not so secure - method of authenticating users to a web server. The username and password are sent in the HTTP request header with Base64 "encryption" which is as good as plain text. However at some point you may have or may want to do just that, either because there is still no trust between organizations (believe me, the world is good  ) or just because its too easy and other methods are way too hard to implement. Now there you are, how do you add a header to a HttpRequest in plain c#? Follow these steps: - Generate the proxy using WSDL.EXE. Search MSDN on how to do that.
- Add this function to the partial class:
protected override System.Net.WebRequest GetWebRequest(Uri uri)
{
HttpWebRequest request = (HttpWebRequest)base.GetWebRequest(uri);
if (PreAuthenticate)
{
NetworkCredential networkCredentials = Credentials.GetCredential(uri, "Basic");
if (networkCredentials != null)
{
byte[] credentialBuffer = new UTF8Encoding().GetBytes(networkCredentials.UserName +":" + networkCredentials.Password);
// Note the space after Basic
request.Headers["Authorization"] = "Basic " + Convert.ToBase64String(credentialBuffer);
}
else
{
throw new ApplicationException("No network credentials");
}
}
return request;
}
- within the client using your proxy add the following:
// these are NOT my real credentials
NetworkCredential netCredential = new NetworkCredential("Elvis", "Graceland");
Uri uri = new Uri(svc.Url);
ICredentials credentials = netCredential.GetCredential(uri, "Basic");
svc.Credentials = credentials;
// set PreAuthenticate as it is checked !!!
svc.PreAuthenticate = true;
Thats it....
A trace filter is a nice thing, it can decide whether to log a message or not. Two filters exist in the framework, and they are covered widely on MSDN. Writing a custom filter is quite easy. Just derive your filter class from TraceFilter, override the one and only method ShouldTrace (which returns bool) and there you go. Now the only thing left is to add the filter to the listener in your applications config file. Happy Tracing... Oh yes, here are the files:
|