Encoding and Decoding With the CryptoAPI

The CryptoAPI has been designed to relieve the programmer from having to actually perform the ASN.1 encoding. Message functions are provided that encode and decode Public Key Cryptography Standard (PKCS) #7 messages where the actual encoding and decoding are handled by the function itself. For additional information on message functions, see Using Low-Level Message Functions, Using Simplified Message Functions, Low-Level Message Functions, and Simplified Message Functions.

For those occasions where the message functions aren't appropriate, such as when encoding certificate requests, the CryptoAPI provides two other functions to aid the programmer with encoding and decoding; CryptEncodeObject and CryptDecodeObject. These functions are designed to use C structures that mirror the appropriate ASN.1 SEQUENCE. This way, the programmer can deal with the familiar C structure rather than having to deal with the ASN.1 encoding language. For example, the ASN.1 abstraction for certificate request information (reviewed in the previous section) is:

CertificationRequestInfo:
CertificationRequestInfo ::= SEQUENCE {
  version Version,
  subject Name,
  subjectPublicKeyInfo SubjectPublicKeyInfo,
  attributes [0] IMPLICIT Attributes }
Version ::= INTEGER
Attributes ::= SET OF Attribute
 

The CryptoAPI C structure used to represent this ASN.1 abstraction is:

typedef struct _CERT_REQUEST_INFO {
    DWORD                 dwVersion;
    CERT_NAME_BLOB        Subject;
    CERT_PUBLIC_KEY_INFO  SubjectPublicKeyInfo;
    DWORD                 cAttribute;
    PCRYPT_ATTRIBUTE      rgAttribute;
} CERT_REQUEST_INFO,     *PCERT_REQUEST_INFO;
 

Notice the following similarities and differences between the ASN.1 notation and the C structure:

ASN.1 Value
ID
ASN.1 Type Struct Member
ID
Struct Type
version INTEGER dwVersion DWORD
subject Name Subject CERT_NAME
_BLOB
subjectPublic
KeyInfo
SubjectPublicKey
Info
SubjectPublicKey
Info
CERT_PUBLIC
_KEY_INFO
cAttribute DWORD
attributes IMPLICIT
Attributes
rgAttribute PCRYPT
_ATTRIBUTE

The structure ID that gets passed into the function along with the structure determines the type of processing performed by the function. The run-time code necessary to perform the DER encoding of the items listed in the table in CryptEncodeObject/CryptDecodeObject Functions is supplied with the CryptoAPI. However, if you want to extend the ability of the CryptoAPI to encode data not defined in that table, a DER encoding compiler, such as the one produced by Open Systems Solutions, Inc. (OSS), will be required. Additional information on extending the performance of the CryptoAPI can be found in Extending CryptoAPI Functionality.

For a description of the general model these functions follow, see the General Encode/Decode Model and Using the Encode/Decode Functions.