CryptoAPI: How to import a certificate

Following is the C code to import a certificate into the Windows trusted root certificate store using CryptoAPI:

PCCERT_CONTEXT pCertCtx = NULL;

if (CryptQueryObject (
        CERT_QUERY_OBJECT_FILE,
        L"D:\\selva\\b64.cer",
        CERT_QUERY_CONTENT_FLAG_ALL,
        CERT_QUERY_FORMAT_FLAG_ALL,
        0,
        NULL,
        NULL,
        NULL,
        NULL,
        NULL,
        (const void **)&pCertCtx) != 0)
{
    HCERTSTORE hCertStore = CertOpenStore (
        CERT_STORE_PROV_SYSTEM,
        0,
        0,
        CERT_STORE_OPEN_EXISTING_FLAG |
        CERT_SYSTEM_STORE_LOCAL_MACHINE,
        L"ROOT");
    if (hCertStore != NULL)
    {
        if (CertAddCertificateContextToStore (
            hCertStore,
            pCertCtx,
            CERT_STORE_ADD_ALWAYS,
            NULL))
        {
            cout << "Added certificate to store." << endl;
        }

        if (CertCloseStore (hCertStore, 0))
        {
            cout << "Cert. store handle closed." << endl;
        }
    }

    if (pCertCtx)
    {
        CertFreeCertificateContext (pCertCtx);
    }
}

NOTE: I have tested the above code to import DER encoded and Base-64 encoded certificates.

6 Comments

Filed under C/C++, Coding is fun, Windows, Windows API

Boxing/Unboxing in .NET

This post has been long overdue; I should have posted it two months back. Anyway, a couple of my friends attended training in .NET concepts sponsored by my company. They came back from the training and discussed with me the stuff they had learnt. One of the fellows mentioned that they had been taught that int.ToString() converts an integer (a value type) to a string (a reference type) and hence, boxes the int. On the other hand, int.Parse() converts a string to an integer and hence, unboxes the string. When I heard that, I knew deep within me that what they had been taught was incorrect. But, I did not know why. So, I set out to find the answer. To find out what happens during a call to int.ToString(), I decompiled mscorlib.dll (It is present is the .NET Framework directory which on my machine happens to be C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727) which contains the implementation of Int32 using Lutz Roeder’s .NET Reflector.

The implementation of ToString() is as follows:

public override string ToString()
{
    return Number.FormatInt32(
        this,
        null,
        NumberFormatInfo.CurrentInfo);
}

The Number.FormatInt32() method is declared as follows:

[MethodImpl(MethodImplOptions.InternalCall)]
public static extern string FormatInt32(
    int value,
    string format,
    NumberFormatInfo info);

According to MSDN, the extern modifier is used in C# to declare a method that is implemented externally. So, the question is: where is FormatInt32() (see above code fragment) implemented? The answer lies in the MethodImpl attribute which decorates the method declaration. According to MSDN, MethodImplOptions.InternalCall specifies that the method is implemented in the CLR itself. So, I proceeded to download SSCLI a.k.a. Rotor (source code to a working implementation of the CLR) from here.

I learnt from this site that the ecall.cpp file (which is located at \clr\src\vm\ecall.cpp in the SSCLI) contains a table that maps managed internal call methods to unmanaged C++ implementations. I searched for FormatInt32 and found the following code:

FCFuncElement("FormatInt32", COMNumber::FormatInt32)

This tells that the implementation of FormatInt32 method is actually the implementation of the native C++ COMNumber::FormatInt32 function. So, the next question is where do I find the implementation of COMNumber::FormatInt32 function? I noticed that there was a file named comnumber.cpp in the \clr\src\vm directory. I opened the file and started to examine the COMNumber::FormatInt32 function. I discovered that COMNumber::FormatInt32 calls COMNumber::Int32ToDecChars function. This function is defined as follows:

wchar_t* COMNumber::Int32ToDecChars(
    wchar_t* p,
    unsigned int value,
    int digits)
{
    LEAF_CONTRACT
    _ASSERTE(p != NULL);

    while (--digits >= 0 || value != 0) {
        *--p = value % 10 + '0';
        value /= 10;
    }
    return p;
}

As you can see here, COMNumber::Int32ToDecChars takes each digit of the integer starting from the rightmost digit and proceeding to the leftmost, converts it to the equivalent character and stores it in a string and returns the string. There is actually more action that goes on inside COMNumber::FormatInt32 but, I won’t be discussing that here. The core function is performed by COMNumber::Int32ToDecChars. So, I would wrap up the discussion of int.ToString() function by saying that it converts individual digits of an integer to their equivalent characters, stores them in a string and returns the string.

Next, I tried to figure out what goes on inside int.Parse(). I used .NET reflector and found out that it is pretty similar to what int.ToString() does. The string is read character-by-character, converted to its equivalent digit and added to a number after the digits converted previously have been shifted by one position.

Most C# textbooks provide an example as shown below for boxing/unboxing:

int i = 1729;
object o = i; // Boxing
int j = (int)o; // Unboxing

int.ToString() and int.Parse() cannot be used in the above manner and so, these functions are not even remotely related to boxing/unboxing.

My final task was to find out what actually happens during boxing/unboxing. The documentation that is available made my task easy. I referred the following:

  1. C# Language Specification
  2. Shared Source CLI Essentials – By David Stutz, Ted Neward and Geoff Schilling

See the excerpts from Shared Source CLI Essentials:

By default, when an instance of a value type is passed from one location to another as a method parameter, it is copied in its entirety. At times, however, developers will want or need to take the value type and use it in a manner consistent with reference types. In these situations, the value type can be “boxed”: a reference type instance will be created whose data is the value type, and a reference to that instance is passed instead. Naturally, the reverse is also possible, to take the boxed value type and dereference it back into a value type – this is called “unboxing”.

The box instruction is a typesafe operation that converts a value type instance to an instance of a reference type that inherits from System.Object. It does so by making a copy of the instance and embedding it in a newly allocated object. For every value type defined, the type system defines a corresponding reference type called the boxed type. The representation of a boxed value is a location where a value of the value type may be stored; in essence, a single-field reference type whose field is that of the value type. Note that this boxed type is never visible to anyone outside the CLI’s implementation-the boxed type is silently generated by the CLI itself, and is not accessible for programmer use. (It is purely an implementation detail that would have no real utility were it exposed.)

This is made clearer by the C# language specification. Please refer to section 4.3 of the specification.

REFERENCES:

  1. Chapter 3 of Shared Source CLI Essentials – By David Stutz, Ted Neward and Geoff Schilling
  2. C# Language Specification 3.0
  3. .NET Matters, MSDN Magazine, November 2004
  4. The extern modifier on MSDN
  5. The MethodImplAttribute Class on MSDN
  6. The MethodImplOptions Enumeration on MSDN

5 Comments

Filed under .NET, C#, C# concepts, Coding is fun

Alice, Bob and Rubik’s cube

During the week before Christmas, I convinced myself that I had to solve the Rubik’s cube. So, on Friday evening, I took a printout of the beginner’s tutorial by Jasmine Lee. I got my cube the next day. After fiddling with the cube for well over two hours, I finally solved it. It was about 1 a.m. The next day, I got myself to solve the cube without referring back to the tutorial. After much practice, I was even able to slash down my solving time to 6-7 minutes. My current record is 4:30 minutes.

Last evening, when I was playing with my cube, I had an epiphany. I realized that solving the Rubik’s cube is very much like doing cryptanalysis. The solved cube is our plain text. The cube can be scrambled (encrypted) using an algorithm such as F B’ U F2 R2 D’ R2 L2 D’ B’ R2 F2 D’ B2 L F2 U’ R2 F2 L2 U F’ R’ D’ L. The key can be the colour of one of the four faces – front, left, back or right – before starting the encryption. If we know the algorithm and the key, we could solve the cube. But since this is not known, other techniques (cryptanalysis) are employed to solve the cube.

4 Comments

Filed under Rubik's cube, Trash Bin

Some more COM+ configuration issues

As the release date of our project was nearing, I had become a bit busier in the past few weeks. That would explain the absence of any activity in this blog. The long coding and debugging sessions were fun. We faced plenty of issues during deployment in our test environment. Had loads of fun solving them, though at times it was pretty stressful. Learnt a lot! Here, I am posting a couple of issues we faced and how we solved them.

We have a COM+ application in our project. It was working fine until one fine day, it started throwing the following error:

8000401A – “The server process could not be started because the configured identity is incorrect. Check the username and password.”

It turned out that all this while, whenever we had tested the COM+ application, someone was “interactively logged” into the server console. But, this time no one was. The identity for the COM+ application had been set as Interactive User. So, we got this error. Changing the identity to Local Service fixed this issue. But, the application threw another exception:

System.Data.Odbc.OdbcException: ERROR [IM002] [Microsoft][ODBC Driver Manager] Data source name not found and no default driver specified

This was because we had configured a User DSN to connect to the database. A user DSN is visible only to the user for whom it is configured. As the identity for the COM+ application had been set as Local Service, it was unable to find the DSN. Configuring a System DSN which is visible to all users of a machine solved this issue.

The COM+ application was making certain changes to the configured IPSec policy. It was working fine until the above changes were made after which it started throwing the following error:

ERR IPSec [05073] Unable to open Policy Store.

Clearly this was a user permission issue. So, the identity of the COM+ application was changed to “Administrator” instead of “Local Service”. And then, we all lived happily until the next bug showed its ugly face.

REFERENCES:

  1. KB 305761: COM+ server application that uses interactive user identity fails to load

Leave a comment

Filed under .NET, Coding is fun, COM+, Enterprise Services, Life @ Aztec

Logic-based hidden item seeking game

I stumbled upon this humorous article by David Vronay about the complexities of UI design. In the article, Vronay describes the challenges faced by the Minesweeper development team of Microsoft.

By the way, David, I guess it would be a good idea to replace mines with bugs. You may have to do some work in finding out the most loathsome bug. If you ask me, my guess would be a bed bug.

Leave a comment

Filed under Interesting articles, Minesweeper

Chak de India!

Kudos to Team India for bringing home the Twenty20 World cup.

Hats off to M S Dhoni and his boys for this feat.

Photo courtesy: http://worldtwenty20.yahoo.com/

Leave a comment

Filed under Cricket, India, Sports

How to find the NetBIOS name of a domain

Following is the C# code needed to find the NetBIOS name of a domain from Active Directory:

using System;
using System.DirectoryServices;

void PrintNetBIOSName()
{
    string netBIOSName = null;
    DirectoryEntry rootDSE = new DirectoryEntry(
        "LDAP://<server address>/rootDSE",
        "<username>", "<password>");
    string domain = (string)rootDSE.Properties[
        "defaultNamingContext"][0];

    if (!String.IsNullOrEmpty(domain))
    {
        DirectoryEntry parts = new DirectoryEntry(
            "LDAP://<server address>/CN=Partitions
            ,CN=Configuration," + domain,
            "<username>", "<password>");

        foreach (DirectoryEntry part in parts.Children)
        {
            if ((string)part.Properties[
                "nCName"][0] == domain)
            {
                netBIOSName = (string)part.Properties[
                    "NetBIOSName"][0];
                break;
            }
        }

        Console.WriteLine(netBIOSName);
    }
}

REFERENCES:

  1. http://home.hot.rr.com/graye/CodeSnippets.htm
  2. Binding to Active Directory Domain Services (MSDN)

3 Comments

Filed under .NET, C#